summaryrefslogtreecommitdiff
path: root/lib/soap
diff options
context:
space:
mode:
Diffstat (limited to 'lib/soap')
-rw-r--r--lib/soap/ecc/mapper/bidding-and-pr-mapper.ts6
-rw-r--r--lib/soap/ecc/mapper/common-mapper-utils.ts35
-rw-r--r--lib/soap/ecc/mapper/rfq-and-pr-mapper.ts33
3 files changed, 61 insertions, 13 deletions
diff --git a/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts b/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts
index 4ab9a745..adbb3e1e 100644
--- a/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts
+++ b/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts
@@ -29,6 +29,7 @@ import {
findMaterialNameByMATNR,
parseSAPDateTime,
parseSAPDateToString,
+ findSpecificationByMATNR,
} from './common-mapper-utils';
// Note: POS 파일은 온디맨드 방식으로 다운로드됩니다.
// 자동 동기화 관련 import는 제거되었습니다.
@@ -267,6 +268,9 @@ export async function mapECCBiddingItemToPrItemForBidding(
// PSPID(Project Code)로 프로젝트 ID 조회
const projectId = await findProjectIdByPSPID(eccItem.PSPID || null);
+ // Specification 조회 (MATNR 기반)
+ const specification = await findSpecificationByMATNR(eccItem.MATNR || null);
+
const mappedData: PrItemForBiddingData = {
biddingId, // 부모 Bidding ID
itemNumber: eccItem.ANFPS || null, // 아이템 번호
@@ -305,12 +309,14 @@ export async function mapECCBiddingItemToPrItemForBidding(
prNumber: eccItem.BANFN || null, // PR번호
hasSpecDocument: false, // 기본값 false
+ specification, // MATNR로 조회한 Specification
};
debugSuccess('ECC Bidding 아이템 매핑 완료', {
itemNumber: eccItem.ANFPS,
prNumber: eccItem.BANFN,
projectId,
+ specification,
});
return mappedData;
}
diff --git a/lib/soap/ecc/mapper/common-mapper-utils.ts b/lib/soap/ecc/mapper/common-mapper-utils.ts
index ed655e0e..9141a29f 100644
--- a/lib/soap/ecc/mapper/common-mapper-utils.ts
+++ b/lib/soap/ecc/mapper/common-mapper-utils.ts
@@ -14,7 +14,7 @@ import { debugLog, debugSuccess, debugError } from '@/lib/debug-utils';
import db from '@/db/db';
import { users, vendors } from '@/db/schema';
import { projects } from '@/db/schema/projects';
-import { EQUP_MASTER_MATL_CHARASGN } from '@/db/schema/MDG/mdg';
+import { EQUP_MASTER_MATL_CHARASGN, MATERIAL_MASTER_PART_MATL } from '@/db/schema/MDG/mdg';
import { eq } from 'drizzle-orm';
import { oracleKnex } from '@/lib/oracle-db/db';
@@ -386,4 +386,37 @@ export async function findVendorIdByLIFNR(lifnr: string | null | undefined): Pro
debugError('Vendor 조회 중 오류 발생', { lifnr, error });
return null;
}
+}
+
+/**
+ * Specification 조회 함수 (MATNR 기반)
+ * MATNR을 기반으로 MATERIAL_MASTER_PART_MATL 테이블에서 ZZSPEC 조회
+ */
+export async function findSpecificationByMATNR(MATNR: string | null): Promise<string | null> {
+ try {
+ debugLog('Specification 조회 시작', { MATNR });
+
+ if (!MATNR) {
+ debugError('MATNR이 null 또는 undefined', { MATNR });
+ return null;
+ }
+
+ const specResult = await db
+ .select({ ZZSPEC: MATERIAL_MASTER_PART_MATL.ZZSPEC })
+ .from(MATERIAL_MASTER_PART_MATL)
+ .where(eq(MATERIAL_MASTER_PART_MATL.MATNR, MATNR))
+ .limit(1);
+
+ if (specResult.length === 0) {
+ debugLog('MATNR에 해당하는 Specification을 찾을 수 없음', { MATNR });
+ return null;
+ }
+
+ const specification = specResult[0].ZZSPEC;
+ debugSuccess('Specification 조회 완료', { MATNR, specification });
+ return specification;
+ } catch (error) {
+ debugError('Specification 조회 중 오류 발생', { MATNR, error });
+ return null;
+ }
} \ No newline at end of file
diff --git a/lib/soap/ecc/mapper/rfq-and-pr-mapper.ts b/lib/soap/ecc/mapper/rfq-and-pr-mapper.ts
index d08bc5fb..c0557d0c 100644
--- a/lib/soap/ecc/mapper/rfq-and-pr-mapper.ts
+++ b/lib/soap/ecc/mapper/rfq-and-pr-mapper.ts
@@ -25,6 +25,7 @@ import {
findProjectInfoByPSPID,
parseSAPDateTime,
findUserInfoByPERNR,
+ findSpecificationByMATNR,
} from './common-mapper-utils';
// ECC 데이터 타입 정의
@@ -241,11 +242,11 @@ export async function mapECCRfqHeaderToRfqLast(
/**
* ECC RFQ 아이템 데이터를 rfqPrItems 테이블로 매핑
*/
-export function mapECCRfqItemToRfqPrItem(
+export async function mapECCRfqItemToRfqPrItem(
eccItem: ECCBidItem,
rfqId: number,
isMajor: boolean = false
-): RfqPrItemData {
+): Promise<RfqPrItemData> {
debugLog('ECC RFQ 아이템 매핑 시작', {
anfnr: eccItem.ANFNR,
anfps: eccItem.ANFPS,
@@ -269,6 +270,9 @@ export function mapECCRfqItemToRfqPrItem(
}
}
+ // Specification 조회 (MATNR 기반)
+ const specification = await findSpecificationByMATNR(eccItem.MATNR || null);
+
const mappedData: RfqPrItemData = {
rfqsLastId: rfqId, // 부모 RFQ ID
rfqItem: eccItem.ANFPS || null, // RFQ Item 번호
@@ -286,6 +290,7 @@ export function mapECCRfqItemToRfqPrItem(
gwUom: eccItem.GEWEI || null, // 중량단위
specNo: null, // ECC에서 제공되지 않음
specUrl: null, // ECC에서 제공되지 않음
+ specification, // MATNR로 조회한 Specification
trackingNo: null, // ECC에서 제공되지 않음
majorYn: isMajor, // ZCON_NO_PO와 BANFN이 같은 경우 true
projectDef: eccItem.PSPID || null, // 프로젝트 정의
@@ -299,6 +304,7 @@ export function mapECCRfqItemToRfqPrItem(
debugSuccess('ECC RFQ 아이템 매핑 완료', {
rfqItem: eccItem.ANFPS,
materialCode: eccItem.MATNR,
+ specification,
});
return mappedData;
}
@@ -363,7 +369,7 @@ export async function mapAndSaveECCRfqDataToRfqLast(
// 4) 모든 새로 삽입된 레코드의 ID 매핑은 이미 완료됨
- // 5) 모든 아이템을 한 번에 생성할 데이터로 변환
+ // 5) 모든 아이템을 한 번에 생성할 데이터로 변환 (async 함수로 병렬 처리)
const allItemsToInsert: RfqPrItemData[] = [];
for (const group of rfqGroups) {
const rfqCode = group.rfqCode;
@@ -374,15 +380,18 @@ export async function mapAndSaveECCRfqDataToRfqLast(
throw new Error(`RFQ ID를 찾을 수 없습니다: ${rfqCode}`);
}
- for (const eccItem of group.relatedItems) {
- // ZCON_NO_PO와 BANFN이 같은 경우 majorYn을 true로 설정
- const isMajor: boolean = !!(eccItem.ZCON_NO_PO &&
- eccItem.ZCON_NO_PO.trim() &&
- eccItem.BANFN === eccItem.ZCON_NO_PO.trim());
-
- const itemData = mapECCRfqItemToRfqPrItem(eccItem, rfqId, isMajor);
- allItemsToInsert.push(itemData);
- }
+ // 각 아이템을 병렬로 매핑 (async 함수로 변경되었으므로)
+ const itemsData = await Promise.all(
+ group.relatedItems.map(async eccItem => {
+ // ZCON_NO_PO와 BANFN이 같은 경우 majorYn을 true로 설정
+ const isMajor: boolean = !!(eccItem.ZCON_NO_PO &&
+ eccItem.ZCON_NO_PO.trim() &&
+ eccItem.BANFN === eccItem.ZCON_NO_PO.trim());
+
+ return await mapECCRfqItemToRfqPrItem(eccItem, rfqId, isMajor);
+ })
+ );
+ allItemsToInsert.push(...itemsData);
}
// 5) 아이템 일괄 삽입 (chunk 처리로 파라미터 제한 회피)