summaryrefslogtreecommitdiff
path: root/lib/sedp
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-11 09:02:00 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-11 09:02:00 +0000
commitcbb4c7fe0b94459162ad5e998bc05cd293e0ff96 (patch)
tree0a26712f7685e4f6511e637b9a81269d90a47c8f /lib/sedp
parenteb654f88214095f71be142b989e620fd28db3f69 (diff)
(대표님) 입찰, EDP 변경사항 대응, spreadJS 오류 수정, 벤더실사 수정
Diffstat (limited to 'lib/sedp')
-rw-r--r--lib/sedp/get-form-tags.ts41
-rw-r--r--lib/sedp/get-tags.ts55
-rw-r--r--lib/sedp/sync-form.ts61
3 files changed, 110 insertions, 47 deletions
diff --git a/lib/sedp/get-form-tags.ts b/lib/sedp/get-form-tags.ts
index 5b1c500d..821fa372 100644
--- a/lib/sedp/get-form-tags.ts
+++ b/lib/sedp/get-form-tags.ts
@@ -26,7 +26,9 @@ interface Attribute {
}
interface TagEntry {
+ TAG_IDX: string;
TAG_NO: string;
+ BF_TAG_NO: string;
TAG_DESC: string;
EP_ID: string;
TAG_TYPE_ID: string;
@@ -389,8 +391,8 @@ export async function importTagsFromSEDP(
existingEntries.forEach(entry => {
const data = entry.data as any[];
data.forEach(item => {
- if (item.TAG_NO) {
- existingTagMap.set(item.TAG_NO, {
+ if (item.TAG_IDX) {
+ existingTagMap.set(item.TAG_IDX, {
entryId: entry.id,
data: item
});
@@ -399,7 +401,7 @@ export async function importTagsFromSEDP(
});
existingTags.forEach(tag => {
- existingTagsMap.set(tag.tagNo, tag);
+ existingTagsMap.set(tag.tagIdx, tag);
});
// 진행 상황 보고
@@ -417,7 +419,7 @@ export async function importTagsFromSEDP(
// SEDP 태그 데이터 처리
for (const tagEntry of tagEntries) {
try {
- if (!tagEntry.TAG_NO) {
+ if (!tagEntry.TAG_IDX) {
excludedCount++;
errors.push(`Missing TAG_NO in tag entry`);
continue;
@@ -459,6 +461,7 @@ export async function importTagsFromSEDP(
// 기본 태그 데이터 객체 생성 (formEntries용)
const tagObject: any = {
+ TAG_IDX: tagEntry.TAG_IDX, // SEDP 고유 식별자
TAG_NO: tagEntry.TAG_NO,
TAG_DESC: tagEntry.TAG_DESC || "",
VNDRCD:vendorRecord[0].vendorCode,
@@ -470,6 +473,7 @@ export async function importTagsFromSEDP(
const tagRecord = {
contractItemId: packageId,
formId: formId,
+ tagIdx: tagEntry.TAG_IDX, // SEDP 고유 식별자
tagNo: tagEntry.TAG_NO,
tagType: tagTypeDescription || "",
class: tagClassLabel,
@@ -508,7 +512,7 @@ export async function importTagsFromSEDP(
}
// 기존 태그가 있는지 확인하고 처리
- const existingTag = existingTagMap.get(tagEntry.TAG_NO);
+ const existingTag = existingTagMap.get(tagEntry.TAG_IDX);
if (existingTag) {
// 기존 태그가 있으면 formEntries 업데이트 데이터 준비
@@ -516,7 +520,14 @@ export async function importTagsFromSEDP(
let hasUpdates = false;
for (const key of Object.keys(tagObject)) {
- if (key === "TAG_NO") continue;
+ if (key === "TAG_IDX") continue;
+
+ if (key === "TAG_NO" && tagObject[key] !== existingTag.data[key]) {
+ updates[key] = tagObject[key];
+ hasUpdates = true;
+ continue;
+ }
+
if (key === "TAG_DESC" && tagObject[key] !== existingTag.data[key]) {
updates[key] = tagObject[key];
@@ -542,7 +553,7 @@ export async function importTagsFromSEDP(
if (hasUpdates) {
updateData.push({
entryId: existingTag.entryId,
- tagNo: tagEntry.TAG_NO,
+ tagIdx: tagEntry.TAG_IDX, // TAG_IDX로 변경
updates
});
}
@@ -557,7 +568,7 @@ export async function importTagsFromSEDP(
processedCount++;
} catch (error) {
excludedCount++;
- errors.push(`Error processing tag ${tagEntry.TAG_NO || 'unknown'}: ${error}`);
+ errors.push(`Error processing tag ${tagEntry.TAG_IDX || 'unknown'}: ${error}`);
}
}
@@ -572,7 +583,7 @@ export async function importTagsFromSEDP(
const data = entry.data as any[];
const updatedData = data.map(item => {
- if (item.TAG_NO === update.tagNo) {
+ if (item.TAG_IDX === update.tagIdx) {
return { ...item, ...update.updates };
}
return item;
@@ -627,6 +638,12 @@ export async function importTagsFromSEDP(
// 기존 태그가 있으면 업데이트 준비
const tagUpdates: any = {};
let hasTagUpdates = false;
+
+ // tagNo도 업데이트 가능 (편집된 경우)
+ if (existingTagRecord.tagNo !== tagRecord.tagNo) {
+ tagUpdates.tagNo = tagRecord.tagNo;
+ hasTagUpdates = true;
+ }
if (existingTagRecord.tagType !== tagRecord.tagType) {
tagUpdates.tagType = tagRecord.tagType;
@@ -663,7 +680,7 @@ export async function importTagsFromSEDP(
await tx.insert(tags)
.values(newTagRecords)
.onConflictDoNothing({
- target: [tags.contractItemId, tags.tagNo]
+ target: [tags.contractItemId, tags.tagIdx]
});
} catch (error) {
// 개별 삽입으로 재시도
@@ -672,10 +689,10 @@ export async function importTagsFromSEDP(
await tx.insert(tags)
.values(tagRecord)
.onConflictDoNothing({
- target: [tags.contractItemId, tags.tagNo]
+ target: [tags.contractItemId, tags.tagIdx]
});
} catch (individualError) {
- errors.push(`Error inserting tag ${tagRecord.tagNo}: ${individualError}`);
+ errors.push(`Error inserting tag ${tagRecord.tagIdx}: ${individualError}`);
}
}
}
diff --git a/lib/sedp/get-tags.ts b/lib/sedp/get-tags.ts
index cb549d8c..ff742299 100644
--- a/lib/sedp/get-tags.ts
+++ b/lib/sedp/get-tags.ts
@@ -18,6 +18,7 @@ import { getSEDPToken } from "./sedp-token";
/**
* 태그 가져오기 서비스 함수
* contractItemId(packageId)를 기반으로 외부 시스템에서 태그 데이터를 가져와 DB에 저장
+ * TAG_IDX를 기준으로 태그를 식별합니다.
*
* @param packageId 계약 아이템 ID (contractItemId)
* @param progressCallback 진행 상황을 보고하기 위한 콜백 함수
@@ -321,7 +322,8 @@ export async function importTagsFromSEDP(
// formEntries를 위한 데이터 수집
const newTagsForFormEntry: Array<{
- TAG_NO: string;
+ TAG_IDX: string; // 변경: TAG_NO → TAG_IDX
+ TAG_NO?: string; // TAG_NO도 함께 저장 (편집 가능한 필드)
TAG_DESC: string | null;
status: string;
[key: string]: any;
@@ -332,6 +334,21 @@ export async function importTagsFromSEDP(
try {
const entry = tagEntries[i];
+ // TAG_IDX가 없는 경우 제외 (변경: TAG_NO → TAG_IDX 체크)
+ if (!entry.TAG_IDX) {
+ excludedCount++;
+ totalExcludedCount++;
+
+ // 주기적으로 진행 상황 보고 (건너뛰어도 진행률은 업데이트)
+ if (progressCallback && (i % 10 === 0 || i === tagEntries.length - 1)) {
+ const baseProgress = 60;
+ const entryProgress = Math.floor(30 * ((mappingIndex * entriesCount + i) / (mappings.length * entriesCount)));
+ progressCallback(baseProgress + entryProgress);
+ }
+
+ continue; // 이 항목은 건너뜀
+ }
+
// TAG_TYPE_ID가 null이거나 빈 문자열인 경우 제외
if (entry.TAG_TYPE_ID === null || entry.TAG_TYPE_ID === "") {
excludedCount++;
@@ -363,19 +380,21 @@ export async function importTagsFromSEDP(
)
});
- // Insert or update the tag
+ // Insert or update the tag - tagIdx 필드 추가
await db.insert(tags).values({
contractItemId: packageId,
formId: formId,
- tagNo: entry.TAG_NO,
+ tagIdx: entry.TAG_IDX, // 추가: SEDP 고유 식별자
+ tagNo: entry.TAG_NO || entry.TAG_IDX, // TAG_NO가 없으면 TAG_IDX 사용
tagType: tagType?.description || entry.TAG_TYPE_ID,
tagClassId: tagClass?.id,
class: tagClass?.label || entry.CLS_ID,
description: entry.TAG_DESC
}).onConflictDoUpdate({
- target: [tags.contractItemId, tags.tagNo],
+ target: [tags.contractItemId, tags.tagIdx], // 변경: tagNo → tagIdx
set: {
formId: formId,
+ tagNo: entry.TAG_NO || entry.TAG_IDX, // tagNo도 업데이트 가능
tagType: tagType?.description || entry.TAG_TYPE_ID,
class: tagClass?.label || entry.CLS_ID,
description: entry.TAG_DESC,
@@ -385,9 +404,10 @@ export async function importTagsFromSEDP(
// formEntries용 데이터 수집
const tagDataForFormEntry = {
- TAG_NO: entry.TAG_NO,
+ TAG_IDX: entry.TAG_IDX, // 변경: TAG_NO → TAG_IDX
+ TAG_NO: entry.TAG_NO || entry.TAG_IDX, // TAG_NO도 함께 저장
TAG_DESC: entry.TAG_DESC || null,
- status:"From S-EDP" // SEDP에서 가져온 데이터임을 표시
+ status: "From S-EDP" // SEDP에서 가져온 데이터임을 표시
};
// ATTRIBUTES가 있으면 추가 (SHI 필드들)
@@ -416,7 +436,7 @@ export async function importTagsFromSEDP(
}
}
- // Step 7: formEntries 업데이트
+ // Step 7: formEntries 업데이트 - TAG_IDX 기준으로 변경
if (newTagsForFormEntry.length > 0) {
try {
// 기존 formEntry 가져오기
@@ -430,7 +450,8 @@ export async function importTagsFromSEDP(
if (existingEntry && existingEntry.id) {
// 기존 formEntry가 있는 경우
let existingData: Array<{
- TAG_NO: string;
+ TAG_IDX?: string; // 추가: TAG_IDX 필드
+ TAG_NO?: string;
TAG_DESC?: string;
status?: string;
[key: string]: any;
@@ -440,18 +461,22 @@ export async function importTagsFromSEDP(
existingData = existingEntry.data;
}
- // 기존 TAG_NO들 추출
- const existingTagNos = new Set(existingData.map(item => item.TAG_NO));
+ // 기존 TAG_IDX들 추출 (변경: TAG_NO → TAG_IDX)
+ const existingTagIdxs = new Set(
+ existingData
+ .map(item => item.TAG_IDX)
+ .filter(tagIdx => tagIdx !== undefined && tagIdx !== null)
+ );
- // 중복되지 않은 새 태그들만 필터링
+ // 중복되지 않은 새 태그들만 필터링 (변경: TAG_NO → TAG_IDX)
const newUniqueTagsData = newTagsForFormEntry.filter(
- tagData => !existingTagNos.has(tagData.TAG_NO)
+ tagData => !existingTagIdxs.has(tagData.TAG_IDX)
);
- // 기존 태그들의 status와 ATTRIBUTES 업데이트
+ // 기존 태그들의 status와 ATTRIBUTES 업데이트 (변경: TAG_NO → TAG_IDX)
const updatedExistingData = existingData.map(existingItem => {
const newTagData = newTagsForFormEntry.find(
- newItem => newItem.TAG_NO === existingItem.TAG_NO
+ newItem => newItem.TAG_IDX === existingItem.TAG_IDX
);
if (newTagData) {
@@ -459,7 +484,7 @@ export async function importTagsFromSEDP(
return {
...existingItem,
...newTagData,
- TAG_NO: existingItem.TAG_NO // TAG_NO는 유지
+ TAG_IDX: existingItem.TAG_IDX // TAG_IDX는 유지
};
}
diff --git a/lib/sedp/sync-form.ts b/lib/sedp/sync-form.ts
index 559c09a2..6ae2e675 100644
--- a/lib/sedp/sync-form.ts
+++ b/lib/sedp/sync-form.ts
@@ -129,6 +129,7 @@ interface newRegister {
REG_TYPE_ID: string;
TOOL_ID: string;
TOOL_TYPE: string;
+ SCOPES: string[];
MAP_CLS: {
TOOL_ATT_NAME: string;
ITEMS: ClassItmes[];
@@ -933,10 +934,15 @@ export async function saveFormMappingsAndMetas(
const defaultAttributes = await getDefaulTAttributes();
/* ------------------------------------------------------------------ */
- /* 2. Contract‑item look‑up (TOOL_TYPE) - 수정된 부분 */
+ /* 2. Contract‑item look‑up (SCOPES) - 수정된 부분 */
/* ------------------------------------------------------------------ */
- const uniqueItemCodes = [...new Set(newRegisters.filter(nr => nr.TOOL_TYPE).map(nr => nr.TOOL_TYPE as string))];
- const itemCodeToContractItemIds = await getContractItemsByItemCodes(uniqueItemCodes, projectId, projectCode);
+ // SCOPES 배열에서 모든 unique한 itemCode들을 추출
+ const uniqueItemCodes = [...new Set(
+ newRegisters
+ .filter(nr => nr.SCOPES && nr.SCOPES.length > 0)
+ .flatMap(nr => nr.SCOPES as string[])
+ )];
+ const itemCodeToContractItemIds = await getContractItemsByItemCodes(uniqueItemCodes, projectId);
/* ------------------------------------------------------------------ */
/* 3. Buffers for bulk insert */
@@ -1019,27 +1025,42 @@ export async function saveFormMappingsAndMetas(
if (!cls) { console.warn(`클래스 ${classId} 없음`); return; }
const tp = tagTypeMap.get(cls.tagTypeCode);
if (!tp) { console.warn(`태그 타입 ${cls.tagTypeCode} 없음`); return; }
- mappingsToSave.push({ projectId, tagTypeLabel: tp.description, classLabel: cls.label, formCode, formName: legacy?.DESC || formCode, remark: newReg.TOOL_TYPE || null, ep: newReg.EP_ID || legacy?.EP_ID || "", createdAt: new Date(), updatedAt: new Date() });
+ // SCOPES 배열을 문자열로 변환하여 remark에 저장
+ const scopesRemark = newReg.SCOPES && newReg.SCOPES.length > 0 ? newReg.SCOPES.join(', ') : null;
+ mappingsToSave.push({
+ projectId,
+ tagTypeLabel: tp.description,
+ classLabel: cls.label,
+ formCode,
+ formName: legacy?.DESC || formCode,
+ remark: scopesRemark,
+ ep: newReg.EP_ID || legacy?.EP_ID || "",
+ createdAt: new Date(),
+ updatedAt: new Date()
+ });
});
/* ---------- 4‑d. contractItem ↔ form - 수정된 부분 -------------- */
- if (newReg.TOOL_TYPE) {
- const contractItemIds = itemCodeToContractItemIds.get(newReg.TOOL_TYPE);
- if (contractItemIds && contractItemIds.length > 0) {
- // 모든 contractItemId에 대해 form 생성
- contractItemIds.forEach(cId => {
- contractItemIdsWithForms.add(cId);
- formsToSave.push({
- contractItemId: cId,
- formCode,
- formName: legacy?.DESC || formCode,
- eng: true,
- createdAt: new Date(),
- updatedAt: new Date()
+ if (newReg.SCOPES && newReg.SCOPES.length > 0) {
+ // SCOPES 배열의 각 itemCode에 대해 처리
+ for (const itemCode of newReg.SCOPES) {
+ const contractItemIds = itemCodeToContractItemIds.get(itemCode);
+ if (contractItemIds && contractItemIds.length > 0) {
+ // 모든 contractItemId에 대해 form 생성
+ contractItemIds.forEach(cId => {
+ contractItemIdsWithForms.add(cId);
+ formsToSave.push({
+ contractItemId: cId,
+ formCode,
+ formName: legacy?.DESC || formCode,
+ eng: true,
+ createdAt: new Date(),
+ updatedAt: new Date()
+ });
});
- });
- } else {
- console.warn(`itemCode ${newReg.TOOL_TYPE} 의 contractItemId 없음`);
+ } else {
+ console.warn(`itemCode ${itemCode} 의 contractItemId 없음`);
+ }
}
}
}