summaryrefslogtreecommitdiff
path: root/components/common/selectors/purchase-group-code/purchase-group-code-service.ts
blob: 191c9f8597ef3b7a0cec3deb8f8f51ffe7ea5f7a (plain)
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
144
145
146
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 }))
  }
}