"use server"; import { unstable_noStore } from "next/cache"; import { and, desc, eq, count } from "drizzle-orm"; import db from "@/db/db"; import { vendorPossibleMaterials, vendors, vendorTypes } from "@/db/schema/vendors"; // 타입 정의 export interface VendorPossibleMaterial { id: number; vendorId: number; itemCode: string | null; itemName: string | null; registerUserId: number | null; registerUserName: string | null; isConfirmed: boolean | null; recentPoNo: string | null; recentPoDate: Date | null; recentDeliveryDate: Date | null; recentOrderDate: Date | null; recentOrderUserName: string | null; purchaseGroupCode: string | null; createdAt: Date; updatedAt: Date; // 업체유형 정보 추가 vendorTypeNameEn?: string | null; vendorTypeName?: string | null; } export interface GetVendorMaterialsParams { vendorId: number; page?: number; perPage?: number; isConfirmed?: boolean; // true: 확정정보, false: 업체입력정보 } export interface VendorMaterialsResult { data: VendorPossibleMaterial[]; total: number; pageCount: number; } /** * 확정정보 공급품목 전체 조회 (클라이언트 사이드 처리용) */ export async function getAllConfirmedMaterials( vendorId: number ): Promise { unstable_noStore(); try { const baseConditions = [ eq(vendorPossibleMaterials.vendorId, vendorId), eq(vendorPossibleMaterials.isConfirmed, true) ]; const whereCondition = and(...baseConditions); const data = await db .select({ id: vendorPossibleMaterials.id, vendorId: vendorPossibleMaterials.vendorId, itemCode: vendorPossibleMaterials.itemCode, itemName: vendorPossibleMaterials.itemName, registerUserId: vendorPossibleMaterials.registerUserId, registerUserName: vendorPossibleMaterials.registerUserName, isConfirmed: vendorPossibleMaterials.isConfirmed, recentPoNo: vendorPossibleMaterials.recentPoNo, recentPoDate: vendorPossibleMaterials.recentPoDate, recentDeliveryDate: vendorPossibleMaterials.recentDeliveryDate, recentOrderDate: vendorPossibleMaterials.recentOrderDate, recentOrderUserName: vendorPossibleMaterials.recentOrderUserName, purchaseGroupCode: vendorPossibleMaterials.purchaseGroupCode, createdAt: vendorPossibleMaterials.createdAt, updatedAt: vendorPossibleMaterials.updatedAt, vendorTypeNameEn: vendorTypes.nameEn, vendorTypeName: vendorTypes.nameKo, }) .from(vendorPossibleMaterials) .leftJoin(vendors, eq(vendorPossibleMaterials.vendorId, vendors.id)) .leftJoin(vendorTypes, eq(vendors.vendorTypeId, vendorTypes.id)) .where(whereCondition) .orderBy(desc(vendorPossibleMaterials.createdAt)); return data; } catch (error) { console.error("확정정보 공급품목 조회 실패:", error); return []; } } /** * 업체입력정보 공급품목 전체 조회 (클라이언트 사이드 처리용) */ export async function getAllVendorInputMaterials( vendorId: number ): Promise { unstable_noStore(); try { const baseConditions = [ eq(vendorPossibleMaterials.vendorId, vendorId), eq(vendorPossibleMaterials.isConfirmed, false) ]; const whereCondition = and(...baseConditions); const data = await db .select({ id: vendorPossibleMaterials.id, vendorId: vendorPossibleMaterials.vendorId, itemCode: vendorPossibleMaterials.itemCode, itemName: vendorPossibleMaterials.itemName, registerUserId: vendorPossibleMaterials.registerUserId, registerUserName: vendorPossibleMaterials.registerUserName, isConfirmed: vendorPossibleMaterials.isConfirmed, recentPoNo: vendorPossibleMaterials.recentPoNo, recentPoDate: vendorPossibleMaterials.recentPoDate, recentDeliveryDate: vendorPossibleMaterials.recentDeliveryDate, recentOrderDate: vendorPossibleMaterials.recentOrderDate, recentOrderUserName: vendorPossibleMaterials.recentOrderUserName, purchaseGroupCode: vendorPossibleMaterials.purchaseGroupCode, createdAt: vendorPossibleMaterials.createdAt, updatedAt: vendorPossibleMaterials.updatedAt, vendorTypeNameEn: vendorTypes.nameEn, vendorTypeName: vendorTypes.nameKo, }) .from(vendorPossibleMaterials) .leftJoin(vendors, eq(vendorPossibleMaterials.vendorId, vendors.id)) .leftJoin(vendorTypes, eq(vendors.vendorTypeId, vendorTypes.id)) .where(whereCondition) .orderBy(desc(vendorPossibleMaterials.createdAt)); return data; } catch (error) { console.error("업체입력정보 공급품목 조회 실패:", error); return []; } } /** * 확정정보 자재 추가 (구매담당자용) */ export async function addConfirmedMaterial( vendorId: number, materialData: { itemCode: string; itemName: string; recentPoNo?: string; recentPoDate?: Date; recentDeliveryDate?: Date; recentOrderDate?: Date; recentOrderUserName?: string; purchaseGroupCode?: string; }, registerUserId: number, registerUserName: string ) { unstable_noStore(); try { // 중복 확인 - 같은 vendorId와 itemCode 조합이 이미 확정정보에 있는지 체크 const existingMaterial = await db .select() .from(vendorPossibleMaterials) .where( and( eq(vendorPossibleMaterials.vendorId, vendorId), eq(vendorPossibleMaterials.itemCode, materialData.itemCode), eq(vendorPossibleMaterials.isConfirmed, true) ) ) .limit(1); if (existingMaterial.length > 0) { throw new Error(`자재그룹코드 ${materialData.itemCode}는 이미 확정정보에 등록되어 있습니다.`); } // 새 확정정보 추가 const result = await db .insert(vendorPossibleMaterials) .values({ vendorId, itemCode: materialData.itemCode, itemName: materialData.itemName, registerUserId, registerUserName, isConfirmed: true, recentPoNo: materialData.recentPoNo || null, recentPoDate: materialData.recentPoDate || null, recentDeliveryDate: materialData.recentDeliveryDate || null, recentOrderDate: materialData.recentOrderDate || null, recentOrderUserName: materialData.recentOrderUserName || null, purchaseGroupCode: materialData.purchaseGroupCode || null, createdAt: new Date(), updatedAt: new Date(), }) .returning(); console.log(`확정정보 자재 추가 성공: vendorId=${vendorId}, itemCode=${materialData.itemCode}, 등록자=${registerUserName}`); return result[0]; } catch (error) { console.error("확정정보 자재 추가 실패:", error); throw error; } }