"use server"; import db from "@/db/db"; import { incoterms } from "@/db/schema/procurementRFQ"; import { GetIncotermsSchema } from "@/lib/incoterms/validations"; import { filterColumns } from "@/lib/filter-columns"; import { asc, desc, ilike, and, or, count, eq } from "drizzle-orm"; // Incoterms CRUD export async function getIncoterms(input: GetIncotermsSchema) { try { const offset = (input.page - 1) * input.perPage; // 1. where 절 let advancedWhere; try { advancedWhere = filterColumns({ table: incoterms, filters: input.filters, joinOperator: input.joinOperator, }); } catch (whereErr) { console.error("Error building advanced where:", whereErr); advancedWhere = undefined; } let globalWhere; if (input.search) { try { const s = `%${input.search}%`; globalWhere = or( ilike(incoterms.code, s), ilike(incoterms.description, s) ); } catch (searchErr) { console.error("Error building search where:", searchErr); globalWhere = undefined; } } // 2. where 결합 let finalWhere; if (advancedWhere && globalWhere) { finalWhere = and(advancedWhere, globalWhere); } else { finalWhere = advancedWhere || globalWhere; } // 3. order by let orderBy; try { orderBy = input.sort.length > 0 ? input.sort .map((item) => { if (!item || !item.id || typeof item.id !== "string" || !(item.id in incoterms)) return null; const col = incoterms[item.id as keyof typeof incoterms]; return item.desc ? desc(col) : asc(col); }) .filter((v): v is Exclude => v !== null) : [asc(incoterms.createdAt)]; } catch (orderErr) { console.error("Error building order by:", orderErr); orderBy = [asc(incoterms.createdAt)]; } // 4. 쿼리 실행 let data = []; let total = 0; try { const queryBuilder = db.select().from(incoterms); if (finalWhere) { queryBuilder.where(finalWhere); } if (orderBy && orderBy.length > 0) { queryBuilder.orderBy(...orderBy); } if (typeof offset === "number" && !isNaN(offset)) { queryBuilder.offset(offset); } if (typeof input.perPage === "number" && !isNaN(input.perPage)) { queryBuilder.limit(input.perPage); } data = await queryBuilder; const countBuilder = db .select({ count: count() }) .from(incoterms); if (finalWhere) { countBuilder.where(finalWhere); } const countResult = await countBuilder; total = countResult[0]?.count || 0; } catch (queryErr) { console.error("Query execution failed:", queryErr); throw queryErr; } const pageCount = Math.ceil(total / input.perPage); return { data, pageCount }; } catch (err) { console.error("Error in getIncoterms:", err); if (err instanceof Error) { console.error("Error message:", err.message); console.error("Error stack:", err.stack); } return { data: [], pageCount: 0 }; } } export async function createIncoterm(data: Omit) { try { const [created] = await db.insert(incoterms).values(data).returning(); return { data: created }; } catch (err) { console.error("Error creating incoterm:", err); return { error: "생성 중 오류가 발생했습니다." }; } } export async function updateIncoterm(code: string, data: Partial) { try { const [updated] = await db .update(incoterms) .set(data) .where(eq(incoterms.code, code)) .returning(); return { data: updated }; } catch (err) { console.error("Error updating incoterm:", err); return { error: "수정 중 오류가 발생했습니다." }; } } export async function deleteIncoterm(code: string) { try { await db.delete(incoterms).where(eq(incoterms.code, code)); return { success: true }; } catch (err) { console.error("Error deleting incoterm:", err); return { error: "삭제 중 오류가 발생했습니다." }; } }