[Employee]

- PATCH 용 과거 데이터와 비교 로직 + null 값 반영 안함
This commit is contained in:
Hyojin Ahn 2025-12-17 08:22:08 -05:00
parent b915f93396
commit 187d602daf
1 changed files with 192 additions and 55 deletions

View File

@ -3,15 +3,23 @@ package com.goi.erp.service;
import com.goi.erp.dto.EmployeeRequestDto;
import com.goi.erp.dto.EmployeeResponseDto;
import com.goi.erp.entity.Employee;
import com.goi.erp.entity.EntityChangeLog;
import com.goi.erp.repository.EmployeeRepository;
import com.goi.erp.repository.EntityChangeLogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
@ -22,6 +30,7 @@ public class EmployeeService {
private final EmployeeRepository employeeRepository;
private final PasswordEncoder passwordEncoder; // 비밀번호 암호화 (auth-service처럼)
private final EntityChangeLogRepository entityChangeLogRepository;
/**
* CREATE
@ -134,65 +143,72 @@ public class EmployeeService {
/**
* UPDATE
*/
public EmployeeResponseDto updateEmployee(UUID empUuid, EmployeeRequestDto dto) {
public EmployeeResponseDto updateEmployee(UUID empUuid, EmployeeRequestDto newEmp) {
Employee employee = employeeRepository.findByEmpUuid(empUuid)
Employee oldEmployee = employeeRepository.findByEmpUuid(empUuid)
.orElseThrow(() -> new RuntimeException("Employee not found"));
// PATCH: 값이 있는 것만 적용
if (dto.getEmpNo() != null) employee.setEmpNo(dto.getEmpNo());
if (dto.getEmpLoginId() != null) employee.setEmpLoginId(dto.getEmpLoginId());
if (dto.getEmpLoginPassword() != null && !dto.getEmpLoginPassword().isEmpty()) employee.setEmpLoginPassword(passwordEncoder.encode(dto.getEmpLoginPassword()));
if (dto.getEmpFirstName() != null) employee.setEmpFirstName(dto.getEmpFirstName());
if (dto.getEmpMiddleName() != null) employee.setEmpMiddleName(dto.getEmpMiddleName());
if (dto.getEmpLastName() != null) employee.setEmpLastName(dto.getEmpLastName());
if (dto.getEmpPreferredFirstName() != null) employee.setEmpPreferredFirstName(dto.getEmpPreferredFirstName());
if (dto.getEmpPreferredLastName() != null) employee.setEmpPreferredLastName(dto.getEmpPreferredLastName());
if (dto.getEmpStatus() != null) employee.setEmpStatus(dto.getEmpStatus());
if (dto.getEmpFulltime() != null) employee.setEmpFulltime(dto.getEmpFulltime());
if (dto.getEmpEmploymentType() != null) employee.setEmpEmploymentType(dto.getEmpEmploymentType());
if (dto.getEmpLeaveStatus() != null) employee.setEmpLeaveStatus(dto.getEmpLeaveStatus());
if (dto.getEmpOfferAcceptedDate() != null) employee.setEmpOfferAcceptedDate(dto.getEmpOfferAcceptedDate());
if (dto.getEmpNationality() != null) employee.setEmpNationality(dto.getEmpNationality());
if (dto.getEmpCitizenshipStatus() != null) employee.setEmpCitizenshipStatus(dto.getEmpCitizenshipStatus());
if (dto.getEmpPassportNo() != null) employee.setEmpPassportNo(dto.getEmpPassportNo());
if (dto.getEmpPassportCountry() != null) employee.setEmpPassportCountry(dto.getEmpPassportCountry());
if (dto.getEmpPassportIssueDate() != null) employee.setEmpPassportIssueDate(dto.getEmpPassportIssueDate());
if (dto.getEmpPassportExpiryDate() != null) employee.setEmpPassportExpiryDate(dto.getEmpPassportExpiryDate());
if (dto.getEmpVisaType() != null) employee.setEmpVisaType(dto.getEmpVisaType());
if (dto.getEmpVisaIssueDate() != null) employee.setEmpVisaIssueDate(dto.getEmpVisaIssueDate());
if (dto.getEmpVisaExpiryDate() != null) employee.setEmpVisaExpiryDate(dto.getEmpVisaExpiryDate());
if (dto.getEmpVisaCountry() != null) employee.setEmpVisaCountry(dto.getEmpVisaCountry());
if (dto.getEmpDateOfBirth() != null) employee.setEmpDateOfBirth(dto.getEmpDateOfBirth());
if (dto.getEmpSex() != null) employee.setEmpSex(dto.getEmpSex());
if (dto.getEmpSin() != null) employee.setEmpSin(dto.getEmpSin());
if (dto.getEmpAccountNo() != null) employee.setEmpAccountNo(dto.getEmpAccountNo());
if (dto.getEmpDriverLicenseNo() != null) employee.setEmpDriverLicenseNo(dto.getEmpDriverLicenseNo());
if (dto.getEmpPersonalEmail() != null) employee.setEmpPersonalEmail(dto.getEmpPersonalEmail());
if (dto.getEmpPersonalPhone() != null) employee.setEmpPersonalPhone(dto.getEmpPersonalPhone());
if (dto.getEmpAddress1() != null) employee.setEmpAddress1(dto.getEmpAddress1());
if (dto.getEmpAddress2() != null) employee.setEmpAddress2(dto.getEmpAddress2());
if (dto.getEmpPostalCode() != null) employee.setEmpPostalCode(dto.getEmpPostalCode());
if (dto.getEmpCity() != null) employee.setEmpCity(dto.getEmpCity());
if (dto.getEmpProvince() != null) employee.setEmpProvince(dto.getEmpProvince());
if (dto.getEmpContractStartDate() != null) employee.setEmpContractStartDate(dto.getEmpContractStartDate());
if (dto.getEmpProbationStartDate() != null) employee.setEmpProbationStartDate(dto.getEmpProbationStartDate());
if (dto.getEmpProbationEndDate() != null) employee.setEmpProbationEndDate(dto.getEmpProbationEndDate());
if (dto.getEmpProbationStatus() != null) employee.setEmpProbationStatus(dto.getEmpProbationStatus());
if (dto.getEmpJobStartDate() != null) employee.setEmpJobStartDate(dto.getEmpJobStartDate());
if (dto.getEmpJobEndDate() != null) employee.setEmpJobEndDate(dto.getEmpJobEndDate());
if (dto.getEmpTerminationDate() != null) employee.setEmpTerminationDate(dto.getEmpTerminationDate());
if (dto.getEmpTerminationReason() != null) employee.setEmpTerminationReason(dto.getEmpTerminationReason());
if (dto.getEmpDeptId() != null) employee.setEmpDeptId(dto.getEmpDeptId());
if (dto.getEmpRate() != null) employee.setEmpRate(dto.getEmpRate());
if (dto.getEmpRateOt() != null) employee.setEmpRateOt(dto.getEmpRateOt());
if (dto.getEmpRateDot() != null) employee.setEmpRateDot(dto.getEmpRateDot());
if (dto.getEmpOfficeEmail() != null) employee.setEmpOfficeEmail(dto.getEmpOfficeEmail());
if (dto.getEmpOfficeMobile() != null) employee.setEmpOfficeMobile(dto.getEmpOfficeMobile());
if (dto.getEmpOfficePhone() != null) employee.setEmpOfficePhone(dto.getEmpOfficePhone());
if (dto.getEmpExtensionNo() != null) employee.setEmpExtensionNo(dto.getEmpExtensionNo());
// 기존 복사본 생성
Employee beforeUpdate = new Employee();
BeanUtils.copyProperties(oldEmployee, beforeUpdate);
return mapToDto(employee);
// PATCH: 값이 있는 것만 적용
if (newEmp.getEmpNo() != null) oldEmployee.setEmpNo(newEmp.getEmpNo());
if (newEmp.getEmpLoginId() != null) oldEmployee.setEmpLoginId(newEmp.getEmpLoginId());
if (newEmp.getEmpLoginPassword() != null && !newEmp.getEmpLoginPassword().isEmpty()) oldEmployee.setEmpLoginPassword(passwordEncoder.encode(newEmp.getEmpLoginPassword()));
if (newEmp.getEmpFirstName() != null) oldEmployee.setEmpFirstName(newEmp.getEmpFirstName());
if (newEmp.getEmpMiddleName() != null) oldEmployee.setEmpMiddleName(newEmp.getEmpMiddleName());
if (newEmp.getEmpLastName() != null) oldEmployee.setEmpLastName(newEmp.getEmpLastName());
if (newEmp.getEmpPreferredFirstName() != null) oldEmployee.setEmpPreferredFirstName(newEmp.getEmpPreferredFirstName());
if (newEmp.getEmpPreferredLastName() != null) oldEmployee.setEmpPreferredLastName(newEmp.getEmpPreferredLastName());
if (newEmp.getEmpStatus() != null) oldEmployee.setEmpStatus(newEmp.getEmpStatus());
if (newEmp.getEmpFulltime() != null) oldEmployee.setEmpFulltime(newEmp.getEmpFulltime());
if (newEmp.getEmpEmploymentType() != null) oldEmployee.setEmpEmploymentType(newEmp.getEmpEmploymentType());
if (newEmp.getEmpLeaveStatus() != null) oldEmployee.setEmpLeaveStatus(newEmp.getEmpLeaveStatus());
if (newEmp.getEmpOfferAcceptedDate() != null) oldEmployee.setEmpOfferAcceptedDate(newEmp.getEmpOfferAcceptedDate());
if (newEmp.getEmpNationality() != null) oldEmployee.setEmpNationality(newEmp.getEmpNationality());
if (newEmp.getEmpCitizenshipStatus() != null) oldEmployee.setEmpCitizenshipStatus(newEmp.getEmpCitizenshipStatus());
if (newEmp.getEmpPassportNo() != null) oldEmployee.setEmpPassportNo(newEmp.getEmpPassportNo());
if (newEmp.getEmpPassportCountry() != null) oldEmployee.setEmpPassportCountry(newEmp.getEmpPassportCountry());
if (newEmp.getEmpPassportIssueDate() != null) oldEmployee.setEmpPassportIssueDate(newEmp.getEmpPassportIssueDate());
if (newEmp.getEmpPassportExpiryDate() != null) oldEmployee.setEmpPassportExpiryDate(newEmp.getEmpPassportExpiryDate());
if (newEmp.getEmpVisaType() != null) oldEmployee.setEmpVisaType(newEmp.getEmpVisaType());
if (newEmp.getEmpVisaIssueDate() != null) oldEmployee.setEmpVisaIssueDate(newEmp.getEmpVisaIssueDate());
if (newEmp.getEmpVisaExpiryDate() != null) oldEmployee.setEmpVisaExpiryDate(newEmp.getEmpVisaExpiryDate());
if (newEmp.getEmpVisaCountry() != null) oldEmployee.setEmpVisaCountry(newEmp.getEmpVisaCountry());
if (newEmp.getEmpDateOfBirth() != null) oldEmployee.setEmpDateOfBirth(newEmp.getEmpDateOfBirth());
if (newEmp.getEmpSex() != null) oldEmployee.setEmpSex(newEmp.getEmpSex());
if (newEmp.getEmpSin() != null) oldEmployee.setEmpSin(newEmp.getEmpSin());
if (newEmp.getEmpAccountNo() != null) oldEmployee.setEmpAccountNo(newEmp.getEmpAccountNo());
if (newEmp.getEmpDriverLicenseNo() != null) oldEmployee.setEmpDriverLicenseNo(newEmp.getEmpDriverLicenseNo());
if (newEmp.getEmpPersonalEmail() != null) oldEmployee.setEmpPersonalEmail(newEmp.getEmpPersonalEmail());
if (newEmp.getEmpPersonalPhone() != null) oldEmployee.setEmpPersonalPhone(newEmp.getEmpPersonalPhone());
if (newEmp.getEmpAddress1() != null) oldEmployee.setEmpAddress1(newEmp.getEmpAddress1());
if (newEmp.getEmpAddress2() != null) oldEmployee.setEmpAddress2(newEmp.getEmpAddress2());
if (newEmp.getEmpPostalCode() != null) oldEmployee.setEmpPostalCode(newEmp.getEmpPostalCode());
if (newEmp.getEmpCity() != null) oldEmployee.setEmpCity(newEmp.getEmpCity());
if (newEmp.getEmpProvince() != null) oldEmployee.setEmpProvince(newEmp.getEmpProvince());
if (newEmp.getEmpContractStartDate() != null) oldEmployee.setEmpContractStartDate(newEmp.getEmpContractStartDate());
if (newEmp.getEmpProbationStartDate() != null) oldEmployee.setEmpProbationStartDate(newEmp.getEmpProbationStartDate());
if (newEmp.getEmpProbationEndDate() != null) oldEmployee.setEmpProbationEndDate(newEmp.getEmpProbationEndDate());
if (newEmp.getEmpProbationStatus() != null) oldEmployee.setEmpProbationStatus(newEmp.getEmpProbationStatus());
if (newEmp.getEmpJobStartDate() != null) oldEmployee.setEmpJobStartDate(newEmp.getEmpJobStartDate());
if (newEmp.getEmpJobEndDate() != null) oldEmployee.setEmpJobEndDate(newEmp.getEmpJobEndDate());
if (newEmp.getEmpTerminationDate() != null) oldEmployee.setEmpTerminationDate(newEmp.getEmpTerminationDate());
if (newEmp.getEmpTerminationReason() != null) oldEmployee.setEmpTerminationReason(newEmp.getEmpTerminationReason());
if (newEmp.getEmpDeptId() != null) oldEmployee.setEmpDeptId(newEmp.getEmpDeptId());
if (newEmp.getEmpRate() != null) oldEmployee.setEmpRate(newEmp.getEmpRate());
if (newEmp.getEmpRateOt() != null) oldEmployee.setEmpRateOt(newEmp.getEmpRateOt());
if (newEmp.getEmpRateDot() != null) oldEmployee.setEmpRateDot(newEmp.getEmpRateDot());
if (newEmp.getEmpOfficeEmail() != null) oldEmployee.setEmpOfficeEmail(newEmp.getEmpOfficeEmail());
if (newEmp.getEmpOfficeMobile() != null) oldEmployee.setEmpOfficeMobile(newEmp.getEmpOfficeMobile());
if (newEmp.getEmpOfficePhone() != null) oldEmployee.setEmpOfficePhone(newEmp.getEmpOfficePhone());
if (newEmp.getEmpExtensionNo() != null) oldEmployee.setEmpExtensionNo(newEmp.getEmpExtensionNo());
// 변경 로그 기록
//compareAndLogChanges(oldData, oldEmployee, changedBy);
return mapToDto(oldEmployee);
}
@ -275,4 +291,125 @@ public class EmployeeService {
return dto;
}
private void compareAndLogChanges(Employee oldData, Employee newData, String changedBy) {
Map<String, String> fieldToColumn = Map.ofEntries(
Map.entry("empNo", "emp_no"),
Map.entry("empLoginId", "emp_login_id"),
Map.entry("empFirstName", "emp_first_name"),
Map.entry("empMiddleName", "emp_middle_name"),
Map.entry("empLastName", "emp_last_name"),
Map.entry("empPreferredFirstName", "emp_preferred_first_name"),
Map.entry("empPreferredLastName", "emp_preferred_last_name"),
Map.entry("empStatus", "emp_status"),
Map.entry("empFulltime", "emp_fulltime"),
Map.entry("empEmploymentType", "emp_employment_type"),
Map.entry("empLeaveStatus", "emp_leave_status"),
Map.entry("empOfferAcceptedDate", "emp_offer_accepted_date"),
Map.entry("empNationality", "emp_nationality"),
Map.entry("empCitizenshipStatus", "emp_citizenship_status"),
Map.entry("empPassportNo", "emp_passport_no"),
Map.entry("empPassportCountry", "emp_passport_country"),
Map.entry("empPassportIssueDate", "emp_passport_issue_date"),
Map.entry("empPassportExpiryDate", "emp_passport_expiry_date"),
Map.entry("empVisaType", "emp_visa_type"),
Map.entry("empVisaIssueDate", "emp_visa_issue_date"),
Map.entry("empVisaExpiryDate", "emp_visa_expiry_date"),
Map.entry("empVisaCountry", "emp_visa_country"),
Map.entry("empDateOfBirth", "emp_date_of_birth"),
Map.entry("empSex", "emp_sex"),
Map.entry("empSin", "emp_sin"),
Map.entry("empAccountNo", "emp_account_no"),
Map.entry("empDriverLicenseNo", "emp_driver_license_no"),
Map.entry("empPersonalEmail", "emp_personal_email"),
Map.entry("empPersonalPhone", "emp_personal_phone"),
Map.entry("empAddress1", "emp_address1"),
Map.entry("empAddress2", "emp_address2"),
Map.entry("empPostalCode", "emp_postal_code"),
Map.entry("empCity", "emp_city"),
Map.entry("empProvince", "emp_province"),
Map.entry("empContractStartDate", "emp_contract_start_date"),
Map.entry("empProbationStartDate", "emp_probation_start_date"),
Map.entry("empProbationEndDate", "emp_probation_end_date"),
Map.entry("empProbationStatus", "emp_probation_status"),
Map.entry("empJobStartDate", "emp_job_start_date"),
Map.entry("empJobEndDate", "emp_job_end_date"),
Map.entry("empTerminationDate", "emp_termination_date"),
Map.entry("empTerminationReason", "emp_termination_reason"),
Map.entry("empDeptId", "emp_dept_id"),
Map.entry("empRate", "emp_rate"),
Map.entry("empRateOt", "emp_rate_ot"),
Map.entry("empRateDot", "emp_rate_dot"),
Map.entry("empOfficeEmail", "emp_office_email"),
Map.entry("empOfficeMobile", "emp_office_mobile"),
Map.entry("empOfficePhone", "emp_office_phone"),
Map.entry("empExtensionNo", "emp_extension_no")
);
Class<?> clazz = Employee.class;
for (var entry : fieldToColumn.entrySet()) {
String fieldName = entry.getKey();
String columnName = entry.getValue();
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Object oldVal = field.get(oldData);
Object newVal = field.get(newData);
if (valuesAreDifferent(oldVal, newVal)) {
entityChangeLogRepository.save(
EntityChangeLog.builder()
.eclEntityType("Employee")
.eclEntityId(newData.getEmpId())
.eclFieldName(fieldName)
.eclColumnName(columnName)
.eclOldValue(oldVal == null ? null : oldVal.toString())
.eclNewValue(newVal == null ? null : newVal.toString())
.eclChangedBy(changedBy)
.eclChangedAt(LocalDateTime.now())
.eclEffectiveDate(LocalDate.now())
.build()
);
}
} catch (Exception e) {
throw new RuntimeException("Failed to compare field: " + fieldName, e);
}
}
}
private boolean valuesAreDifferent(Object oldVal, Object newVal) {
if (oldVal == null && newVal == null) return false;
if (oldVal == null || newVal == null) return true;
// BigDecimal (numeric 비교)
if (oldVal instanceof BigDecimal oldNum && newVal instanceof BigDecimal newNum) {
return oldNum.compareTo(newNum) != 0;
}
// LocalDate
if (oldVal instanceof LocalDate oldDate && newVal instanceof LocalDate newDate) {
return !oldDate.isEqual(newDate);
}
// LocalDateTime
if (oldVal instanceof LocalDateTime oldDt && newVal instanceof LocalDateTime newDt) {
return !oldDt.equals(newDt);
}
// Boolean
if (oldVal instanceof Boolean && newVal instanceof Boolean) {
return !oldVal.equals(newVal);
}
// 기본 equals
return !oldVal.equals(newVal);
}
}