diff options
Diffstat (limited to 'lib/tech-vendors/service.ts')
| -rw-r--r-- | lib/tech-vendors/service.ts | 157 |
1 files changed, 150 insertions, 7 deletions
diff --git a/lib/tech-vendors/service.ts b/lib/tech-vendors/service.ts index 05ec1178..b2dec1ab 100644 --- a/lib/tech-vendors/service.ts +++ b/lib/tech-vendors/service.ts @@ -2,7 +2,7 @@ import { revalidateTag, unstable_noStore } from "next/cache"; import db from "@/db/db"; -import { techVendorAttachments, techVendorContacts, techVendorPossibleItems, techVendors, techVendorItemsView, type TechVendor } from "@/db/schema/techVendors"; +import { techVendorAttachments, techVendorContacts, techVendorPossibleItems, techVendors, techVendorItemsView, type TechVendor, techVendorCandidates } from "@/db/schema/techVendors"; import { items, itemShipbuilding, itemOffshoreTop, itemOffshoreHull } from "@/db/schema/items"; import { filterColumns } from "@/lib/filter-columns"; @@ -272,7 +272,7 @@ export async function createTechVendor(input: CreateTechVendorSchema) { phone: input.phone || null, email: input.email, website: input.website || null, - techVendorType: input.techVendorType as "조선" | "해양TOP" | "해양HULL", + techVendorType: Array.isArray(input.techVendorType) ? input.techVendorType.join(',') : input.techVendorType, representativeName: input.representativeName || null, representativeBirth: input.representativeBirth || null, representativeEmail: input.representativeEmail || null, @@ -1066,9 +1066,9 @@ export async function exportTechVendorDetails(vendorIds: number[]) { } /** - * 기술영업 벤더 상세 정보 조회 + * 기술영업 벤더 상세 정보 조회 (연락처, 첨부파일 포함) */ -async function getTechVendorDetailById(id: number) { +export async function getTechVendorDetailById(id: number) { try { const vendor = await db.select().from(techVendors).where(eq(techVendors.id, id)).limit(1); @@ -1255,7 +1255,7 @@ export async function importTechVendorsFromExcel( phone: vendor.phone || null, email: vendor.email, website: vendor.website || null, - techVendorType: vendor.techVendorType as "조선" | "해양TOP" | "해양HULL", + techVendorType: vendor.techVendorType, status: "ACTIVE", representativeName: vendor.representativeName || null, representativeEmail: vendor.representativeEmail || null, @@ -1345,6 +1345,149 @@ export async function findTechVendorById(id: number): Promise<TechVendor | null> } /** + * 회원가입 폼을 통한 기술영업 벤더 생성 (초대 토큰 기반) + */ +export async function createTechVendorFromSignup(params: { + vendorData: { + vendorName: string + vendorCode?: string + items: string + website?: string + taxId: string + address?: string + email: string + phone?: string + country: string + techVendorType: "조선" | "해양TOP" | "해양HULL" + representativeName?: string + representativeBirth?: string + representativeEmail?: string + representativePhone?: string + } + files?: File[] + contacts: { + contactName: string + contactPosition?: string + contactEmail: string + contactPhone?: string + isPrimary?: boolean + }[] + invitationToken?: string // 초대 토큰 +}) { + unstable_noStore(); + + try { + console.log("기술영업 벤더 회원가입 시작:", params.vendorData.vendorName); + + const result = await db.transaction(async (tx) => { + // 1. 이메일 중복 체크 + const existingVendor = await tx.query.techVendors.findFirst({ + where: eq(techVendors.email, params.vendorData.email), + columns: { id: true, vendorName: true } + }); + + if (existingVendor) { + throw new Error(`이미 등록된 이메일입니다: ${params.vendorData.email}`); + } + + // 2. 벤더 생성 + const [newVendor] = await tx.insert(techVendors).values({ + vendorName: params.vendorData.vendorName, + vendorCode: params.vendorData.vendorCode || null, + taxId: params.vendorData.taxId, + country: params.vendorData.country, + address: params.vendorData.address || null, + phone: params.vendorData.phone || null, + email: params.vendorData.email, + website: params.vendorData.website || null, + techVendorType: params.vendorData.techVendorType, + status: "ACTIVE", + representativeName: params.vendorData.representativeName || null, + representativeEmail: params.vendorData.representativeEmail || null, + representativePhone: params.vendorData.representativePhone || null, + representativeBirth: params.vendorData.representativeBirth || null, + items: params.vendorData.items, + }).returning(); + + console.log("기술영업 벤더 생성 성공:", newVendor.id); + + // 3. 연락처 생성 + if (params.contacts && params.contacts.length > 0) { + for (const [index, contact] of params.contacts.entries()) { + await tx.insert(techVendorContacts).values({ + vendorId: newVendor.id, + contactName: contact.contactName, + contactPosition: contact.contactPosition || null, + contactEmail: contact.contactEmail, + contactPhone: contact.contactPhone || null, + isPrimary: index === 0, // 첫 번째 연락처를 primary로 설정 + }); + } + console.log("연락처 생성 완료:", params.contacts.length, "개"); + } + + // 4. 첨부파일 처리 + if (params.files && params.files.length > 0) { + await storeTechVendorFiles(tx, newVendor.id, params.files, "GENERAL"); + console.log("첨부파일 저장 완료:", params.files.length, "개"); + } + + // 5. 유저 생성 (techCompanyId 설정) + console.log("유저 생성 시도:", params.vendorData.email); + + const existingUser = await tx.query.users.findFirst({ + where: eq(users.email, params.vendorData.email), + columns: { id: true, techCompanyId: true } + }); + + let userId = null; + if (!existingUser) { + const [newUser] = await tx.insert(users).values({ + name: params.vendorData.vendorName, + email: params.vendorData.email, + techCompanyId: newVendor.id, // 중요: techCompanyId 설정 + domain: "partners", + }).returning(); + userId = newUser.id; + console.log("유저 생성 성공:", userId); + } else { + // 기존 유저의 techCompanyId 업데이트 + if (!existingUser.techCompanyId) { + await tx.update(users) + .set({ techCompanyId: newVendor.id }) + .where(eq(users.id, existingUser.id)); + console.log("기존 유저의 techCompanyId 업데이트:", existingUser.id); + } + userId = existingUser.id; + } + + // 6. 후보에서 해당 이메일이 있으면 vendorId 업데이트 및 상태 변경 + if (params.vendorData.email) { + await tx.update(techVendorCandidates) + .set({ + vendorId: newVendor.id, + status: "INVITED" + }) + .where(eq(techVendorCandidates.contactEmail, params.vendorData.email)); + } + + return { vendor: newVendor, userId }; + }); + + // 캐시 무효화 + revalidateTag("tech-vendors"); + revalidateTag("tech-vendor-candidates"); + revalidateTag("users"); + + console.log("기술영업 벤더 회원가입 완료:", result); + return { success: true, data: result }; + } catch (error) { + console.error("기술영업 벤더 회원가입 실패:", error); + return { success: false, error: getErrorMessage(error) }; + } +} + +/** * 단일 기술영업 벤더 추가 (사용자 계정도 함께 생성) */ export async function addTechVendor(input: { @@ -1361,7 +1504,7 @@ export async function addTechVendor(input: { address?: string | null; phone?: string | null; website?: string | null; - techVendorType: "조선" | "해양TOP" | "해양HULL"; + techVendorType: string; representativeName?: string | null; representativeEmail?: string | null; representativePhone?: string | null; @@ -1404,7 +1547,7 @@ export async function addTechVendor(input: { phone: input.phone || null, email: input.email, website: input.website || null, - techVendorType: input.techVendorType, + techVendorType: Array.isArray(input.techVendorType) ? input.techVendorType.join(',') : input.techVendorType, status: "ACTIVE", representativeName: input.representativeName || null, representativeEmail: input.representativeEmail || null, |
