summaryrefslogtreecommitdiff
path: root/lib/rfq-last
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last')
-rw-r--r--lib/rfq-last/attachment/rfq-attachments-table.tsx6
-rw-r--r--lib/rfq-last/service.ts29
-rw-r--r--lib/rfq-last/vendor/batch-update-conditions-dialog.tsx69
-rw-r--r--lib/rfq-last/vendor/vendor-detail-dialog.tsx10
4 files changed, 101 insertions, 13 deletions
diff --git a/lib/rfq-last/attachment/rfq-attachments-table.tsx b/lib/rfq-last/attachment/rfq-attachments-table.tsx
index 3098f8f5..d97d32fd 100644
--- a/lib/rfq-last/attachment/rfq-attachments-table.tsx
+++ b/lib/rfq-last/attachment/rfq-attachments-table.tsx
@@ -416,7 +416,7 @@ export function RfqAttachmentsTable({
if (activeTab !== '구매') {
return <span className="text-muted-foreground text-sm">-</span>;
}
-
+
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -442,7 +442,7 @@ export function RfqAttachmentsTable({
새 버전 업로드
</DropdownMenuItem>
<DropdownMenuSeparator />
- <DropdownMenuItem
+ <DropdownMenuItem
onClick={() => handleAction({ type: "delete", row })}
className="text-red-600"
>
@@ -455,7 +455,7 @@ export function RfqAttachmentsTable({
size: 60,
enablePinning: true,
},
- ], [handleAction]);
+ ], [handleAction, activeTab]);
const advancedFilterFields: DataTableAdvancedFilterField<RfqAttachment>[] = [
{ id: "serialNo", label: "일련번호", type: "text" },
diff --git a/lib/rfq-last/service.ts b/lib/rfq-last/service.ts
index f536a142..f600d04b 100644
--- a/lib/rfq-last/service.ts
+++ b/lib/rfq-last/service.ts
@@ -2574,6 +2574,35 @@ export async function getRfqAttachments(rfqId: number) {
return fullInfo.attachments;
}
+/**
+ * 특정 벤더의 현재 조건 조회
+ */
+export async function getVendorConditions(rfqId: number, vendorId: number) {
+ const fullInfo = await getRfqFullInfo(rfqId);
+ const vendor = fullInfo.vendors?.find(v => v.vendorId === vendorId);
+
+ if (!vendor) {
+ throw new Error('벤더 정보를 찾을 수 없습니다.');
+ }
+
+ return {
+ currency: vendor.currency,
+ paymentTermsCode: vendor.paymentTermsCode,
+ incotermsCode: vendor.incotermsCode,
+ incotermsDetail: vendor.incotermsDetail,
+ deliveryDate: vendor.deliveryDate,
+ contractDuration: vendor.contractDuration,
+ taxCode: vendor.taxCode,
+ placeOfShipping: vendor.placeOfShipping,
+ placeOfDestination: vendor.placeOfDestination,
+ materialPriceRelatedYn: vendor.materialPriceRelatedYn,
+ sparepartYn: vendor.sparepartYn,
+ firstYn: vendor.firstYn,
+ firstDescription: vendor.firstDescription,
+ sparepartDescription: vendor.sparepartDescription,
+ };
+}
+
// RFQ 발송용 데이터 타입
export interface RfqSendData {
diff --git a/lib/rfq-last/vendor/batch-update-conditions-dialog.tsx b/lib/rfq-last/vendor/batch-update-conditions-dialog.tsx
index 7eae48db..70d5569f 100644
--- a/lib/rfq-last/vendor/batch-update-conditions-dialog.tsx
+++ b/lib/rfq-last/vendor/batch-update-conditions-dialog.tsx
@@ -44,7 +44,7 @@ import { format } from "date-fns";
import { ko } from "date-fns/locale";
import { cn } from "@/lib/utils";
import { toast } from "sonner";
-import { updateVendorConditionsBatch } from "../service";
+import { updateVendorConditionsBatch, getVendorConditions } from "../service";
import { Badge } from "@/components/ui/badge";
import { TAX_CONDITIONS } from "@/lib/tax-conditions/types";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
@@ -72,8 +72,8 @@ interface BatchUpdateConditionsDialogProps {
}
// 타입 정의
-interface SelectOption {
- id: number;
+type SelectOption = {
+ id?: number;
code: string;
description: string;
}
@@ -169,7 +169,7 @@ export function BatchUpdateConditionsDialog({
setIncotermsLoading(true);
try {
const data = await getIncotermsForSelection();
- setIncoterms(data);
+ setIncoterms(data as unknown as SelectOption[]);
} catch (error) {
console.error("Failed to load incoterms:", error);
toast.error("Incoterms 목록을 불러오는데 실패했습니다.");
@@ -182,7 +182,7 @@ export function BatchUpdateConditionsDialog({
setPaymentTermsLoading(true);
try {
const data = await getPaymentTermsForSelection();
- setPaymentTerms(data);
+ setPaymentTerms(data as unknown as SelectOption[]);
} catch (error) {
console.error("Failed to load payment terms:", error);
toast.error("결제조건 목록을 불러오는데 실패했습니다.");
@@ -195,7 +195,7 @@ export function BatchUpdateConditionsDialog({
setShippingLoading(true);
try {
const data = await getPlaceOfShippingForSelection();
- setShippingPlaces(data);
+ setShippingPlaces(data as unknown as SelectOption[]);
} catch (error) {
console.error("Failed to load shipping places:", error);
toast.error("선적지 목록을 불러오는데 실패했습니다.");
@@ -208,7 +208,7 @@ export function BatchUpdateConditionsDialog({
setDestinationLoading(true);
try {
const data = await getPlaceOfDestinationForSelection();
- setDestinationPlaces(data);
+ setDestinationPlaces(data as unknown as SelectOption[]);
} catch (error) {
console.error("Failed to load destination places:", error);
toast.error("도착지 목록을 불러오는데 실패했습니다.");
@@ -217,6 +217,33 @@ export function BatchUpdateConditionsDialog({
}
}, []);
+ // 벤더별 조건 로드 함수
+ const loadVendorConditions = React.useCallback(async (vendorId: number) => {
+ try {
+ const conditions = await getVendorConditions(rfqId, vendorId);
+ // 가져온 조건으로 폼 초기화
+ form.reset({
+ currency: conditions.currency || "",
+ paymentTermsCode: conditions.paymentTermsCode || "",
+ incotermsCode: conditions.incotermsCode || "",
+ incotermsDetail: conditions.incotermsDetail || "",
+ deliveryDate: conditions.deliveryDate || undefined,
+ contractDuration: conditions.contractDuration || "",
+ taxCode: conditions.taxCode || "",
+ placeOfShipping: conditions.placeOfShipping || "",
+ placeOfDestination: conditions.placeOfDestination || "",
+ materialPriceRelatedYn: conditions.materialPriceRelatedYn || false,
+ sparepartYn: conditions.sparepartYn || false,
+ firstYn: conditions.firstYn || false,
+ firstDescription: conditions.firstDescription || "",
+ sparepartDescription: conditions.sparepartDescription || "",
+ });
+ } catch (error) {
+ console.error("Failed to load vendor conditions:", error);
+ toast.error("벤더 조건을 불러오는데 실패했습니다.");
+ }
+ }, [rfqId, form]);
+
// 초기 데이터 로드
React.useEffect(() => {
if (open) {
@@ -224,13 +251,35 @@ export function BatchUpdateConditionsDialog({
loadPaymentTerms();
loadShippingPlaces();
loadDestinationPlaces();
+
+ // 선택된 벤더가 1개일 때만 해당 벤더의 조건을 가져옴
+ if (selectedVendors.length === 1) {
+ loadVendorConditions(selectedVendors[0].id);
+ }
}
- }, [open, loadIncoterms, loadPaymentTerms, loadShippingPlaces, loadDestinationPlaces]);
+ }, [open, loadIncoterms, loadPaymentTerms, loadShippingPlaces, loadDestinationPlaces, selectedVendors, loadVendorConditions]);
// 다이얼로그 닫힐 때 초기화
React.useEffect(() => {
if (!open) {
- form.reset();
+ // 선택된 벤더가 2개 이상이거나 없다면 기본값으로 초기화
+ if (selectedVendors.length !== 1) {
+ form.reset({
+ currency: "",
+ paymentTermsCode: "",
+ incotermsCode: "",
+ incotermsDetail: "",
+ contractDuration: "",
+ taxCode: "",
+ placeOfShipping: "",
+ placeOfDestination: "",
+ materialPriceRelatedYn: false,
+ sparepartYn: false,
+ firstYn: false,
+ firstDescription: "",
+ sparepartDescription: "",
+ });
+ }
setFieldsToUpdate({
currency: false,
paymentTermsCode: false,
@@ -244,7 +293,7 @@ export function BatchUpdateConditionsDialog({
first: false,
});
}
- }, [open, form]);
+ }, [open, form, selectedVendors]);
// 제출 처리
const onSubmit = async (data: FormValues) => {
diff --git a/lib/rfq-last/vendor/vendor-detail-dialog.tsx b/lib/rfq-last/vendor/vendor-detail-dialog.tsx
index 074924eb..08288dd6 100644
--- a/lib/rfq-last/vendor/vendor-detail-dialog.tsx
+++ b/lib/rfq-last/vendor/vendor-detail-dialog.tsx
@@ -36,6 +36,7 @@ import {
Paperclip,
Info,
Edit,
+ X,
} from "lucide-react";
import { format } from "date-fns";
import { ko } from "date-fns/locale";
@@ -160,6 +161,15 @@ export function VendorResponseDetailDialog({
</DialogDescription>
</div>
<div className="flex items-center gap-2">
+ <Button
+ variant="ghost"
+ size="sm"
+ onClick={() => onOpenChange(false)}
+ className="h-8 w-8 p-0"
+ >
+ <X className="h-4 w-4" />
+ <span className="sr-only">창 닫기</span>
+ </Button>
{/* {onEdit && (
<Button variant="outline" size="sm" onClick={onEdit}>
<Edit className="h-4 w-4 mr-2" />