summaryrefslogtreecommitdiff
path: root/lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts')
-rw-r--r--lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts b/lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts
new file mode 100644
index 00000000..903a164c
--- /dev/null
+++ b/lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts
@@ -0,0 +1,143 @@
+import { oracleKnex } from '@/lib/oracle-db/db';
+import db from '@/db/db';
+import { users } from '@/db/schema/users';
+import { eq } from 'drizzle-orm';
+
+/**
+ * 오라클 NonSAP 데이터베이스에서 구매그룹 정보 조회
+ * CMCTB_CD 테이블에서 CD_CLF='MMA070' 조건으로 구매그룹 데이터를 가져옴
+ */
+async function fetchPurchasingGroupsFromOracle(): Promise<Array<{ code: string; employeeNumber: string }>> {
+ try {
+ console.log('🔍 오라클에서 구매그룹 데이터 조회 시작...');
+
+ const result = await oracleKnex
+ .select('CD as code', 'USR_DF_CHAR_9 as employeeNumber')
+ .from('CMCTB_CD')
+ .where('CD_CLF', 'MMA070')
+ .whereNotNull('USR_DF_CHAR_9')
+
+ console.log(`✅ 구매그룹 데이터 ${result.length}건 조회 완료`);
+ return result;
+ } catch (error) {
+ console.error('❌ 오라클에서 구매그룹 데이터 조회 중 오류:', error);
+ throw error;
+ }
+}
+
+/**
+ * employeeNumber 기준으로 users 테이블에 사용자 코드 upsert
+ */
+async function updateUsersCode(purchasingGroups: Array<{ code: string; employeeNumber: string }>) {
+ try {
+ console.log('🔄 사용자 테이블 사용자 코드 업데이트 시작...');
+
+ let updateCount = 0;
+ let notFoundCount = 0;
+ const errors: Array<{ employeeNumber: string; error: string }> = [];
+
+ // 개별 트랜잭션으로 안전하게 처리
+ for (const group of purchasingGroups) {
+ try {
+ await db.transaction(async (tx) => {
+ const result = await tx
+ .update(users)
+ .set({
+ userCode: group.code,
+ updatedAt: new Date()
+ })
+ .where(eq(users.employeeNumber, group.employeeNumber))
+ .returning({ id: users.id });
+
+ if (result.length > 0) {
+ updateCount++;
+ } else {
+ notFoundCount++;
+ console.warn(`⚠️ 사번 ${group.employeeNumber}에 해당하는 사용자를 찾을 수 없음 (사용자 코드: ${group.code})`);
+ }
+ });
+ } catch (error) {
+ errors.push({
+ employeeNumber: group.employeeNumber,
+ error: error instanceof Error ? error.message : '알 수 없는 오류'
+ });
+ console.error(`❌ 사번 ${group.employeeNumber} 업데이트 중 오류:`, error);
+ }
+ }
+
+ // 에러가 있었다면 로그 출력
+ if (errors.length > 0) {
+ console.error(`❌ ${errors.length}건의 업데이트 오류 발생:`);
+ errors.forEach(({ employeeNumber, error }) => {
+ console.error(` - 사번 ${employeeNumber}: ${error}`);
+ });
+ }
+
+ console.log(`✅ 사용자 코드 업데이트 완료: 성공 ${updateCount}건, 미발견 ${notFoundCount}건`);
+ return { updateCount, notFoundCount };
+ } catch (error) {
+ console.error('❌ 사용자 테이블 업데이트 중 오류:', error);
+ throw error;
+ }
+}
+
+/**
+ * 사용자 코드 동기화 메인 함수
+ * 오라클에서 구매그룹 데이터를 조회하여 users 테이블을 업데이트
+ */
+export async function syncUserCodes(): Promise<{ success: boolean; updateCount: number; notFoundCount: number; error?: string }> {
+ try {
+ console.log('🚀 사용자 코드 동기화 작업 시작...');
+ const startTime = Date.now();
+
+ // 1. 오라클에서 구매그룹 데이터 조회
+ const purchasingGroups = await fetchPurchasingGroupsFromOracle();
+
+ if (purchasingGroups.length === 0) {
+ console.log('⚠️ 조회된 구매그룹 데이터가 없습니다.');
+ return { success: true, updateCount: 0, notFoundCount: 0 };
+ }
+
+ // 2. users 테이블 업데이트
+ const { updateCount, notFoundCount } = await updateUsersCode(purchasingGroups);
+
+ const endTime = Date.now();
+ const duration = endTime - startTime;
+
+ console.log(`🎉 사용자 코드 동기화 완료! 소요시간: ${duration}ms`);
+ console.log(`📊 처리 결과: 총 ${purchasingGroups.length}건 중 업데이트 ${updateCount}건, 미발견 ${notFoundCount}건`);
+
+ return {
+ success: true,
+ updateCount,
+ notFoundCount
+ };
+ } catch (error) {
+ console.error('💥 사용자 코드 동기화 작업 중 오류:', error);
+ return {
+ success: false,
+ updateCount: 0,
+ notFoundCount: 0,
+ error: error instanceof Error ? error.message : '알 수 없는 오류'
+ };
+ }
+}
+
+/**
+ * 특정 사번의 사용자 코드를 조회하는 함수 (개별 조회용)
+ */
+export async function getUserCodeByEmployeeNumber(employeeNumber: string): Promise<string | null> {
+ try {
+ const result = await oracleKnex
+ .select('CD')
+ .from('CMCTB_CD')
+ .where('CD_CLF', 'MMA070')
+ .andWhere('USR_DF_CHAR_9', employeeNumber)
+ .limit(1);
+
+ return result.length > 0 ? result[0].CD : null;
+ } catch (error) {
+ console.error(`사용자 코드 조회 중 오류 (사번: ${employeeNumber}):`, error);
+ return null;
+ }
+}