1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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;
}
}
|