From 25749225689c3934bc10ad1e8285e13020b61282 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 4 Dec 2025 09:04:09 +0000
Subject: (최겸)구매 입찰, 계약 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../detail/general-contract-basic-info.tsx         | 478 +++++++++++++++------
 1 file changed, 352 insertions(+), 126 deletions(-)

(limited to 'lib/general-contracts/detail/general-contract-basic-info.tsx')

diff --git a/lib/general-contracts/detail/general-contract-basic-info.tsx b/lib/general-contracts/detail/general-contract-basic-info.tsx
index b0378912..d7533d2e 100644
--- a/lib/general-contracts/detail/general-contract-basic-info.tsx
+++ b/lib/general-contracts/detail/general-contract-basic-info.tsx
@@ -8,7 +8,21 @@ import { Label } from '@/components/ui/label'
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
 import { Textarea } from '@/components/ui/textarea'
 import { Button } from '@/components/ui/button'
-import { Save, LoaderIcon } from 'lucide-react'
+import { Save, LoaderIcon, Check, ChevronsUpDown } from 'lucide-react'
+import {
+  Popover,
+  PopoverContent,
+  PopoverTrigger,
+} from '@/components/ui/popover'
+import {
+  Command,
+  CommandEmpty,
+  CommandGroup,
+  CommandInput,
+  CommandItem,
+  CommandList,
+} from '@/components/ui/command'
+import { cn } from '@/lib/utils'
 import { updateContractBasicInfo, getContractBasicInfo } from '../service'
 import { toast } from 'sonner'
 import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
@@ -140,19 +154,28 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
         
         // paymentDelivery에서 퍼센트와 타입 분리
         const paymentDeliveryValue = contractData?.paymentDelivery || ''
+        console.log(paymentDeliveryValue,"paymentDeliveryValue")
         let paymentDeliveryType = ''
         let paymentDeliveryPercentValue = ''
         
-        if (paymentDeliveryValue.includes('%')) {
+        // "60일 이내" 또는 "추가조건"은 그대로 사용
+        if (paymentDeliveryValue === '납품완료일로부터 60일 이내 지급' || paymentDeliveryValue === '추가조건') {
+          paymentDeliveryType = paymentDeliveryValue
+        } else if (paymentDeliveryValue.includes('%')) {
+          // 퍼센트가 포함된 경우 (예: "10% L/C")
           const match = paymentDeliveryValue.match(/(\d+)%\s*(.+)/)
           if (match) {
             paymentDeliveryPercentValue = match[1]
             paymentDeliveryType = match[2]
+          } else {
+            paymentDeliveryType = paymentDeliveryValue
           }
         } else {
+          // 일반 지급조건 코드 (예: "P008")
           paymentDeliveryType = paymentDeliveryValue
         }
-        
+        console.log(paymentDeliveryType,"paymentDeliveryType")
+        console.log(paymentDeliveryPercentValue,"paymentDeliveryPercentValue")
         setPaymentDeliveryPercent(paymentDeliveryPercentValue)
         
         // 합의계약(AD, AW)인 경우 인도조건 기본값 설정
@@ -309,6 +332,7 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
     loadShippingPlaces();
     loadDestinationPlaces();
   }, [loadPaymentTerms, loadIncoterms, loadShippingPlaces, loadDestinationPlaces]);
