diff options
Diffstat (limited to 'lib/knox-api/employee/employee.ts')
| -rw-r--r-- | lib/knox-api/employee/employee.ts | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/lib/knox-api/employee/employee.ts b/lib/knox-api/employee/employee.ts new file mode 100644 index 00000000..885b5a3f --- /dev/null +++ b/lib/knox-api/employee/employee.ts @@ -0,0 +1,435 @@ +"use server" + +// Knox API 임직원 관련 서버 액션들 + +// 기본 설정 타입 +interface KnoxConfig { + baseUrl: string; + systemId: string; +} + +// 공통 응답 타입 +interface BaseResponse { + result: "success" | "fail"; +} + +// 임직원 조회 관련 타입 +interface EmployeeSearchParams { + companyCode?: string; + fullName?: string; + departmentCode?: string; + employeeNumber?: string; + name?: string; + epIds?: string; + userIds?: string; + emailAddresses?: string; + titleCode?: string; + page?: string; + resultType: "basic" | "optional"; + attributes?: string[]; +} + +interface Employee { + accountStatus?: string; + busiCode?: string; + busiName?: string; + companyCode: string; + companyName: string; + country?: string; + defaultCompanyCode?: string; + departmentCode: string; + departmentName: string; + description?: string; + emailAddress?: string; + employeeNumber?: string; + employeeStatus?: string; + employeeType?: string; + enBusiName?: string; + enCompanyName?: string; + enDepartmentName?: string; + enDiscription?: string; + enFullName?: string; + enGivenName?: string; + enGradeName?: string; + enOfficeAddress?: string; + enRegionName?: string; + enSendBusiName?: string; + enSendCompanyName?: string; + enSendDepartmentName?: string; + enSendGradeName?: string; + enSendRegionName?: string; + enSendSubOrgName?: string; + enSendTitleName?: string; + enSirName?: string; + enSubOrgName?: string; + enTitleName?: string; + epId: string; + executiveYn?: string; + externalEmailAddress?: string; + fullName: string; + givenName?: string; + gradeName?: string; + gradeTitleIndiCode?: string; + inDepartmentCode?: string; + inDepartmentName?: string; + jobName?: string; + jobCode?: string; + localStaffYn?: string; + mobile?: string; + nickName?: string; + officeAddress?: string; + officeDetailAddress?: string; + officeFaxNumber?: string; + officeZipCode?: string; + officeTelNumber?: string; + preferredLanguage?: string; + realNameYn?: string; + regionCode?: string; + regionName?: string; + securityLevel?: string; + sendBusiCde?: string; + sendCompanyCode?: string; + sendCompanyName?: string; + sendDepartmentCode?: string; + sendDepartmentName?: string; + sendGradeName?: string; + sendGradeTitleIndiCode?: string; + sendRegionCode?: string; + sendSecurityLevel?: string; + sendSubOrgCode?: string; + sendSubOrgName?: string; + sendTitleName?: string; + sendTitleCode?: string; + sendTitleSortOrder?: string; + serverLocation?: string; + sirName?: string; + subOrgCode?: string; + subOrgName?: string; + titleName?: string; + titleCode?: string; + titleSortOrder?: string; + openCode?: string; + userId?: string; + voipNumber?: string; + withdrawDate?: string; + epIdExpiryDate?: string; + timeZone?: string; +} + +interface EmployeeResponse extends BaseResponse { + currentPage: number; + totalPage: number; + totalCount: number; + employees: Employee[]; +} + +// 조직도 조회 관련 타입 +interface OrganizationSearchParams { + companyCode: string; + uprDepartmentCode?: string; + departmentCode?: string; + departmentName?: string; + page?: string; +} + +interface Organization { + companyCode: string; + companyName: string; + departmentCode: string; + departmentLevel?: string; + departmentName: string; + departmentOrder?: string; + enCompanyName?: string; + enDepartmentName?: string; + enManagerTitle?: string; + enSubOrgCode?: string; + inDepartmentCode?: string; + lowDepartmentYn?: string; + managerId?: string; + managerName?: string; + managerTitle?: string; + preferredLanguage?: string; + subOrgCode?: string; + subOrgName?: string; + uprDepartmentCode?: string; + enUprDepartmentName?: string; + uprDepartmentName?: string; + hiddenDepartmentYn?: string; + corpCode?: string; + corpName?: string; + enCorpName?: string; +} + +interface OrganizationResponse extends BaseResponse { + currentPage: number; + totalPage: number; + totalCount: number; + organizations: Organization[]; +} + +// 직급정보 조회 관련 타입 +interface TitleSearchParams { + companyCode: string; +} + +interface Title { + companyCode: string; + titleCode: string; + titleName: string; + enTitleName: string; + sortOrder: string; +} + +interface TitleResponse extends BaseResponse { + titles: Title[]; +} + +// 설정 가져오기 (환경변수 또는 설정에서) +const getKnoxConfig = (): KnoxConfig => { + return { + baseUrl: process.env.KNOX_API_BASE_URL || "https://api.knox.samsung.com", + systemId: process.env.KNOX_SYSTEM_ID || "C60REST0001" + }; +}; + +// 공통 헤더 생성 +const createHeaders = (systemId: string): Record<string, string> => { + return { + "Content-Type": "application/json", + "System-ID": systemId + }; +}; + +/** + * 임직원 조회 API + * POST /employee/api/v2.0/employees + */ +export async function searchEmployees(params: EmployeeSearchParams): Promise<EmployeeResponse> { + const config = getKnoxConfig(); + + try { + // URL 파라미터 구성 + const searchParams = new URLSearchParams(); + + if (params.companyCode) searchParams.append("companyCode", params.companyCode); + if (params.fullName) searchParams.append("fullName", params.fullName); + if (params.departmentCode) searchParams.append("departmentCode", params.departmentCode); + if (params.employeeNumber) searchParams.append("employeeNumber", params.employeeNumber); + if (params.name) searchParams.append("name", params.name); + if (params.epIds) searchParams.append("epIds", params.epIds); + if (params.userIds) searchParams.append("userIds", params.userIds); + if (params.emailAddresses) searchParams.append("emailAddresses", params.emailAddresses); + if (params.titleCode) searchParams.append("titleCode", params.titleCode); + if (params.page) searchParams.append("page", params.page); + + // Body 데이터 구성 + const body = { + resultType: params.resultType, + ...(params.attributes && { attributes: params.attributes }) + }; + + const response = await fetch( + `${config.baseUrl}/employee/api/v2.0/employees?${searchParams.toString()}`, + { + method: "POST", + headers: createHeaders(config.systemId), + body: JSON.stringify(body) + } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data as EmployeeResponse; + } catch (error) { + console.error("임직원 조회 오류:", error); + throw error; + } +} + +/** + * 조직도 조회 API + * GET /employee/api/v2.0/organizations + */ +export async function searchOrganizations(params: OrganizationSearchParams): Promise<OrganizationResponse> { + const config = getKnoxConfig(); + + try { + // URL 파라미터 구성 + const searchParams = new URLSearchParams(); + searchParams.append("companyCode", params.companyCode); + + if (params.uprDepartmentCode) searchParams.append("uprDepartmentCode", params.uprDepartmentCode); + if (params.departmentCode) searchParams.append("departmentCode", params.departmentCode); + if (params.departmentName) searchParams.append("departmentName", params.departmentName); + if (params.page) searchParams.append("page", params.page); + + const response = await fetch( + `${config.baseUrl}/employee/api/v2.0/organizations?${searchParams.toString()}`, + { + method: "GET", + headers: createHeaders(config.systemId) + } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data as OrganizationResponse; + } catch (error) { + console.error("조직도 조회 오류:", error); + throw error; + } +} + +/** + * 직급정보 조회 API + * GET /employee/api/v2.0/titles + */ +export async function searchTitles(params: TitleSearchParams): Promise<TitleResponse> { + const config = getKnoxConfig(); + + try { + // URL 파라미터 구성 + const searchParams = new URLSearchParams(); + searchParams.append("companyCode", params.companyCode); + + const response = await fetch( + `${config.baseUrl}/employee/api/v2.0/titles?${searchParams.toString()}`, + { + method: "GET", + headers: createHeaders(config.systemId) + } + ); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data as TitleResponse; + } catch (error) { + console.error("직급정보 조회 오류:", error); + throw error; + } +} + +/** + * 편의 함수들 + */ + +/** + * 사번으로 임직원 조회 + */ +export async function getEmployeeByNumber(employeeNumber: string, companyCode?: string): Promise<Employee | null> { + try { + const response = await searchEmployees({ + employeeNumber, + companyCode, + resultType: "basic" + }); + + if (response.result === "success" && response.employees.length > 0) { + return response.employees[0]; + } + return null; + } catch (error) { + console.error("사번으로 임직원 조회 오류:", error); + return null; + } +} + +/** + * 이메일로 임직원 조회 + */ +export async function getEmployeeByEmail(emailAddress: string, companyCode?: string): Promise<Employee | null> { + try { + const response = await searchEmployees({ + emailAddresses: emailAddress, + companyCode, + resultType: "basic" + }); + + if (response.result === "success" && response.employees.length > 0) { + return response.employees[0]; + } + return null; + } catch (error) { + console.error("이메일로 임직원 조회 오류:", error); + return null; + } +} + +/** + * 부서 코드로 임직원 목록 조회 + */ +export async function getEmployeesByDepartment(departmentCode: string, page?: string): Promise<Employee[]> { + try { + const response = await searchEmployees({ + departmentCode, + page, + resultType: "basic" + }); + + if (response.result === "success") { + return response.employees; + } + return []; + } catch (error) { + console.error("부서별 임직원 조회 오류:", error); + return []; + } +} + +/** + * 회사의 모든 부서 조회 + */ +export async function getDepartmentsByCompany(companyCode: string): Promise<Organization[]> { + try { + const response = await searchOrganizations({ + companyCode + }); + + if (response.result === "success") { + return response.organizations; + } + return []; + } catch (error) { + console.error("회사별 부서 조회 오류:", error); + return []; + } +} + +/** + * 회사의 모든 직급 조회 + */ +export async function getTitlesByCompany(companyCode: string): Promise<Title[]> { + try { + const response = await searchTitles({ companyCode }); + + if (response.result === "success") { + return response.titles; + } + return []; + } catch (error) { + console.error("회사별 직급 조회 오류:", error); + return []; + } +} + +// 타입 export +export type { + EmployeeSearchParams, + Employee, + EmployeeResponse, + OrganizationSearchParams, + Organization, + OrganizationResponse, + TitleSearchParams, + Title, + TitleResponse +}; |
