diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-22 02:57:00 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-22 02:57:00 +0000 |
| commit | ee57cc221ff2edafd3c0f12a181214c602ed257e (patch) | |
| tree | 148f552f503798f7a350d6eff936b889f16be49f /lib/sedp | |
| parent | 14f61e24947fb92dd71ec0a7196a6e815f8e66da (diff) | |
(대표님, 최겸) 이메일 템플릿, 벤더데이터 변경사항 대응, 기술영업 변경요구사항 구현
Diffstat (limited to 'lib/sedp')
| -rw-r--r-- | lib/sedp/get-form-tags.ts | 124 | ||||
| -rw-r--r-- | lib/sedp/sync-form.ts | 18 |
2 files changed, 84 insertions, 58 deletions
diff --git a/lib/sedp/get-form-tags.ts b/lib/sedp/get-form-tags.ts index d44e11f5..32f4403e 100644 --- a/lib/sedp/get-form-tags.ts +++ b/lib/sedp/get-form-tags.ts @@ -54,7 +54,7 @@ export async function importTagsFromSEDP( processedCount: number; excludedCount: number; totalEntries: number; - formCreated?: boolean; // 새로 추가: form이 생성되었는지 여부 + formCreated?: boolean; errors?: string[]; }> { try { @@ -67,29 +67,10 @@ export async function importTagsFromSEDP( // SEDP API에서 태그 데이터 가져오기 const tagData = await fetchTagDataFromSEDP(projectCode, formCode); - // 데이터 형식 처리 - const tableName = Object.keys(tagData)[0]; - if (!tableName || !tagData[tableName]) { - throw new Error("Invalid tag data format from SEDP API"); - } - - const tagEntries: TagEntry[] = tagData[tableName]; - if (!Array.isArray(tagEntries) || tagEntries.length === 0) { - return { - processedCount: 0, - excludedCount: 0, - totalEntries: 0, - errors: ["No tag entries found in API response"] - }; - } - - // 진행 상황 보고 - if (progressCallback) progressCallback(20); - // 트랜잭션으로 모든 DB 작업 처리 return await db.transaction(async (tx) => { - // 프로젝트 ID 가져오기 - const projectRecord = await tx.select({ id: projects.id }) + // 프로젝트 정보 가져오기 (type 포함) + const projectRecord = await tx.select({ id: projects.id, type: projects.type }) .from(projects) .where(eq(projects.code, projectCode)) .limit(1); @@ -99,7 +80,74 @@ export async function importTagsFromSEDP( } const projectId = projectRecord[0].id; + const projectType = projectRecord[0].type; + + // 프로젝트 타입에 따라 packageCode를 찾을 ATT_ID 결정 + const packageCodeAttId = projectType === "ship" ? "CM3003" : "ME5074"; + + // packageId로 contractItem과 item 정보 가져오기 + const contractItemRecord = await tx.select({ itemId: contractItems.itemId }) + .from(contractItems) + .where(eq(contractItems.id, packageId)) + .limit(1); + + if (!contractItemRecord || contractItemRecord.length === 0) { + throw new Error(`Contract item not found for packageId: ${packageId}`); + } + + const itemRecord = await tx.select({ packageCode: items.packageCode }) + .from(items) + .where(eq(items.id, contractItemRecord[0].itemId)) + .limit(1); + + if (!itemRecord || itemRecord.length === 0) { + throw new Error(`Item not found for itemId: ${contractItemRecord[0].itemId}`); + } + + const targetPackageCode = itemRecord[0].packageCode; + + // 데이터 형식 처리 - tagData의 첫 번째 키 사용 + const tableName = Object.keys(tagData)[0]; + if (!tableName || !tagData[tableName]) { + throw new Error("Invalid tag data format from SEDP API"); + } + + const allTagEntries: TagEntry[] = tagData[tableName]; + + if (!Array.isArray(allTagEntries) || allTagEntries.length === 0) { + return { + processedCount: 0, + excludedCount: 0, + totalEntries: 0, + errors: ["No tag entries found in API response"] + }; + } + + // packageCode로 필터링 - ATTRIBUTES에서 지정된 ATT_ID의 VALUE와 packageCode 비교 + const tagEntries = allTagEntries.filter(entry => { + if (Array.isArray(entry.ATTRIBUTES)) { + const packageCodeAttr = entry.ATTRIBUTES.find(attr => attr.ATT_ID === packageCodeAttId); + if (packageCodeAttr && packageCodeAttr.VALUE === targetPackageCode) { + return true; + } + } + return false; + }); + + if (tagEntries.length === 0) { + return { + processedCount: 0, + excludedCount: 0, + totalEntries: allTagEntries.length, + errors: [`No tag entries found with ${packageCodeAttId} attribute value matching packageCode: ${targetPackageCode}`] + }; + } + + // 진행 상황 보고 + if (progressCallback) progressCallback(20); + + // 나머지 코드는 기존과 동일... // form ID 가져오기 - 없으면 생성 let formRecord = await tx.select({ id: forms.id }) .from(forms) @@ -139,7 +187,7 @@ export async function importTagsFromSEDP( // tagClass 조회 (CLS_ID -> label) let tagClassLabel = firstTag.CLS_ID; // 기본값 if (firstTag.CLS_ID) { - const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) // ✅ 수정 + const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) .from(tagClasses) .where(and( eq(tagClasses.code, firstTag.CLS_ID), @@ -147,8 +195,6 @@ export async function importTagsFromSEDP( )) .limit(1); - - if (tagClassRecord && tagClassRecord.length > 0) { tagClassLabel = tagClassRecord[0].label; } @@ -159,14 +205,11 @@ export async function importTagsFromSEDP( projectId, ); - // ep가 "IMEP"인 것만 필터링 - // const formMappings = allFormMappings?.filter(mapping => mapping.ep === "IMEP") || []; - // 현재 formCode와 일치하는 매핑 찾기 const targetFormMapping = allFormMappings.find(mapping => mapping.formCode === formCode); if (targetFormMapping) { - console.log(`[IMPORT TAGS] Found IMEP form mapping for ${formCode}, creating form...`); + console.log(`[IMPORT TAGS] Found form mapping for ${formCode}, creating form...`); // form 생성 const insertResult = await tx @@ -176,7 +219,7 @@ export async function importTagsFromSEDP( formCode: targetFormMapping.formCode, formName: targetFormMapping.formName, eng: true, // ENG 모드에서 가져오는 것이므로 eng: true - im: targetFormMapping.ep === "IMEP" ? true:false + im: targetFormMapping.ep === "IMEP" ? true : false }) .returning({ id: forms.id }); @@ -185,9 +228,9 @@ export async function importTagsFromSEDP( console.log(`[IMPORT TAGS] Successfully created form:`, insertResult[0]); } else { - console.log(`[IMPORT TAGS] No IMEP form mapping found for formCode: ${formCode}`); - console.log(`[IMPORT TAGS] Available IMEP mappings:`, formMappings.map(m => m.formCode)); - throw new Error(`Form ${formCode} not found and no IMEP mapping available for tag type ${tagTypeDescription}`); + console.log(`[IMPORT TAGS] No form mapping found for formCode: ${formCode}`); + console.log(`[IMPORT TAGS] Available mappings:`, allFormMappings.map(m => m.formCode)); + throw new Error(`Form ${formCode} not found and no mapping available for tag type ${tagTypeDescription}`); } } else { throw new Error(`Form not found for formCode: ${formCode} and contractItemId: ${packageId}, and no tags to derive form mapping`); @@ -232,7 +275,7 @@ export async function importTagsFromSEDP( // tagClass 조회 let tagClassLabel = firstTag.CLS_ID; if (firstTag.CLS_ID) { - const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) // ✅ 수정 + const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) .from(tagClasses) .where(and( eq(tagClasses.code, firstTag.CLS_ID), @@ -250,9 +293,6 @@ export async function importTagsFromSEDP( projectId, ); - // ep가 "IMEP"인 것만 필터링 - // const formMappings = allFormMappings?.filter(mapping => mapping.ep === "IMEP") || []; - // 현재 formCode와 일치하는 매핑 찾기 const targetFormMapping = allFormMappings.find(mapping => mapping.formCode === formCode); @@ -292,6 +332,9 @@ export async function importTagsFromSEDP( const formId = formRecord[0].id; + // 나머지 처리 로직은 기존과 동일... + // (양식 메타데이터 가져오기, 태그 처리 등) + // 양식 메타데이터 가져오기 const formMetaRecord = await tx.select({ columns: formMetas.columns }) .from(formMetas) @@ -388,7 +431,7 @@ export async function importTagsFromSEDP( let tagClassLabel = tagEntry.CLS_ID; // 기본값 let tagClassId = null; // 기본값 if (tagEntry.CLS_ID) { - const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) // ✅ 수정 + const tagClassRecord = await tx.select({ id: tagClasses.id, label: tagClasses.label }) .from(tagClasses) .where(and( eq(tagClasses.code, tagEntry.CLS_ID), @@ -414,7 +457,7 @@ export async function importTagsFromSEDP( contractItemId: packageId, formId: formId, tagNo: tagEntry.TAG_NO, - tagType: tagTypeDescription, + tagType: tagTypeDescription || "", class: tagClassLabel, tagClassId: tagClassId, description: tagEntry.TAG_DESC || null, @@ -644,7 +687,7 @@ export async function importTagsFromSEDP( processedCount, excludedCount, totalEntries: tagEntries.length, - formCreated, // 새로 추가: form이 생성되었는지 여부 + formCreated, errors: errors.length > 0 ? errors : undefined }; }); @@ -654,7 +697,6 @@ export async function importTagsFromSEDP( throw error; } } - /** * SEDP API에서 태그 데이터 가져오기 * diff --git a/lib/sedp/sync-form.ts b/lib/sedp/sync-form.ts index c3c88f07..f9e63caf 100644 --- a/lib/sedp/sync-form.ts +++ b/lib/sedp/sync-form.ts @@ -430,23 +430,7 @@ async function getRegisters(projectCode: string): Promise<Register[]> { } // 결과를 배열로 변환 (단일 객체인 경우 배열로 래핑) - let registers: Register[] = Array.isArray(data) ? data : [data]; - - // MAP_CLS_ID가 비어있지 않고 REMARK가 vd, VD, vD, Vd 중 하나인 레지스터만 필터링 - registers = registers.filter(register => { - // 삭제된 레지스터 제외 - if (register.DELETED) return false; - - // MAP_CLS_ID 배열이 존재하고 요소가 하나 이상 있는지 확인 - const hasValidMapClsId = Array.isArray(register.MAP_CLS_ID) && register.MAP_CLS_ID.length > 0; - - // REMARK가 'vd_' 또는 'vd' 포함 확인 (대소문자 구분 없이) - const remarkLower = register.REMARK && register.REMARK.toLowerCase(); - const hasValidRemark = remarkLower && (remarkLower.includes('vd')); - - // 두 조건 모두 충족해야 함 - return hasValidMapClsId && hasValidRemark; - }); + const registers: Register[] = Array.isArray(data) ? data : [data]; console.log(`프로젝트 ${projectCode}에서 ${registers.length}개의 유효한 레지스터를 가져왔습니다.`); return registers; |
