summaryrefslogtreecommitdiff
path: root/components/common/selectors/purchase-group-code/README.md
blob: b956a2966fc508b059c5d0579f7e902d90a691be (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# 구매그룹코드 선택기 (Purchase Group Code Selector)

구매그룹코드를 선택할 수 있는 컴포넌트들입니다. Oracle DB의 CMCTB_CDNM, CMCTB_CD 테이블에서 CD_CLF='MMA070' 조건으로 구매그룹 정보를 조회하며, 선택 시 해당 사번의 사용자 정보도 함께 반환합니다.

## 컴포넌트 구조

- `purchase-group-code-service.ts`: 구매그룹코드 데이터 조회 서버 액션 (Oracle DB 조회 + 사용자 정보 포함)
- `purchase-group-code-selector.tsx`: 기본 구매그룹코드 선택기 (트리거 버튼 포함)
- `purchase-group-code-single-selector.tsx`: 단일 선택 다이얼로그
- `purchase-group-code-multi-selector.tsx`: 다중 선택 다이얼로그

## 데이터 구조

```typescript
// 기본 구매그룹코드 정보
interface PurchaseGroupCode {
  PURCHASE_GROUP_CODE: string  // 구매그룹코드
  DISPLAY_NAME: string         // 표시명 (이름_부서_퇴직/전배정보)
  EMPLOYEE_NUMBER: string      // 사번
}

// 사용자 정보를 포함한 구매그룹코드
interface PurchaseGroupCodeWithUser extends PurchaseGroupCode {
  user?: {
    id: number
    name: string
    email: string
    employeeNumber: string | null
    userCode: string | null
  } | null
}
```

## 사용 예제

### 1. 기본 구매그룹코드 선택기

```tsx
import { useState } from 'react'
import { PurchaseGroupCodeSelector, PurchaseGroupCodeWithUser } from '@/components/common/selectors/purchase-group-code'

function MyComponent() {
  const [selectedCode, setSelectedCode] = useState<PurchaseGroupCodeWithUser>()

  const handleSelect = (code: PurchaseGroupCodeWithUser) => {
    console.log('선택된 구매그룹코드:', code.PURCHASE_GROUP_CODE)
    console.log('표시명:', code.DISPLAY_NAME)
    console.log('사번:', code.EMPLOYEE_NUMBER)
    console.log('사용자 정보:', code.user)
    setSelectedCode(code)
  }

  return (
    <PurchaseGroupCodeSelector
      selectedCode={selectedCode}
      onCodeSelect={handleSelect}
      placeholder="구매그룹코드를 선택하세요"
    />
  )
}
```

### 2. 단일 선택 다이얼로그

```tsx
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { 
  PurchaseGroupCodeSingleSelector, 
  PurchaseGroupCodeWithUser 
} from '@/components/common/selectors/purchase-group-code'

function MyComponent() {
  const [open, setOpen] = useState(false)
  const [selectedCode, setSelectedCode] = useState<PurchaseGroupCodeWithUser>()

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        구매그룹코드 선택
      </Button>
      
      <PurchaseGroupCodeSingleSelector
        open={open}
        onOpenChange={setOpen}
        selectedCode={selectedCode}
        onCodeSelect={setSelectedCode}
        title="구매그룹코드 선택"
        description="하나의 구매그룹코드를 선택하세요"
        showConfirmButtons={true}
        onConfirm={(code) => {
          console.log('선택 완료:', code)
          if (code?.user) {
            console.log('연결된 사용자:', code.user.name)
          }
        }}
        onCancel={() => {
          console.log('선택 취소됨')
        }}
      />
    </>
  )
}
```

### 3. 다중 선택 다이얼로그

```tsx
import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { 
  PurchaseGroupCodeMultiSelector, 
  PurchaseGroupCodeWithUser 
} from '@/components/common/selectors/purchase-group-code'

function MyComponent() {
  const [open, setOpen] = useState(false)
  const [selectedCodes, setSelectedCodes] = useState<PurchaseGroupCodeWithUser[]>([])

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        구매그룹코드 다중 선택 ({selectedCodes.length}개 선택됨)
      </Button>
      
      <PurchaseGroupCodeMultiSelector
        open={open}
        onOpenChange={setOpen}
        selectedCodes={selectedCodes}
        onCodesSelect={setSelectedCodes}
        title="구매그룹코드 다중 선택"
        description="여러 구매그룹코드를 선택하세요"
        maxSelection={5} // 최대 5개까지 선택 가능
        onConfirm={(codes) => {
          console.log('선택된 구매그룹코드들:', codes)
          codes.forEach(code => {
            console.log(`${code.PURCHASE_GROUP_CODE}: ${code.user?.name}`)
          })
        }}
        onCancel={() => {
          console.log('선택 취소됨')
        }}
      />
    </>
  )
}
```

### 4. 서버 액션 직접 사용

```tsx
import { 
  getPurchaseGroupCodes, 
  getPurchaseGroupCodeWithUser,
  getPurchaseGroupCodeByEmployeeNumber
} from '@/components/common/selectors/purchase-group-code'

// 모든 구매그룹코드 조회
const result = await getPurchaseGroupCodes()
if (result.success) {
  console.log('구매그룹코드 목록:', result.data)
}

// 검색 조건으로 조회
const searchResult = await getPurchaseGroupCodes({
  searchTerm: '홍길동',
  limit: 50
})

// 특정 구매그룹코드로 조회 (사용자 정보 포함)
const codeWithUser = await getPurchaseGroupCodeWithUser('PG001')
if (codeWithUser) {
  console.log('구매그룹코드:', codeWithUser.PURCHASE_GROUP_CODE)
  console.log('사용자:', codeWithUser.user?.name)
}

// 사번으로 구매그룹코드 조회 (사용자 정보 포함)
const byEmployeeNumber = await getPurchaseGroupCodeByEmployeeNumber('1234567')
if (byEmployeeNumber) {
  console.log('해당 사번의 구매그룹코드:', byEmployeeNumber.PURCHASE_GROUP_CODE)
}
```

## Props 옵션

### PurchaseGroupCodeSelector

- `selectedCode?: PurchaseGroupCodeWithUser` - 선택된 구매그룹코드
- `onCodeSelect: (code: PurchaseGroupCodeWithUser) => void` - 구매그룹코드 선택 콜백
- `disabled?: boolean` - 비활성화 여부
- `placeholder?: string` - 플레이스홀더 텍스트
- `className?: string` - 추가 CSS 클래스
- `searchOptions?: Partial<PurchaseGroupCodeSearchOptions>` - 검색 옵션

### PurchaseGroupCodeSingleSelector

- `open: boolean` - 다이얼로그 열림 상태
- `onOpenChange: (open: boolean) => void` - 다이얼로그 상태 변경 콜백
- `selectedCode?: PurchaseGroupCodeWithUser` - 선택된 구매그룹코드
- `onCodeSelect: (code: PurchaseGroupCodeWithUser) => void` - 구매그룹코드 선택 콜백
- `onConfirm?: (code: PurchaseGroupCodeWithUser | undefined) => void` - 확인 버튼 콜백
- `onCancel?: () => void` - 취소 버튼 콜백
- `title?: string` - 다이얼로그 제목
- `description?: string` - 다이얼로그 설명
- `showConfirmButtons?: boolean` - 확인/취소 버튼 표시 여부

### PurchaseGroupCodeMultiSelector

- `open: boolean` - 다이얼로그 열림 상태
- `onOpenChange: (open: boolean) => void` - 다이얼로그 상태 변경 콜백
- `selectedCodes?: PurchaseGroupCodeWithUser[]` - 선택된 구매그룹코드들
- `onCodesSelect: (codes: PurchaseGroupCodeWithUser[]) => void` - 구매그룹코드들 선택 콜백
- `onConfirm?: (codes: PurchaseGroupCodeWithUser[]) => void` - 확인 버튼 콜백
- `onCancel?: () => void` - 취소 버튼 콜백
- `title?: string` - 다이얼로그 제목
- `description?: string` - 다이얼로그 설명
- `maxSelection?: number` - 최대 선택 가능 개수

## 특징

- **Oracle DB 연동**: Oracle NonSAP 데이터베이스에서 실시간 조회
- **폴백 테스트 데이터**: Oracle DB 연결 실패 시 자동으로 테스트 데이터 사용
- **사용자 정보 통합**: 선택 시 사번으로 연결된 사용자 정보 자동 조회
- **검색 기능**: 구매그룹코드, 이름, 사번으로 실시간 검색
- **페이지네이션**: 대량의 데이터를 페이지별로 표시
- **디바운스**: 검색 성능 최적화
- **다중 선택 지원**: 여러 구매그룹코드 동시 선택 가능
- **접근성**: 키보드 네비게이션 및 스크린 리더 지원
- **반응형**: 다양한 화면 크기에 대응

## 데이터 소스

구매그룹코드는 Oracle DB의 다음 테이블에서 조회됩니다:

```sql
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.USR_DF_CHAR_9 IS NOT NULL
```

사용자 정보는 PostgreSQL DB의 `users` 테이블에서 `employeeNumber`로 조회됩니다.

## 주의사항

1. **Oracle DB 연결 필요**: 이 컴포넌트는 Oracle DB 연결이 필요합니다. 환경 변수가 올바르게 설정되어 있는지 확인하세요.
2. **폴백 테스트 데이터**: Oracle DB 연결 실패 시 하드코딩된 10개의 테스트 데이터가 자동으로 사용됩니다. 테스트 환경에서 유용합니다.
3. **사용자 정보 매칭**: 사번으로 사용자 정보를 조회하므로, 사용자 테이블에 해당 사번이 존재해야 합니다.
4. **성능**: 검색 시 Oracle DB를 직접 조회하므로, 대량 데이터 환경에서는 인덱스 설정이 중요합니다.

## 폴백 테스트 데이터

Oracle DB 연결이 불가능한 테스트 환경에서는 다음 10개의 구매그룹코드가 자동으로 제공됩니다:

- `12L` - 김철수_구매팀_재직
- `32F` - 이영희_자재팀_재직
- `45A` - 박민수_조달팀_재직
- `67K` - 정수진_구매1팀_재직
- `89D` - 최동욱_구매2팀_재직
- `11B` - 강미라_자재관리팀_재직
- `23G` - 윤성호_구매기획팀_재직
- `56H` - 임지훈_조달지원팀_재직
- `78M` - 한소희_구매운영팀_재직
- `90C` - 오준석_전략구매팀_재직

## 관련 서비스

- 구매그룹코드 동기화: `lib/nonsap-sync/purchase-group-code/purchase-group-code-sync.ts`
- 사용자 서비스: `lib/users/service.ts`