diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-01 00:58:23 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-01 00:58:23 +0000 |
| commit | 8440ac29c7dcbef992039678ecc0fabff2fd04ec (patch) | |
| tree | 59092b8dcd22135009bf70d5863ffde444e5bed2 /lib/forms-plant | |
| parent | 748f68bb7b5d02450664651ae5025c9a38fb71a5 (diff) | |
(대표님) S-EDP 관련 대표님 작업사항
Diffstat (limited to 'lib/forms-plant')
| -rw-r--r-- | lib/forms-plant/services.ts | 458 | ||||
| -rw-r--r-- | lib/forms-plant/stat.ts | 32 |
2 files changed, 223 insertions, 267 deletions
diff --git a/lib/forms-plant/services.ts b/lib/forms-plant/services.ts index 219f36e4..7e1976e6 100644 --- a/lib/forms-plant/services.ts +++ b/lib/forms-plant/services.ts @@ -7,18 +7,18 @@ import fs from "fs/promises"; import { v4 as uuidv4 } from "uuid"; import db from "@/db/db"; import { - formEntries, - formMetas, + formEntries,formEntriesPlant, + formMetas,formsPlant, forms, tagClassAttributes, tagClasses, - tags, + tags,tagsPlant, tagSubfieldOptions, tagSubfields, tagTypeClassFormMappings, tagTypes, - vendorDataReportTemps, - VendorDataReportTemps, + vendorDataReportTempsPlant, + VendorDataReportTempsPlant, } from "@/db/schema/vendorData"; import { eq, and, desc, sql, DrizzleError, inArray, or, type SQL, type InferSelectModel } from "drizzle-orm"; import { unstable_cache } from "next/cache"; @@ -29,6 +29,7 @@ import { contractItems, contracts, items, projects } from "@/db/schema"; import { getSEDPToken } from "../sedp/sedp-token"; import { decryptWithServerAction } from "@/components/drm/drmUtils"; import { deleteFile, saveFile } from "@/lib/file-stroage"; +import { Register } from "@/components/form-data-plant/form-data-table-columns"; export type FormInfo = InferSelectModel<typeof forms>; @@ -164,7 +165,8 @@ export interface EditableFieldsInfo { // TAG별 편집 가능 필드 조회 함수 export async function getEditableFieldsByTag( - contractItemId: number, + projectCode: string, + packageCode: string, projectId: number ): Promise<Map<string, string[]>> { try { @@ -174,8 +176,11 @@ export async function getEditableFieldsByTag( tagNo: tags.tagNo, tagClass: tags.class }) - .from(tags) - .where(eq(tags.contractItemId, contractItemId)); + .from(tagsPlant) + .where( + eq(tagsPlant.projectCode, projectCode), + eq(tagsPlant.packageCode, packageCode), + ); const editableFieldsMap = new Map<string, string[]>(); @@ -228,26 +233,17 @@ export async function getEditableFieldsByTag( * data가 배열이면 그 배열을 반환, * 그리고 이 로직 전체를 unstable_cache로 감싸 캐싱. */ -export async function getFormData(formCode: string, contractItemId: number) { +export async function getFormData(formCode: string, projectCode: string, packageCode:string) { try { - // 기존 로직으로 projectId, columns, data 가져오기 - const contractItemResult = await db - .select({ - projectId: projects.id - }) - .from(contractItems) - .innerJoin(contracts, eq(contractItems.contractId, contracts.id)) - .innerJoin(projects, eq(contracts.projectId, projects.id)) - .where(eq(contractItems.id, contractItemId)) - .limit(1); - - if (contractItemResult.length === 0) { - console.warn(`[getFormData] No contract item found with ID: ${contractItemId}`); - return { columns: null, data: [], editableFieldsMap: new Map() }; - } + const project = await db.query.projects.findFirst({ + where: eq(projects.code, projectCode), + columns: { + id: true + } + }); - const projectId = contractItemResult[0].projectId; + const projectId = project.id; const metaRows = await db .select() @@ -269,14 +265,15 @@ export async function getFormData(formCode: string, contractItemId: number) { const entryRows = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode), ) ) - .orderBy(desc(formEntries.updatedAt)) + .orderBy(desc(formEntriesPlant.updatedAt)) .limit(1); const entry = entryRows[0] ?? null; @@ -321,7 +318,7 @@ export async function getFormData(formCode: string, contractItemId: number) { } // *** 새로 추가: 편집 가능 필드 정보 계산 *** - const editableFieldsMap = await getEditableFieldsByTag(contractItemId, projectId); + const editableFieldsMap = await getEditableFieldsByTag(projectCode,packageCode ,projectId); return { columns, data, editableFieldsMap }; @@ -331,24 +328,16 @@ export async function getFormData(formCode: string, contractItemId: number) { // Fallback logic (기존과 동일하게 editableFieldsMap 추가) try { - console.log(`[getFormData] Fallback DB query for (${formCode}, ${contractItemId})`); - - const contractItemResult = await db - .select({ - projectId: projects.id - }) - .from(contractItems) - .innerJoin(contracts, eq(contractItems.contractId, contracts.id)) - .innerJoin(projects, eq(contracts.projectId, projects.id)) - .where(eq(contractItems.id, contractItemId)) - .limit(1); + console.log(`[getFormData] Fallback DB query for (${formCode}, ${packageCode})`); - if (contractItemResult.length === 0) { - console.warn(`[getFormData] Fallback: No contract item found with ID: ${contractItemId}`); - return { columns: null, data: [], editableFieldsMap: new Map() }; - } + const project = await db.query.projects.findFirst({ + where: eq(projects.code, projectCode), + columns: { + id: true + } + }); - const projectId = contractItemResult[0].projectId; + const projectId = project.id; const metaRows = await db .select() @@ -370,14 +359,15 @@ export async function getFormData(formCode: string, contractItemId: number) { const entryRows = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode) ) ) - .orderBy(desc(formEntries.updatedAt)) + .orderBy(desc(formEntriesPlant.updatedAt)) .limit(1); const entry = entryRows[0] ?? null; @@ -406,7 +396,7 @@ export async function getFormData(formCode: string, contractItemId: number) { } // Fallback에서도 편집 가능 필드 정보 계산 - const editableFieldsMap = await getEditableFieldsByTag(contractItemId, projectId); + const editableFieldsMap = await getEditableFieldsByTag(projectCode, packageCode, projectId); return { columns, data, projectId, editableFieldsMap }; } catch (dbError) { @@ -415,7 +405,7 @@ export async function getFormData(formCode: string, contractItemId: number) { } } } -/**1 +/** * contractId와 formCode(itemCode)를 사용하여 contractItemId를 찾는 서버 액션 * * @param contractId - 계약 ID @@ -517,24 +507,26 @@ export async function getPackageCodeById(contractItemId: number): Promise<string export async function syncMissingTags( - contractItemId: number, + projectCode: string, + packageCode: string, formCode: string ) { // (1) Ensure there's a row in `forms` matching (contractItemId, formCode). const [formRow] = await db .select() - .from(forms) + .from(formsPlant) .where( and( - eq(forms.contractItemId, contractItemId), - eq(forms.formCode, formCode) + eq(formsPlant.projectCode, projectCode), + eq(formsPlant.packageCode, packageCode), + eq(formsPlant.formCode, formCode) ) ) .limit(1); if (!formRow) { throw new Error( - `Form not found for contractItemId=${contractItemId}, formCode=${formCode}` + `Form not found for projectCode=${projectCode}, formCode=${formCode}` ); } @@ -558,26 +550,28 @@ export async function syncMissingTags( // (3) Fetch all matching `tags` for the contractItemId + any of the (tagType, class) pairs. const tagRows = await db .select() - .from(tags) - .where(and(eq(tags.contractItemId, contractItemId), or(...orConditions))); + .from(tagsPlant) + .where(and(eq(tagsPlant.packageCode, packageCode),eq(tagsPlant.projectCode, projectCode), or(...orConditions))); // (4) Fetch (or create) a single `formEntries` row for (contractItemId, formCode). let [entry] = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.contractItemId, contractItemId), - eq(formEntries.formCode, formCode) + eq(formEntriesPlant.packageCode, packageCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.formCode, formCode) ) ) .limit(1); if (!entry) { const [inserted] = await db - .insert(formEntries) + .insert(formEntriesPlant) .values({ - contractItemId, + projectCode, + packageCode, formCode, data: [], // Initialize with empty array }) @@ -646,13 +640,13 @@ export async function syncMissingTags( // (6) 실제로 추가되거나 수정되거나 삭제된 게 있다면 DB에 반영 if (createdCount > 0 || updatedCount > 0 || deletedCount > 0) { await db - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedData }) - .where(eq(formEntries.id, entry.id)); + .where(eq(formEntriesPlant.id, entry.id)); } // 캐시 무효화 등 후처리 - revalidateTag(`form-data-${formCode}-${contractItemId}`); + // revalidateTag(`form-data-${formCode}-${projectCode}`); return { createdCount, updatedCount, deletedCount }; } @@ -681,7 +675,8 @@ export interface UpdateResponse { export async function updateFormDataInDB( formCode: string, - contractItemId: number, + projectCode: string, + packageCode: string, newData: Record<string, any> ): Promise<UpdateResponse> { try { @@ -697,11 +692,12 @@ export async function updateFormDataInDB( // 2) row 찾기 (단 하나) const entries = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntries.projectCode, projectCode), + eq(formEntries.packageCode, packageCode), ) ) .limit(1); @@ -756,12 +752,12 @@ export async function updateFormDataInDB( // 6) DB UPDATE try { await db - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedArray, updatedAt: new Date(), // 업데이트 시간도 갱신 }) - .where(eq(formEntries.id, entry.id)); + .where(eq(formEntriesPlant.id, entry.id)); } catch (dbError) { console.error("Database update error:", dbError); @@ -781,7 +777,7 @@ export async function updateFormDataInDB( // 7) Cache 무효화 try { // 캐시 태그를 form-data-${formCode}-${contractItemId} 형태로 가정 - const cacheTag = `form-data-${formCode}-${contractItemId}`; + const cacheTag = `form-data-${formCode}-${projectCode}`; console.log(cacheTag, "update") revalidateTag(cacheTag); } catch (cacheError) { @@ -814,7 +810,8 @@ export async function updateFormDataInDB( export async function updateFormDataBatchInDB( formCode: string, - contractItemId: number, + projectCode: string, + packageCode: string, newDataArray: Record<string, any>[] ): Promise<UpdateResponse> { try { @@ -839,11 +836,12 @@ export async function updateFormDataBatchInDB( // 1) DB에서 현재 데이터 가져오기 const entries = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode), ) ) .limit(1); @@ -851,7 +849,7 @@ export async function updateFormDataBatchInDB( if (!entries || entries.length === 0) { return { success: false, - message: `폼 데이터를 찾을 수 없습니다. (formCode=${formCode}, contractItemId=${contractItemId})`, + message: `폼 데이터를 찾을 수 없습니다. (formCode=${formCode}, projectCode=${projectCode})`, }; } @@ -918,12 +916,12 @@ export async function updateFormDataBatchInDB( // 3) DB에 한 번만 저장 try { await db - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedArray, updatedAt: new Date(), }) - .where(eq(formEntries.id, entry.id)); + .where(eq(formEntriesPlant.id, entry.id)); } catch (dbError) { console.error("Database update error:", dbError); @@ -952,7 +950,7 @@ export async function updateFormDataBatchInDB( // 4) 캐시 무효화 try { - const cacheTag = `form-data-${formCode}-${contractItemId}`; + const cacheTag = `form-data-${formCode}-${projectCode}`; console.log(`Cache invalidated: ${cacheTag}`); revalidateTag(cacheTag); } catch (cacheError) { @@ -1043,26 +1041,37 @@ export async function fetchFormMetadata( } type GetReportFileList = ( - packageId: string, - formCode: string + projectCode: string, + packageCode: string, + formCode: string, + mode: string ) => Promise<{ formId: number; }>; -export const getFormId: GetReportFileList = async (packageId, formCode) => { +export const getFormId: GetReportFileList = async (projectCode, packageCode, formCode, mode) => { const result: { formId: number } = { formId: 0, }; try { + // mode에 따른 조건 배열 생성 + const conditions = [ + eq(formsPlant.formCode, formCode), + eq(formsPlant.projectCode, projectCode), + eq(formsPlant.packageCode, packageCode), + ]; + + // mode에 따라 추가 조건 설정 + if (mode === "IM") { + conditions.push(eq(formsPlant.im, true)); + } else if (mode === "ENG") { + conditions.push(eq(formsPlant.eng, true)); + } + const [targetForm] = await db .select() - .from(forms) - .where( - and( - eq(forms.formCode, formCode), - eq(forms.contractItemId, Number(packageId)) - ) - ); + .from(formsPlant) + .where(and(...conditions)); if (!targetForm) { throw new Error("Not Found Target Form"); @@ -1072,30 +1081,34 @@ export const getFormId: GetReportFileList = async (packageId, formCode) => { result.formId = formId; } catch (err) { + console.error("Error getting form ID:", err); } finally { return result; } }; type getReportTempList = ( - packageId: number, + projectCode: string, + packageCode: string, formId: number -) => Promise<VendorDataReportTemps[]>; +) => Promise<VendorDataReportTempsPlant[]>; export const getReportTempList: getReportTempList = async ( - packageId, + projectCode, + packageCode, formId ) => { - let result: VendorDataReportTemps[] = []; + let result: VendorDataReportTempsPlant[] = []; try { result = await db .select() - .from(vendorDataReportTemps) + .from(vendorDataReportTempsPlant) .where( and( - eq(vendorDataReportTemps.contractItemId, packageId), - eq(vendorDataReportTemps.formId, formId) + eq(vendorDataReportTempsPlant.projectCode, projectCode), + eq(vendorDataReportTempsPlant.packageCode, packageCode), + eq(vendorDataReportTempsPlant.formId, formId) ) ); } catch (err) { @@ -1105,7 +1118,8 @@ export const getReportTempList: getReportTempList = async ( }; export async function uploadReportTemp( - packageId: number, + projectCode: string, + packageCode: string, formId: number, formData: FormData ) { @@ -1128,9 +1142,10 @@ export async function uploadReportTemp( return db.transaction(async (tx) => { // 파일 정보를 테이블에 저장 await tx - .insert(vendorDataReportTemps) + .insert(vendorDataReportTempsPlant) .values({ - contractItemId: packageId, + projectCode, + packageCode, formId: formId, fileName: customFileName, filePath: saveResult.publicPath!, @@ -1160,16 +1175,16 @@ export const deleteReportTempFile: deleteReportTempFile = async (id) => { return db.transaction(async (tx) => { const [targetTempFile] = await tx .select() - .from(vendorDataReportTemps) - .where(eq(vendorDataReportTemps.id, id)); + .from(vendorDataReportTempsPlant) + .where(eq(vendorDataReportTempsPlant.id, id)); if (!targetTempFile) { throw new Error("해당 Template File을 찾을 수 없습니다."); } await tx - .delete(vendorDataReportTemps) - .where(eq(vendorDataReportTemps.id, id)); + .delete(vendorDataReportTempsPlant) + .where(eq(vendorDataReportTempsPlant.id, id)); const { filePath } = targetTempFile; @@ -1310,7 +1325,8 @@ async function transformDataToSEDPFormat( formCode: string, objectCode: string, projectNo: string, - contractItemId: number, // Add contractItemId parameter + packageCode: string, + contractItemId: string, designerNo: string = "253213" ): Promise<SEDPDataItem[]> { // Create a map for quick column lookup @@ -1331,9 +1347,6 @@ async function transformDataToSEDPFormat( // Cache for UOM factors to avoid duplicate API calls const uomFactorCache = new Map<string, number>(); - // Cache for packageCode to avoid duplicate DB queries for same tag - const packageCodeCache = new Map<string, string>(); - // Cache for tagClass code to avoid duplicate DB queries for same tag const tagClassCodeCache = new Map<string, string>(); @@ -1341,97 +1354,15 @@ async function transformDataToSEDPFormat( const transformedItems = []; for (const row of tableData) { + let tagClassCode = ""; - const cotractItem = await db.query.contractItems.findFirst({ - where: - eq(contractItems.id, contractItemId), - }); - - const item = await db.query.items.findFirst({ - where: - eq(items.id, cotractItem.itemId), - }); - - // Get packageCode for this specific tag - let packageCode = item.packageCode; // fallback to formCode - let tagClassCode = ""; // for CLS_ID - + // Get tagClass code if TAG_NO exists if (row.TAG_NO && contractItemId) { - // Check cache first const cacheKey = `${contractItemId}-${row.TAG_NO}`; - if (packageCodeCache.has(cacheKey)) { - packageCode = packageCodeCache.get(cacheKey)!; - } else { - try { - // Query to get packageCode for this specific tag - const tagResult = await db.query.tags.findFirst({ - where: and( - eq(tags.contractItemId, contractItemId), - eq(tags.tagNo, row.TAG_NO) - ) - }); - - if (tagResult) { - // Get tagClass code if tagClassId exists - if (tagResult.tagClassId) { - // Check tagClass cache first - if (tagClassCodeCache.has(cacheKey)) { - tagClassCode = tagClassCodeCache.get(cacheKey)!; - } else { - const tagClassResult = await db.query.tagClasses.findFirst({ - where: eq(tagClasses.id, tagResult.tagClassId) - }); - - if (tagClassResult) { - tagClassCode = tagClassResult.code; - console.log(`Found tagClass code for tag ${row.TAG_NO}: ${tagClassCode}`); - } else { - console.warn(`No tagClass found for tagClassId: ${tagResult.tagClassId}`); - } - - // Cache the tagClass code result - tagClassCodeCache.set(cacheKey, tagClassCode); - } - } - - // Get the contract item - const contractItemResult = await db.query.contractItems.findFirst({ - where: eq(contractItems.id, tagResult.contractItemId) - }); - - if (contractItemResult) { - // Get the first item with this itemId - const itemResult = await db.query.items.findFirst({ - where: eq(items.id, contractItemResult.itemId) - }); - - if (itemResult && itemResult.packageCode) { - packageCode = itemResult.packageCode; - console.log(`Found packageCode for tag ${row.TAG_NO}: ${packageCode}`); - } else { - console.warn(`No item found for contractItem.itemId: ${contractItemResult.itemId}, using fallback`); - } - } else { - console.warn(`No contractItem found for tag ${row.TAG_NO}, using fallback`); - } - } else { - console.warn(`No tag found for contractItemId: ${contractItemId}, tagNo: ${row.TAG_NO}, using fallback`); - } - - // Cache the result (even if it's the fallback value) - packageCodeCache.set(cacheKey, packageCode); - } catch (error) { - console.error(`Error fetching packageCode for tag ${row.TAG_NO}:`, error); - // Use fallback value and cache it - packageCodeCache.set(cacheKey, packageCode); - } - } - - // Get tagClass code if not already retrieved above - if (!tagClassCode && tagClassCodeCache.has(cacheKey)) { + if (tagClassCodeCache.has(cacheKey)) { tagClassCode = tagClassCodeCache.get(cacheKey)!; - } else if (!tagClassCode) { + } else { try { const tagResult = await db.query.tags.findFirst({ where: and( @@ -1440,22 +1371,20 @@ async function transformDataToSEDPFormat( ) }); - if (tagResult && tagResult.tagClassId) { + if (tagResult?.tagClassId) { const tagClassResult = await db.query.tagClasses.findFirst({ where: eq(tagClasses.id, tagResult.tagClassId) }); - + if (tagClassResult) { tagClassCode = tagClassResult.code; console.log(`Found tagClass code for tag ${row.TAG_NO}: ${tagClassCode}`); } } - // Cache the tagClass code result tagClassCodeCache.set(cacheKey, tagClassCode); } catch (error) { - console.error(`Error fetching tagClass code for tag ${row.TAG_NO}:`, error); - // Cache empty string as fallback + console.error(`Error fetching tagClass for tag ${row.TAG_NO}:`, error); tagClassCodeCache.set(cacheKey, ""); } } @@ -1466,17 +1395,16 @@ async function transformDataToSEDPFormat( TAG_NO: row.TAG_NO || "", TAG_DESC: row.TAG_DESC || "", ATTRIBUTES: [], - // SCOPE: objectCode, SCOPE: packageCode, - TOOLID: "eVCP", // Changed from VDCS + TOOLID: "eVCP", ITM_NO: row.TAG_NO || "", - OP_DELETE: row.status === "Deleted", // Set OP_DELETE based on status + OP_DELETE: row.status === "Deleted", MAIN_YN: true, LAST_REV_YN: true, CRTER_NO: designerNo, CHGER_NO: designerNo, - TYPE: formCode, // Use packageCode instead of formCode - CLS_ID: tagClassCode, // Add CLS_ID with tagClass code + TYPE: formCode, + CLS_ID: tagClassCode, PROJ_NO: projectNo, REV_NO: "00", CRTE_DTM: currentTimestamp, @@ -1522,7 +1450,7 @@ async function transformDataToSEDPFormat( const uomData = await response.json(); if (uomData && uomData.FACTOR !== undefined && uomData.FACTOR !== null) { factor = Number(uomData.FACTOR); - // Store in cache for future use (type assertion to ensure it's a number) + // Store in cache for future use uomFactorCache.set(column.uomId, factor); } } else { @@ -1533,7 +1461,7 @@ async function transformDataToSEDPFormat( } } - // Apply the factor if we got one + // Apply the factor if needed (currently commented out) // if (factor !== undefined && typeof value === 'number') { // value = value * factor; // } @@ -1541,7 +1469,7 @@ async function transformDataToSEDPFormat( const attribute: SEDPAttribute = { NAME: key, - VALUE: String(value), // 모든 값을 문자열로 변환 + VALUE: String(value), UOM: column?.uom || "", CLS_ID: tagClassCode || "", }; @@ -1569,7 +1497,7 @@ export async function transformFormDataToSEDP( formCode: string, objectCode: string, projectNo: string, - contractItemId: number, // Add contractItemId parameter + packageCode: string, // Add contractItemId parameter designerNo: string = "253213" ): Promise<SEDPDataItem[]> { return transformDataToSEDPFormat( @@ -1578,7 +1506,7 @@ export async function transformFormDataToSEDP( formCode, objectCode, projectNo, - contractItemId, // Pass contractItemId + packageCode, designerNo ); } @@ -1599,6 +1527,20 @@ export async function getProjectCodeById(projectId: number): Promise<string> { return projectRecord[0].code; } +export async function getProjectIdByCode(projectCode: string): Promise<number> { + const projectRecord = await db + .select({ id: projects.id }) + .from(projects) + .where(eq(projects.code, projectCode)) + .limit(1); + + if (!projectRecord || projectRecord.length === 0) { + throw new Error(`Project not found with ID: ${projectId}`); + } + + return projectRecord[0].id; +} + export async function getProjectById(projectId: number): Promise<{ code: string; type: string; }> { const projectRecord = await db .select({ code: projects.code , type:projects.type}) @@ -1679,13 +1621,13 @@ export async function sendDataToSEDP( export async function sendFormDataToSEDP( formCode: string, projectId: number, - contractItemId: number, // contractItemId 파라미터 추가 + projectCode: string, // contractItemId 파라미터 추가 + packageCode: string, // contractItemId 파라미터 추가 formData: GenericData[], columns: DataTableColumnJSON[] ): Promise<{ success: boolean; message: string; data?: any }> { try { // 1. Get project code - const projectCode = await getProjectCodeById(projectId); // 2. Get class mapping const mappingsResult = await db.query.tagTypeClassFormMappings.findFirst({ @@ -1728,7 +1670,7 @@ export async function sendFormDataToSEDP( formCode, objectCode, projectCode, - contractItemId // Add contractItemId parameter + packageCode // Add contractItemId parameter ); // 4. Send to SEDP API @@ -1739,11 +1681,12 @@ export async function sendFormDataToSEDP( // Get the current formEntries data const entries = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode), ) ) .limit(1); @@ -1778,17 +1721,17 @@ export async function sendFormDataToSEDP( // Update the database await db - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedDataArray, updatedAt: new Date() }) - .where(eq(formEntries.id, entry.id)); + .where(eq(formEntriesPlant.id, entry.id)); console.log(`Updated status for ${sentTagNumbers.size} tags to "Sent to S-EDP"`); } } else { - console.warn(`No formEntries found for formCode: ${formCode}, contractItemId: ${contractItemId}`); + console.warn(`No formEntriesPlant found for formCode: ${formCode}`); } } catch (statusUpdateError) { // Status 업데이트 실패는 경고로만 처리 (SEDP 전송은 성공했으므로) @@ -1812,12 +1755,14 @@ export async function sendFormDataToSEDP( export async function deleteFormDataByTags({ formCode, - contractItemId, + projectCode, + packageCode, tagIdxs, projectId, }: { formCode: string - contractItemId: number + projectCode: string + packageCode: string tagIdxs: string[] projectId?: number }): Promise<{ @@ -1830,25 +1775,26 @@ export async function deleteFormDataByTags({ }> { try { // 입력 검증 - if (!formCode || !contractItemId || !Array.isArray(tagIdxs) || tagIdxs.length === 0) { + if (!formCode || !projectCode || !Array.isArray(tagIdxs) || tagIdxs.length === 0) { return { error: "Missing required parameters: formCode, contractItemId, tagIdxs", } } - console.log(`[DELETE ACTION] Deleting tags for formCode: ${formCode}, contractItemId: ${contractItemId}, tagIdxs:`, tagIdxs) + console.log(`[DELETE ACTION] Deleting tags for formCode: ${formCode}, projectCode: ${projectCode}, tagIdxs:`, tagIdxs) // 1. 트랜잭션 전에 삭제할 항목들을 미리 조회하여 저장 (S-EDP 전송용) const entryForSedp = await db .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode) ) ) - .orderBy(desc(formEntries.updatedAt)) + .orderBy(desc(formEntriesPlant.updatedAt)) .limit(1) let itemsToSendToSedp: Record<string, unknown>[] = [] @@ -1868,14 +1814,15 @@ export async function deleteFormDataByTags({ // 2-1. 현재 formEntry 데이터 가져오기 const currentEntryResult = await tx .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode) ) ) - .orderBy(desc(formEntries.updatedAt)) + .orderBy(desc(formEntriesPlant.updatedAt)) .limit(1) if (currentEntryResult.length === 0) { @@ -1903,14 +1850,15 @@ export async function deleteFormDataByTags({ // 2-3. tags 테이블에서 해당 태그들 삭제 const deletedTagsResult = await tx - .delete(tags) + .delete(tagsPlant) .where( and( - eq(tags.contractItemId, contractItemId), - inArray(tags.tagIdx, tagIdxs) + eq(tagsPlant.projectCode, projectCode), + eq(tagsPlant.packageCode, packageCode), + inArray(tagsPlant.tagIdx, tagIdxs) ) ) - .returning({ tagNo: tags.tagNo }) + .returning({ tagNo: tagsPlant.tagNo }) const deletedTagsCount = deletedTagsResult.length @@ -1919,15 +1867,16 @@ export async function deleteFormDataByTags({ // 2-4. formEntries 데이터 업데이트 (삭제된 항목 제외) await tx - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedData, updatedAt: new Date(), }) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode), ) ) @@ -2020,7 +1969,8 @@ export async function deleteFormDataByTags({ const sedpResult = await sendFormDataToSEDP( formCode, projectId, - contractItemId, + projectCode, + packageCode, uniqueDeletedItems as GenericData[], formMetaResult.columns as DataTableColumnJSON[] ) @@ -2079,11 +2029,13 @@ export async function deleteFormDataByTags({ */ export async function excludeFormDataByTags({ formCode, - contractItemId, + projectCode, + packageCode, tagNumbers, }: { formCode: string - contractItemId: number + projectCode: string + packageCode: string tagNumbers: string[] }): Promise<{ error?: string @@ -2092,27 +2044,28 @@ export async function excludeFormDataByTags({ }> { try { // 입력 검증 - if (!formCode || !contractItemId || !Array.isArray(tagNumbers) || tagNumbers.length === 0) { + if (!formCode || !projectCode || !Array.isArray(tagNumbers) || tagNumbers.length === 0) { return { - error: "Missing required parameters: formCode, contractItemId, tagNumbers", + error: "Missing required parameters: formCode, projectCode, tagNumbers", } } - console.log(`[EXCLUDE ACTION] Excluding tags for formCode: ${formCode}, contractItemId: ${contractItemId}, tagNumbers:`, tagNumbers) + console.log(`[EXCLUDE ACTION] Excluding tags for formCode: ${formCode}, projectCode: ${projectCode}, tagNumbers:`, tagNumbers) // 트랜잭션으로 안전하게 처리 const result = await db.transaction(async (tx) => { // 1. 현재 formEntry 데이터 가져오기 const currentEntryResult = await tx .select() - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode) ) ) - .orderBy(desc(formEntries.updatedAt)) + .orderBy(desc(formEntriesPlant.updatedAt)) .limit(1) if (currentEntryResult.length === 0) { @@ -2146,15 +2099,16 @@ export async function excludeFormDataByTags({ // 3. formEntries 데이터 업데이트 await tx - .update(formEntries) + .update(formEntriesPlant) .set({ data: updatedData, updatedAt: new Date(), }) .where( and( - eq(formEntries.formCode, formCode), - eq(formEntries.contractItemId, contractItemId) + eq(formEntriesPlant.formCode, formCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.packageCode, packageCode) ) ) @@ -2165,7 +2119,7 @@ export async function excludeFormDataByTags({ }) // 4. 캐시 무효화 - const cacheKey = `form-data-${formCode}-${contractItemId}` + const cacheKey = `form-data-${formCode}-${packageCode}` revalidateTag(cacheKey) console.log(`[EXCLUDE ACTION] Transaction completed successfully`) diff --git a/lib/forms-plant/stat.ts b/lib/forms-plant/stat.ts index f13bab61..f734e782 100644 --- a/lib/forms-plant/stat.ts +++ b/lib/forms-plant/stat.ts @@ -1,7 +1,7 @@ "use server" import db from "@/db/db" -import { vendors, contracts, contractItems, forms, formEntries, formMetas, tags, tagClasses, tagClassAttributes, projects } from "@/db/schema" +import { vendors, contracts, contractItems, forms,formsPlant,formEntriesPlant, formEntries, formMetas, tags,tagsPlant, tagClasses, tagClassAttributes, projects } from "@/db/schema" import { eq, and, inArray } from "drizzle-orm" import { getEditableFieldsByTag } from "./services" import { getServerSession } from "next-auth/next" @@ -218,7 +218,7 @@ export async function getVendorFormStatus(projectId?: number): Promise<VendorFor -export async function getFormStatusByVendor(projectId: number, contractItemId: number, formCode: string): Promise<FormStatusByVendor[]> { +export async function getFormStatusByVendor(projectId: number, projectCode: string, packageCode: string, formCode: string): Promise<FormStatusByVendor[]> { try { const session = await getServerSession(authOptions) if (!session?.user?.id) { @@ -244,15 +244,16 @@ export async function getFormStatusByVendor(projectId: number, contractItemId: n // 4. contractItem별 forms 조회 const formsList = await db .select({ - id: forms.id, - formCode: forms.formCode, - contractItemId: forms.contractItemId + id: formsPlant.id, + formCode: formsPlant.formCode, + contractItemId: formsPlant.contractItemId }) - .from(forms) + .from(formsPlant) .where( and( - eq(forms.contractItemId, contractItemId), - eq(forms.formCode, formCode) + eq(formsPlant.projectCode, projectCode), + eq(formsPlant.packageCode, packageCode), + eq(formsPlant.formCode, formCode) ) ) @@ -261,20 +262,21 @@ export async function getFormStatusByVendor(projectId: number, contractItemId: n // 5. formEntries 조회 const entriesList = await db .select({ - id: formEntries.id, - formCode: formEntries.formCode, - data: formEntries.data + id: formEntriesPlant.id, + formCode: formEntriesPlant.formCode, + data: formEntriesPlant.data }) - .from(formEntries) + .from(formEntriesPlant) .where( and( - eq(formEntries.contractItemId, contractItemId), - eq(formEntries.formCode, formCode) + eq(formEntriesPlant.packageCode, packageCode), + eq(formEntriesPlant.projectCode, projectCode), + eq(formEntriesPlant.formCode, formCode) ) ) // 6. TAG별 편집 가능 필드 조회 - const editableFieldsByTag = await getEditableFieldsByTag(contractItemId, projectId) + const editableFieldsByTag = await getEditableFieldsByTag(projectCode,packageCode, projectId) const vendorStatusList: VendorFormStatus[] = [] |
