summaryrefslogtreecommitdiff
path: root/components/common/selectors/purchase-group-code/purchase-group-code-service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'components/common/selectors/purchase-group-code/purchase-group-code-service.ts')
-rw-r--r--components/common/selectors/purchase-group-code/purchase-group-code-service.ts147
1 files changed, 147 insertions, 0 deletions
diff --git a/components/common/selectors/purchase-group-code/purchase-group-code-service.ts b/components/common/selectors/purchase-group-code/purchase-group-code-service.ts
new file mode 100644
index 00000000..191c9f85
--- /dev/null
+++ b/components/common/selectors/purchase-group-code/purchase-group-code-service.ts
@@ -0,0 +1,147 @@
+"use server"
+
+import { oracleKnex } from '@/lib/oracle-db/db'
+import { getUserByEmployeeNumber } from '@/lib/users/service'
+
+// 구매그룹코드 타입 정의
+export interface PurchaseGroupCode {
+ PURCHASE_GROUP_CODE: string // 구매그룹코드
+ DISPLAY_NAME: string // 표시명 (이름_부서_퇴직/전배정보)
+ EMPLOYEE_NUMBER: string // 사번
+}
+
+// 구매그룹코드 + 사용자 정보 타입
+export interface PurchaseGroupCodeWithUser extends PurchaseGroupCode {
+ user?: {
+ id: number
+ name: string
+ email: string
+ employeeNumber: string | null
+ // 필요한 다른 사용자 필드들...
+ } | null
+}
+
+// 테스트 환경용 폴백 데이터
+const FALLBACK_TEST_DATA: PurchaseGroupCode[] = [
+ { PURCHASE_GROUP_CODE: '12L', DISPLAY_NAME: '김철수_구매팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1001234' },
+ { PURCHASE_GROUP_CODE: '32F', DISPLAY_NAME: '이영희_자재팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1002345' },
+ { PURCHASE_GROUP_CODE: '45A', DISPLAY_NAME: '박민수_조달팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1003456' },
+ { PURCHASE_GROUP_CODE: '67K', DISPLAY_NAME: '정수진_구매1팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1004567' },
+ { PURCHASE_GROUP_CODE: '89D', DISPLAY_NAME: '최동욱_구매2팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1005678' },
+ { PURCHASE_GROUP_CODE: '11B', DISPLAY_NAME: '강미라_자재관리팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1006789' },
+ { PURCHASE_GROUP_CODE: '23G', DISPLAY_NAME: '윤성호_구매기획팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1007890' },
+ { PURCHASE_GROUP_CODE: '56H', DISPLAY_NAME: '임지훈_조달지원팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1008901' },
+ { PURCHASE_GROUP_CODE: '78M', DISPLAY_NAME: '한소희_구매운영팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1009012' },
+ { PURCHASE_GROUP_CODE: '90C', DISPLAY_NAME: '오준석_전략구매팀_재직(테스트데이터 - 오라클 페칭 실패시)', EMPLOYEE_NUMBER: '1010123' },
+]
+
+/**
+ * 모든 구매그룹코드 목록 조회 (Oracle에서 전체 조회, 실패 시 폴백 데이터 사용)
+ * CMCTB_CDNM, CMCTB_CD 테이블에서 CD_CLF = 'MMA070' 조건으로 조회
+ * 클라이언트에서 검색/필터링 수행
+ */
+export async function getPurchaseGroupCodes(): Promise<{
+ success: boolean
+ data: PurchaseGroupCode[]
+ error?: string
+ isUsingFallback?: boolean
+}> {
+ try {
+ console.log('📋 [getPurchaseGroupCodes] Oracle 쿼리 시작...')
+
+ const result = await oracleKnex.raw(`
+ SELECT
+ CD.CD AS PURCHASE_GROUP_CODE,
+ NM.CDNM AS DISPLAY_NAME,
+ CD.USR_DF_CHAR_9 AS EMPLOYEE_NUMBER
+ FROM CMCTB_CDNM NM
+ JOIN CMCTB_CD CD
+ ON NM.CD_CLF = CD.CD_CLF
+ AND NM.CD = CD.CD
+ AND NM.CD2 = CD.CD3
+ WHERE NM.CD_CLF = 'MMA070'
+ AND CD.DEL_YN != 'Y'
+ ORDER BY CD.CD
+ `)
+
+ // Oracle raw query의 결과는 rows 배열에 들어있음
+ const rows = (result.rows || result) as Array<Record<string, unknown>>
+
+ console.log(`✅ [getPurchaseGroupCodes] Oracle 쿼리 성공 - ${rows.length}건 조회`)
+
+ // null 값 필터링
+ const cleanedResult = rows
+ .filter((item) =>
+ item.PURCHASE_GROUP_CODE &&
+ item.DISPLAY_NAME &&
+ item.EMPLOYEE_NUMBER
+ )
+ .map((item) => ({
+ PURCHASE_GROUP_CODE: String(item.PURCHASE_GROUP_CODE),
+ DISPLAY_NAME: String(item.DISPLAY_NAME),
+ EMPLOYEE_NUMBER: String(item.EMPLOYEE_NUMBER)
+ }))
+
+ console.log(`✅ [getPurchaseGroupCodes] 필터링 후 ${cleanedResult.length}건`)
+
+ return {
+ success: true,
+ data: cleanedResult,
+ isUsingFallback: false
+ }
+ } catch (error) {
+ console.error('❌ [getPurchaseGroupCodes] Oracle 오류:', error)
+ console.log('🔄 [getPurchaseGroupCodes] 폴백 테스트 데이터 사용 (' + FALLBACK_TEST_DATA.length + '건)')
+ return {
+ success: true,
+ data: FALLBACK_TEST_DATA,
+ isUsingFallback: true
+ }
+ }
+}
+
+/**
+ * 구매그룹코드(들)에 사용자 정보 추가 (1개 또는 여러 개 처리)
+ * @param codes - 단일 또는 배열 형태의 구매그룹코드
+ * @returns 사용자 정보가 포함된 구매그룹코드 배열
+ */
+export async function addUsersToCodesAsync(
+ codes: PurchaseGroupCode | PurchaseGroupCode[]
+): Promise<PurchaseGroupCodeWithUser[]> {
+ try {
+ // 배열로 정규화
+ const codesArray = Array.isArray(codes) ? codes : [codes]
+
+ console.log(`👤 [addUsersToCodesAsync] ${codesArray.length}개 구매그룹코드에 대한 사용자 정보 조회 시작`)
+
+ // 각 구매그룹코드에 대해 사용자 정보 조회
+ const withUsers = await Promise.all(
+ codesArray.map(async (code) => {
+ console.log(` 🔍 [addUsersToCodesAsync] 사번 ${code.EMPLOYEE_NUMBER} 조회 중...`)
+ const user = await getUserByEmployeeNumber(code.EMPLOYEE_NUMBER)
+
+ if (user) {
+ console.log(` ✅ [addUsersToCodesAsync] 사번 ${code.EMPLOYEE_NUMBER} → 사용자 찾음: ${user.name}`)
+ } else {
+ console.log(` ⚠️ [addUsersToCodesAsync] 사번 ${code.EMPLOYEE_NUMBER} → 사용자 없음`)
+ }
+
+ return {
+ ...code,
+ user: user ? {
+ id: user.id,
+ name: user.name,
+ email: user.email,
+ employeeNumber: user.employeeNumber,
+ } : null
+ }
+ })
+ )
+
+ return withUsers
+ } catch (error) {
+ console.error('❌ [addUsersToCodesAsync] 오류:', error)
+ const codesArray = Array.isArray(codes) ? codes : [codes]
+ return codesArray.map(code => ({ ...code, user: null }))
+ }
+}