'use server' import db from '@/db/db' import { biddings, biddingCompanies, companyPrItemBids } from '@/db/schema/bidding' import { eq, and } from 'drizzle-orm' import { revalidateTag, revalidatePath } from 'next/cache' import { users } from '@/db/schema' // userId를 user.name으로 변환하는 유틸리티 함수 async function getUserNameById(userId: string): Promise { try { const user = await db .select({ name: users.name }) .from(users) .where(eq(users.id, parseInt(userId))) .limit(1) return user[0]?.name || userId } catch (error) { console.error('Failed to get user name:', error) return userId } } // 응찰 포기 서버 액션 (최종제출이 아닌 경우만 가능) export async function cancelBiddingResponse( biddingCompanyId: number, userId: string ) { try { const userName = await getUserNameById(userId) return await db.transaction(async (tx) => { // 1. 현재 상태 확인 (최종제출 여부) const [company] = await tx .select({ isFinalSubmission: biddingCompanies.isFinalSubmission, biddingId: biddingCompanies.biddingId, }) .from(biddingCompanies) .where(eq(biddingCompanies.id, biddingCompanyId)) .limit(1) if (!company) { return { success: false, error: '업체 정보를 찾을 수 없습니다.' } } // 최종제출한 경우 취소 불가 if (company.isFinalSubmission) { return { success: false, error: '최종 제출된 응찰은 취소할 수 없습니다.' } } // 2. 응찰 데이터 초기화 await tx .update(biddingCompanies) .set({ finalQuoteAmount: null, finalQuoteSubmittedAt: null, isFinalSubmission: false, invitationStatus: 'bidding_cancelled', // 응찰 포기 상태 updatedAt: new Date() }) .where(eq(biddingCompanies.id, biddingCompanyId)) // 3. 품목별 견적 삭제 (본입찰 데이터) await tx .delete(companyPrItemBids) .where( and( eq(companyPrItemBids.biddingCompanyId, biddingCompanyId), eq(companyPrItemBids.isPreQuote, false) ) ) // 캐시 무효화 revalidateTag(`bidding-${company.biddingId}`) revalidateTag('quotation-vendors') revalidateTag('quotation-details') revalidatePath(`/partners/bid/${company.biddingId}`) return { success: true, message: '응찰이 포기되었습니다.' } }) } catch (error) { console.error('Failed to cancel bidding response:', error) return { success: false, error: error instanceof Error ? error.message : '응찰 포기에 실패했습니다.' } } }