+  
   const handleSaveContractInfo = async () => {
     if (!userId) {
       toast.error('사용자 정보를 찾을 수 없습니다.')
@@ -342,12 +366,29 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
         return
       }
       
-      // paymentDelivery와 paymentDeliveryPercent 합쳐서 저장
+      // paymentDelivery 저장 로직
+      // 1. "60일 이내" 또는 "추가조건"은 그대로 저장
+      // 2. L/C 또는 T/T이고 퍼센트가 있으면 "퍼센트% 코드" 형식으로 저장
+      // 3. 그 외의 경우는 그대로 저장
+      let paymentDeliveryToSave = formData.paymentDelivery
+      
+      if (
+        formData.paymentDelivery !== '납품완료일로부터 60일 이내 지급' &&
+        formData.paymentDelivery !== '추가조건' &&
+        (formData.paymentDelivery === 'L/C' || formData.paymentDelivery === 'T/T') &&
+        paymentDeliveryPercent
+      ) {
+        paymentDeliveryToSave = `${paymentDeliveryPercent}% ${formData.paymentDelivery}`
+      }
+      console.log(paymentDeliveryToSave,"paymentDeliveryToSave")
+      
       const dataToSave = {
         ...formData,
-        paymentDelivery: (formData.paymentDelivery === 'L/C' || formData.paymentDelivery === 'T/T') && paymentDeliveryPercent
-          ? `${paymentDeliveryPercent}% ${formData.paymentDelivery}`
-          : formData.paymentDelivery
+        paymentDelivery: paymentDeliveryToSave,
+        // 추가조건 선택 시에만 추가 텍스트 저장, 그 외에는 빈 문자열 또는 undefined
+        paymentDeliveryAdditionalText: formData.paymentDelivery === '추가조건' 
+          ? (formData.paymentDeliveryAdditionalText || '') 
+          : ''
       }
       
       await updateContractBasicInfo(contractId, dataToSave, userId as number)
@@ -1026,20 +1067,100 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
                 <div className="space-y-2">
                   <div className="space-y-1">
                     <Label htmlFor="paymentDelivery" className="text-xs">지급조건 *</Label>
-                    <Select value={formData.paymentDelivery} onValueChange={(value) => setFormData(prev => ({ ...prev, paymentDelivery: value }))}>
-                      <SelectTrigger className={`h-8 text-xs ${errors.paymentDelivery ? 'border-red-500' : ''}`}>
-                        <SelectValue placeholder="선택" />
-                      </SelectTrigger>
-                      <SelectContent>
-                        {paymentTermsOptions.map((term) => (
-                          <SelectItem key={term.code} value={term.code} className="text-xs">
-                            {term.code}
-                          </SelectItem>
-                        ))}
-                        <SelectItem value="납품완료일로부터 60일 이내 지급" className="text-xs">60일 이내</SelectItem>
-                        <SelectItem value="추가조건" className="text-xs">추가조건</SelectItem>
-                      </SelectContent>
-                    </Select>
+                    <Popover>
+                      <PopoverTrigger asChild>
+                        <Button
+                          variant="outline"
+                          role="combobox"
+                          className={cn(
+                            "w-full justify-between h-8 text-xs",
+                            !formData.paymentDelivery && "text-muted-foreground",
+                            errors.paymentDelivery && "border-red-500"
+                          )}
+                        >
+                          {formData.paymentDelivery
+                            ? (() => {
+                                // 1. paymentTermsOptions에서 찾기
+                                const foundOption = paymentTermsOptions.find((option) => option.code === formData.paymentDelivery)
+                                if (foundOption) {
+                                  return `${foundOption.code} ${foundOption.description ? `(${foundOption.description})` : ''}`
+                                }
+                                // 2. 특수 케이스 처리
+                                if (formData.paymentDelivery === '납품완료일로부터 60일 이내 지급') {
+                                  return '60일 이내'
+                                }
+                                if (formData.paymentDelivery === '추가조건') {
+                                  return '추가조건'
+                                }
+                                // 3. 그 외의 경우 원본 값 표시 (로드된 값이지만 옵션에 없는 경우)
+                                return formData.paymentDelivery
+                              })()
+                            : "지급조건 선택"}
+                          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+                        </Button>
+                      </PopoverTrigger>
+                      <PopoverContent className="w-[400px] p-0">
+                        <Command>
+                          <CommandInput placeholder="지급조건 검색..." />
+                          <CommandList>
+                            <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+                            <CommandGroup>
+                              {paymentTermsOptions.map((option) => (
+                                <CommandItem
+                                  key={option.code}
+                                  value={`${option.code} ${option.description || ''}`}
+                                  onSelect={() => {
+                                    setFormData(prev => ({ ...prev, paymentDelivery: option.code }))
+                                  }}
+                                >
+                                  <Check
+                                    className={cn(
+                                      "mr-2 h-4 w-4",
+                                      option.code === formData.paymentDelivery
+                                        ? "opacity-100"
+                                        : "opacity-0"
+                                    )}
+                                  />
+                                  {option.code} {option.description && `(${option.description})`}
+                                </CommandItem>
+                              ))}
+                              <CommandItem
+                                value="납품완료일로부터 60일 이내 지급"
+                                onSelect={() => {
+                                  setFormData(prev => ({ ...prev, paymentDelivery: '납품완료일로부터 60일 이내 지급' }))
+                                }}
+                              >
+                                <Check
+                                  className={cn(
+                                    "mr-2 h-4 w-4",
+                                    formData.paymentDelivery === '납품완료일로부터 60일 이내 지급'
+                                      ? "opacity-100"
+                                      : "opacity-0"
+                                  )}
+                                />
+                                60일 이내
+                              </CommandItem>
+                              <CommandItem
+                                value="추가조건"
+                                onSelect={() => {
+                                  setFormData(prev => ({ ...prev, paymentDelivery: '추가조건' }))
+                                }}
+                              >
+                                <Check
+                                  className={cn(
+                                    "mr-2 h-4 w-4",
+                                    formData.paymentDelivery === '추가조건'
+                                      ? "opacity-100"
+                                      : "opacity-0"
+                                  )}
+                                />
+                                추가조건
+                              </CommandItem>
+                            </CommandGroup>
+                          </CommandList>
+                        </Command>
+                      </PopoverContent>
+                    </Popover>
                     {formData.paymentDelivery === '추가조건' && (
                       <Input
                         type="text"
@@ -1152,53 +1273,59 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
                 </div>
               </div>
 
-              {/* 지불조건 -> 세금조건 (지불조건 삭제됨) */}
+              {/*세금조건*/}
               <div className="space-y-2">
                 <Label className="text-sm font-medium">세금조건</Label>
                 <div className="space-y-2">
-                  {/* 지불조건 필드 삭제됨
-                  <div className="space-y-1">
-                    <Label htmlFor="paymentTerm" className="text-xs">지불조건 *</Label>
-                    <Select
-                      value={formData.paymentTerm}
-                      onValueChange={(value) => setFormData(prev => ({ ...prev, paymentTerm: value }))}
-                    >
-                      <SelectTrigger className={`h-8 text-xs ${errors.paymentTerm ? 'border-red-500' : ''}`}>
-                        <SelectValue placeholder="선택" />
-                      </SelectTrigger>
-                      <SelectContent>
-                        {paymentTermsOptions.length > 0 ? (
-                          paymentTermsOptions.map((option) => (
-                            <SelectItem key={option.code} value={option.code} className="text-xs">
-                              {option.code}
-                            </SelectItem>
-                          ))
-                        ) : (
-                          <SelectItem value="loading" disabled className="text-xs">
-                            로딩중...
-                          </SelectItem>
-                        )}
-                      </SelectContent>
-                    </Select>
-                  </div>
-                  */}
                   <div className="space-y-1">
                     <Label htmlFor="taxType" className="text-xs">세금조건 *</Label>
-                    <Select
-                      value={formData.taxType}
-                      onValueChange={(value) => setFormData(prev => ({ ...prev, taxType: value }))}
-                    >
-                      <SelectTrigger className={`h-8 text-xs ${errors.taxType ? 'border-red-500' : ''}`}>
-                        <SelectValue placeholder="선택" />
-                      </SelectTrigger>
-                      <SelectContent>
-                        {TAX_CONDITIONS.map((condition) => (
-                          <SelectItem key={condition.code} value={condition.code} className="text-xs">
-                            {condition.name}
-                          </SelectItem>
-                        ))}
-                      </SelectContent>
-                    </Select>
+                    <Popover>
+                      <PopoverTrigger asChild>
+                        <Button
+                          variant="outline"
+                          role="combobox"
+                          className={cn(
+                            "w-full justify-between h-8 text-xs",
+                            !formData.taxType && "text-muted-foreground",
+                            errors.taxType && "border-red-500"
+                          )}
+                        >
+                          {formData.taxType
+                            ? TAX_CONDITIONS.find((condition) => condition.code === formData.taxType)?.name
+                            : "세금조건 선택"}
+                          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+                        </Button>
+                      </PopoverTrigger>
+                      <PopoverContent className="w-[400px] p-0">
+                        <Command>
+                          <CommandInput placeholder="세금조건 검색..." />
+                          <CommandList>
+                            <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+                            <CommandGroup>
+                              {TAX_CONDITIONS.map((condition) => (
+                                <CommandItem
+                                  key={condition.code}
+                                  value={`${condition.code} ${condition.name}`}
+                                  onSelect={() => {
+                                    setFormData(prev => ({ ...prev, taxType: condition.code }))
+                                  }}
+                                >
+                                  <Check
+                                    className={cn(
+                                      "mr-2 h-4 w-4",
+                                      condition.code === formData.taxType
+                                        ? "opacity-100"
+                                        : "opacity-0"
+                                    )}
+                                  />
+                                  {condition.name}
+                                </CommandItem>
+                              ))}
+                            </CommandGroup>
+                          </CommandList>
+                        </Command>
+                      </PopoverContent>
+                    </Popover>
                   </div>
                 </div>
               </div>
@@ -1266,79 +1393,178 @@ export function ContractBasicInfo({ contractId }: ContractBasicInfoProps) {
                 {/* 인도조건 */}
                 <div className="space-y-2">
                   <Label htmlFor="deliveryTerm" className="text-xs">인도조건</Label>
-                  <Select
-                    value={formData.deliveryTerm}
-                    onValueChange={(value) => setFormData(prev => ({ ...prev, deliveryTerm: value }))}
-                  >
-                    <SelectTrigger className="h-8 text-xs">
-                      <SelectValue placeholder="선택" />
-                    </SelectTrigger>
-                    <SelectContent>
-                      {incotermsOptions.length > 0 ? (
-                        incotermsOptions.map((option) => (
-                          <SelectItem key={option.code} value={option.code} className="text-xs">
-                            {option.code}
-                          </SelectItem>
-                        ))
-                      ) : (
-                        <SelectItem value="loading" disabled className="text-xs">
-                          로딩중...
-                        </SelectItem>
-                      )}
-                    </SelectContent>
-                  </Select>
+                  <Popover>
+                    <PopoverTrigger asChild>
+                      <Button
+                        variant="outline"
+                        role="combobox"
+                        className={cn(
+                          "w-full justify-between h-8 text-xs",
+                          !formData.deliveryTerm && "text-muted-foreground"
+                        )}
+                      >
+                        {formData.deliveryTerm
+                          ? incotermsOptions.find((option) => option.code === formData.deliveryTerm)
+                            ? `${incotermsOptions.find((option) => option.code === formData.deliveryTerm)?.code} ${incotermsOptions.find((option) => option.code === formData.deliveryTerm)?.description ? `(${incotermsOptions.find((option) => option.code === formData.deliveryTerm)?.description})` : ''}`
+                            : formData.deliveryTerm
+                          : "인코텀즈 선택"}
+                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+                      </Button>
+                    </PopoverTrigger>
+                    <PopoverContent className="w-[400px] p-0">
+                      <Command>
+                        <CommandInput placeholder="인코텀즈 검색..." />
+                        <CommandList>
+                          <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+                          <CommandGroup>
+                            {incotermsOptions.length > 0 ? (
+                              incotermsOptions.map((option) => (
+                                <CommandItem
+                                  key={option.code}
+                                  value={`${option.code} ${option.description || ''}`}
+                                  onSelect={() => {
+                                    setFormData(prev => ({ ...prev, deliveryTerm: option.code }))
+                                  }}
+                                >
+                                  <Check
+                                    className={cn(
+                                      "mr-2 h-4 w-4",
+                                      option.code === formData.deliveryTerm
+                                        ? "opacity-100"
+                                        : "opacity-0"
+                                    )}
+                                  />
+                                  {option.code} {option.description && `(${option.description})`}
+                                </CommandItem>
+                              ))
+                            ) : (
+                              <CommandItem value="loading" disabled>
+                                로딩중...
+                              </CommandItem>
+                            )}
+                          </CommandGroup>
+                        </CommandList>
+                      </Command>
+                    </PopoverContent>
+                  </Popover>
                 </div>
 
                 {/* 선적지 */}
                 <div className="space-y-2">
                   <Label htmlFor="shippingLocation" className="text-xs">선적지</Label>
-                  <Select
-                    value={formData.shippingLocation}
-                    onValueChange={(value) => setFormData(prev => ({ ...prev, shippingLocation: value }))}
-                  >
-                    <SelectTrigger className="h-8 text-xs">
-                      <SelectValue placeholder="선택" />
-                    </SelectTrigger>
-                    <SelectContent>
-                      {shippingPlaces.length > 0 ? (
-                        shippingPlaces.map((place) => (
-                          <SelectItem key={place.code} value={place.code} className="text-xs">
-                            {place.code}
-                          </SelectItem>
-                        ))
-                      ) : (
-                        <SelectItem value="loading" disabled className="text-xs">
-                          로딩중...
-                        </SelectItem>
-                      )}
-                    </SelectContent>
-                  </Select>
+                  <Popover>
+                    <PopoverTrigger asChild>
+                      <Button
+                        variant="outline"
+                        role="combobox"
+                        className={cn(
+                          "w-full justify-between h-8 text-xs",
+                          !formData.shippingLocation && "text-muted-foreground"
+                        )}
+                      >
+                        {formData.shippingLocation
+                          ? shippingPlaces.find((place) => place.code === formData.shippingLocation)
+                            ? `${shippingPlaces.find((place) => place.code === formData.shippingLocation)?.code} ${shippingPlaces.find((place) => place.code === formData.shippingLocation)?.description ? `(${shippingPlaces.find((place) => place.code === formData.shippingLocation)?.description})` : ''}`
+                            : formData.shippingLocation
+                          : "선적지 선택"}
+                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+                      </Button>
+                    </PopoverTrigger>
+                    <PopoverContent className="w-[400px] p-0">
+                      <Command>
+                        <CommandInput placeholder="선적지 검색..." />
+                        <CommandList>
+                          <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+                          <CommandGroup>
+                            {shippingPlaces.length > 0 ? (
+                              shippingPlaces.map((place) => (
+                                <CommandItem
+                                  key={place.code}
+                                  value={`${place.code} ${place.description || ''}`}
+                                  onSelect={() => {
+                                    setFormData(prev => ({ ...prev, shippingLocation: place.code }))
+                                  }}
+                                >
+                                  <Check
+                                    className={cn(
+                                      "mr-2 h-4 w-4",
+                                      place.code === formData.shippingLocation
+                                        ? "opacity-100"
+                                        : "opacity-0"
+                                    )}
+                                  />
+                                  {place.code} {place.description && `(${place.description})`}
+                                </CommandItem>
+                              ))
+                            ) : (
+                              <CommandItem value="loading" disabled>
+                                로딩중...
+                              </CommandItem>
+                            )}
+                          </CommandGroup>
+                        </CommandList>
+                      </Command>
+                    </PopoverContent>
+                  </Popover>
                 </div>
 
                 {/* 하역지 */}
                 <div className="space-y-2">
                   <Label htmlFor="dischargeLocation" className="text-xs">하역지</Label>
-                  <Select
-                    value={formData.dischargeLocation}
-                    onValueChange={(value) => setFormData(prev => ({ ...prev, dischargeLocation: value }))}
-                  >
-                    <SelectTrigger className="h-8 text-xs">
-                      <SelectValue placeholder="선택" />
-                    </SelectTrigger>
-                    <SelectContent>
-                      {destinationPlaces.length > 0 ? (
-                        destinationPlaces.map((place) => (
-                          <SelectItem key={place.code} value={place.code} className="text-xs">
-                            {place.code}
-                          </SelectItem>
-                        ))
-                      ) : (
-                        <SelectItem value="loading" disabled className="text-xs">
-                          로딩중...
-                        </SelectItem>
-                      )}
-                    </SelectContent>
-                  </Select>
+                  <Popover>
+                    <PopoverTrigger asChild>
+                      <Button
+                        variant="outline"
+                        role="combobox"
+                        className={cn(
+                          "w-full justify-between h-8 text-xs",
+                          !formData.dischargeLocation && "text-muted-foreground"
+                        )}
+                      >
+                        {formData.dischargeLocation
+                          ? destinationPlaces.find((place) => place.code === formData.dischargeLocation)
+                            ? `${destinationPlaces.find((place) => place.code === formData.dischargeLocation)?.code} ${destinationPlaces.find((place) => place.code === formData.dischargeLocation)?.description ? `(${destinationPlaces.find((place) => place.code === formData.dischargeLocation)?.description})` : ''}`
+                            : formData.dischargeLocation
+                          : "하역지 선택"}
+                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+                      </Button>
+                    </PopoverTrigger>
+                    <PopoverContent className="w-[400px] p-0">
+                      <Command>
+                        <CommandInput placeholder="하역지 검색..." />
+                        <CommandList>
+                          <CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
+                          <CommandGroup>
+                            {destinationPlaces.length > 0 ? (
+                              destinationPlaces.map((place) => (
+                                <CommandItem
+                                  key={place.code}
+                                  value={`${place.code} ${place.description || ''}`}
+                                  onSelect={() => {
+                                    setFormData(prev => ({ ...prev, dischargeLocation: place.code }))
+                                  }}
+                                >
+                                  <Check
+                                    className={cn(
+                                      "mr-2 h-4 w-4",
+                                      place.code === formData.dischargeLocation
+                                        ? "opacity-100"
+                                        : "opacity-0"
+                                    )}
+                                  />
+                                  {place.code} {place.description && `(${place.description})`}
+                                </CommandItem>
+                              ))
+                            ) : (
+                              <CommandItem value="loading" disabled>
+                                로딩중...
+                              </CommandItem>
+                            )}
+                          </CommandGroup>
+                        </CommandList>
+                      </Command>
+                    </PopoverContent>
+                  </Popover>
                 </div>
 
                 {/* 계약납기일 */}
-- 
cgit v1.2.3

