summaryrefslogtreecommitdiff
path: root/lib/pos/get-dcmtm-id.ts
blob: 78c7793bc434c018e76fbf134341644ec8f2d306 (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
'use server';

import { oracleKnex } from '@/lib/oracle-db/db';
import type { PosFileInfo, GetDcmtmIdParams, GetDcmtmIdResult } from './types';
import { debugLog, debugError, debugSuccess, debugProcess } from '@/lib/debug-utils';

/**
 * 자재코드로 POS 파일의 DCMTM_ID를 조회하는 서버 액션
 * 
 * @param params - 자재코드를 포함한 조회 파라미터
 * @returns POS 파일 정보 목록 (여러 파일이 있을 수 있음)
 */
export async function getDcmtmIdByMaterialCode(
  params: GetDcmtmIdParams
): Promise<GetDcmtmIdResult> {
  try {
    const { materialCode } = params;
    debugLog(`🔍 DCMTM_ID 조회 시작`, { materialCode });

    if (!materialCode) {
      debugError(`❌ 자재코드가 제공되지 않음`);
      return {
        success: false,
        error: '자재코드가 제공되지 않았습니다.',
      };
    }

    // Oracle 쿼리 실행
    const query = `
      SELECT Y.PROJ_NO,
             Y.POS_NO,
             Y.POS_REV_NO,
             Y.FILE_SER,
             Y.FILE_NM,
             Y.DCMTM_ID
      FROM PLDTB_POS_ITEM X,
           PLDTB_POS_ITEM_FILE Y,
           PLMTB_EMLS Z
      WHERE X.PROJ_NO = Y.PROJ_NO
        AND X.POS_NO = Y.POS_NO
        AND X.POS_REV_NO = Y.POS_REV_NO
        AND X.POS_NO = Z.DOC_NO
        AND NVL(X.APP_ID, ' ') <> ' '
        AND NVL(Z.PUR_REQ_NO, ' ') <> ' '
        AND Z.MAT_NO = ?
    `;

    debugProcess(`🗄️ Oracle 쿼리 실행`, { materialCode, query: query.trim() });
    const results = await oracleKnex.raw(query, [materialCode]);
    debugLog(`🗄️ Oracle 쿼리 결과`, {
      materialCode,
      resultType: typeof results,
      isArray: Array.isArray(results),
      resultKeys: results && typeof results === 'object' ? Object.keys(results) : null,
      resultLength: Array.isArray(results) ? results.length : null,
      resultValue: results
    });

    // Oracle 결과 처리 (oracledb 드라이버의 결과 구조에 따라)
    // Knex.js oracledb 클라이언트의 실제 결과 구조:
    // - 데이터 행들의 배열: [{PROJ_NO: '...', ...}, {PROJ_NO: '...', ...}]
    // - 또는 [rows, metaData] 형태
    // - 또는 { rows: [...], metaData: [...] } 형태
    let rows;
    if (Array.isArray(results)) {
      debugLog(`🔍 배열 형태 결과 처리`, {
        materialCode,
        arrayLength: results.length,
        firstElementType: typeof results[0],
        firstElementIsArray: Array.isArray(results[0]),
        firstElementKeys: results[0] && typeof results[0] === 'object' ? Object.keys(results[0]) : null
      });

      // results가 데이터 행들의 배열인지 확인
      if (results.length > 0 && typeof results[0] === 'object' && !Array.isArray(results[0]) && results[0].PROJ_NO) {
        // results = [{PROJ_NO: '...', POS_NO: '...', ...}, ...] - 바로 데이터 행들
        rows = results;
      } else {
        // [rows, metaData] 형태 - 첫 번째 요소가 실제 데이터
        rows = results[0] || [];
      }
    } else if (results && typeof results === 'object' && results.rows) {
      debugLog(`🔍 객체 형태 결과 처리`, {
        materialCode,
        hasRows: !!results.rows,
        rowsType: typeof results.rows,
        rowsIsArray: Array.isArray(results.rows),
        rowsLength: Array.isArray(results.rows) ? results.rows.length : null
      });

      // { rows: [...], metaData: [...] } 형태
      rows = results.rows || [];
    } else {
      debugLog(`🔍 기타 형태 결과 처리`, {
        materialCode,
        resultValue: results
      });

      // 직접 배열인 경우
      rows = results || [];
    }

    debugLog(`📊 최종 rows 추출 결과`, {
      materialCode,
      rowsType: typeof rows,
      isRowsArray: Array.isArray(rows),
      rowCount: Array.isArray(rows) ? rows.length : 0,
      firstRow: Array.isArray(rows) && rows.length > 0 ? rows[0] : null,
      firstRowType: Array.isArray(rows) && rows.length > 0 ? typeof rows[0] : null
    });
    
    if (!Array.isArray(rows) || rows.length === 0) {
      debugLog(`⚠️ POS 파일을 찾을 수 없음 (자재코드: ${materialCode})`);
      return {
        success: false,
        error: '해당 자재코드에 대한 POS 파일을 찾을 수 없습니다.',
      };
    }

    // 결과를 PosFileInfo 형태로 변환
    debugProcess(`🔄 Oracle 결과를 PosFileInfo로 변환 중...`);
    const files: PosFileInfo[] = rows.map((row: Record<string, unknown>, index: number) => {
      const fileInfo = {
        projNo: (row.PROJ_NO || row[0]) as string,
        posNo: (row.POS_NO || row[1]) as string,
        posRevNo: (row.POS_REV_NO || row[2]) as string,
        fileSer: (row.FILE_SER || row[3]) as string,
        fileName: (row.FILE_NM || row[4]) as string,
        dcmtmId: (row.DCMTM_ID || row[5]) as string,
      };
      debugLog(`📄 파일 ${index + 1} 변환 결과`, { materialCode, index, original: row, converted: fileInfo });
      return fileInfo;
    });

    debugSuccess(`✅ DCMTM_ID 조회 성공 (자재코드: ${materialCode}, 파일 수: ${files.length})`);
    return {
      success: true,
      files,
    };
  } catch (error) {
    debugError('❌ DCMTM_ID 조회 실패', { 
      materialCode: params.materialCode, 
      error: error instanceof Error ? error.message : '알 수 없는 오류',
      stack: error instanceof Error ? error.stack : undefined
    });
    return {
      success: false,
      error: error instanceof Error ? error.message : '데이터베이스 조회 중 오류가 발생했습니다.',
    };
  }
}

/**
 * 단일 DCMTM_ID만 필요한 경우를 위한 헬퍼 함수
 * 여러 파일이 있을 경우 첫 번째 파일의 DCMTM_ID를 반환
 */
export async function getFirstDcmtmId(
  params: GetDcmtmIdParams
): Promise<{
  success: boolean;
  dcmtmId?: string;
  fileName?: string;
  error?: string;
}> {
  const result = await getDcmtmIdByMaterialCode(params);
  
  if (!result.success || !result.files || result.files.length === 0) {
    return {
      success: false,
      error: result.error,
    };
  }

  const firstFile = result.files[0];
  return {
    success: true,
    dcmtmId: firstFile.dcmtmId,
    fileName: firstFile.fileName,
  };
}