416 lines
21 KiB
Java
416 lines
21 KiB
Java
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;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Transactional
|
|
public class EmployeeService {
|
|
|
|
private final EmployeeRepository employeeRepository;
|
|
private final PasswordEncoder passwordEncoder; // 비밀번호 암호화 (auth-service처럼)
|
|
private final EntityChangeLogRepository entityChangeLogRepository;
|
|
|
|
/**
|
|
* CREATE
|
|
*/
|
|
public EmployeeResponseDto createEmployee(EmployeeRequestDto dto) {
|
|
|
|
Employee employee = Employee.builder()
|
|
.empUuid(UUID.randomUUID())
|
|
.empNo(dto.getEmpNo())
|
|
.empLoginId(dto.getEmpLoginId())
|
|
.empLoginPassword(passwordEncoder.encode(dto.getEmpLoginPassword()))
|
|
.empFirstName(dto.getEmpFirstName())
|
|
.empMiddleName(dto.getEmpMiddleName())
|
|
.empLastName(dto.getEmpLastName())
|
|
.empPreferredFirstName(dto.getEmpPreferredFirstName())
|
|
.empPreferredLastName(dto.getEmpPreferredLastName())
|
|
.empStatus(dto.getEmpStatus())
|
|
.empFulltime(dto.getEmpFulltime())
|
|
.empEmploymentType(dto.getEmpEmploymentType())
|
|
.empLeaveStatus(dto.getEmpLeaveStatus())
|
|
.empOfferAcceptedDate(dto.getEmpOfferAcceptedDate())
|
|
.empNationality(dto.getEmpNationality())
|
|
.empCitizenshipStatus(dto.getEmpCitizenshipStatus())
|
|
.empPassportNo(dto.getEmpPassportNo())
|
|
.empPassportCountry(dto.getEmpPassportCountry())
|
|
.empPassportIssueDate(dto.getEmpPassportIssueDate())
|
|
.empPassportExpiryDate(dto.getEmpPassportExpiryDate())
|
|
.empVisaType(dto.getEmpVisaType())
|
|
.empVisaIssueDate(dto.getEmpVisaIssueDate())
|
|
.empVisaExpiryDate(dto.getEmpVisaExpiryDate())
|
|
.empVisaCountry(dto.getEmpVisaCountry())
|
|
.empDateOfBirth(dto.getEmpDateOfBirth())
|
|
.empSex(dto.getEmpSex())
|
|
.empSin(dto.getEmpSin())
|
|
.empAccountNo(dto.getEmpAccountNo())
|
|
.empDriverLicenseNo(dto.getEmpDriverLicenseNo())
|
|
.empPersonalEmail(dto.getEmpPersonalEmail())
|
|
.empPersonalPhone(dto.getEmpPersonalPhone())
|
|
.empAddress1(dto.getEmpAddress1())
|
|
.empAddress2(dto.getEmpAddress2())
|
|
.empPostalCode(dto.getEmpPostalCode())
|
|
.empCity(dto.getEmpCity())
|
|
.empProvince(dto.getEmpProvince())
|
|
.empContractStartDate(dto.getEmpContractStartDate())
|
|
.empProbationStartDate(dto.getEmpProbationStartDate())
|
|
.empProbationEndDate(dto.getEmpProbationEndDate())
|
|
.empProbationStatus(dto.getEmpProbationStatus())
|
|
.empJobStartDate(dto.getEmpJobStartDate())
|
|
.empJobEndDate(dto.getEmpJobEndDate())
|
|
.empTerminationDate(dto.getEmpTerminationDate())
|
|
.empTerminationReason(dto.getEmpTerminationReason())
|
|
.empDeptId(dto.getEmpDeptId())
|
|
.empRate(dto.getEmpRate())
|
|
.empRateOt(dto.getEmpRateOt())
|
|
.empRateDot(dto.getEmpRateDot())
|
|
.empOfficeEmail(dto.getEmpOfficeEmail())
|
|
.empOfficeMobile(dto.getEmpOfficeMobile())
|
|
.empOfficePhone(dto.getEmpOfficePhone())
|
|
.empExtensionNo(dto.getEmpExtensionNo())
|
|
.build();
|
|
|
|
employeeRepository.save(employee);
|
|
|
|
return mapToDto(employee);
|
|
}
|
|
|
|
/**
|
|
* READ - detail
|
|
*/
|
|
@Transactional(readOnly = true)
|
|
public EmployeeResponseDto getEmployeeByUuid(UUID empUuid) {
|
|
Employee employee = employeeRepository.findByEmpUuid(empUuid)
|
|
.orElseThrow(() -> new RuntimeException("Employee not found"));
|
|
|
|
return mapToDto(employee);
|
|
}
|
|
|
|
/**
|
|
* READ - list
|
|
*/
|
|
@Transactional(readOnly = true)
|
|
public List<EmployeeResponseDto> getAllEmployees() {
|
|
return employeeRepository.findAll().stream()
|
|
.map(this::mapToDto)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
/**
|
|
* READ - active
|
|
*/
|
|
@Transactional(readOnly = true)
|
|
public List<EmployeeResponseDto> getActiveEmployees() {
|
|
return employeeRepository.findAll().stream()
|
|
.filter(e -> "A".equals(e.getEmpStatus()))
|
|
.map(this::mapToDto)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
/**
|
|
* READ - inactive
|
|
*/
|
|
@Transactional(readOnly = true)
|
|
public List<EmployeeResponseDto> getInactiveEmployees() {
|
|
return employeeRepository.findAll().stream()
|
|
.filter(e -> "I".equals(e.getEmpStatus()))
|
|
.map(this::mapToDto)
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
/**
|
|
* UPDATE
|
|
*/
|
|
public EmployeeResponseDto updateEmployee(UUID empUuid, EmployeeRequestDto newEmp) {
|
|
|
|
Employee oldEmployee = employeeRepository.findByEmpUuid(empUuid)
|
|
.orElseThrow(() -> new RuntimeException("Employee not found"));
|
|
|
|
// 기존 값 복사본 생성
|
|
Employee beforeUpdate = new Employee();
|
|
BeanUtils.copyProperties(oldEmployee, beforeUpdate);
|
|
|
|
// 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);
|
|
}
|
|
|
|
|
|
/**
|
|
* INACTIVATE (Soft Delete)
|
|
* 직원 삭제하지 않고 emp_status = 'I' 로 비활성화
|
|
*/
|
|
public EmployeeResponseDto inactivateEmployee(UUID empUuid) {
|
|
|
|
Employee employee = employeeRepository.findByEmpUuid(empUuid)
|
|
.orElseThrow(() -> new RuntimeException("Employee not found"));
|
|
|
|
employee.setEmpStatus("I"); // Inactive
|
|
|
|
return mapToDto(employee);
|
|
}
|
|
|
|
/**
|
|
* ENTITY → DTO 변환
|
|
*/
|
|
private EmployeeResponseDto mapToDto(Employee e) {
|
|
EmployeeResponseDto dto = new EmployeeResponseDto();
|
|
|
|
dto.setEmpId(e.getEmpId());
|
|
dto.setEmpUuid(e.getEmpUuid());
|
|
dto.setEmpNo(e.getEmpNo());
|
|
dto.setEmpLoginId(e.getEmpLoginId());
|
|
dto.setEmpFirstName(e.getEmpFirstName());
|
|
dto.setEmpMiddleName(e.getEmpMiddleName());
|
|
dto.setEmpLastName(e.getEmpLastName());
|
|
dto.setEmpPreferredFirstName(e.getEmpPreferredFirstName());
|
|
dto.setEmpPreferredLastName(e.getEmpPreferredLastName());
|
|
dto.setEmpStatus(e.getEmpStatus());
|
|
dto.setEmpFulltime(e.getEmpFulltime());
|
|
dto.setEmpEmploymentType(e.getEmpEmploymentType());
|
|
dto.setEmpLeaveStatus(e.getEmpLeaveStatus());
|
|
dto.setEmpOfferAcceptedDate(e.getEmpOfferAcceptedDate());
|
|
dto.setEmpCreatedAt(e.getEmpCreatedAt());
|
|
dto.setEmpUpdatedAt(e.getEmpUpdatedAt());
|
|
dto.setEmpCreatedBy(e.getEmpCreatedBy());
|
|
dto.setEmpUpdatedBy(e.getEmpUpdatedBy());
|
|
dto.setEmpNationality(e.getEmpNationality());
|
|
dto.setEmpCitizenshipStatus(e.getEmpCitizenshipStatus());
|
|
dto.setEmpPassportNo(e.getEmpPassportNo());
|
|
dto.setEmpPassportCountry(e.getEmpPassportCountry());
|
|
dto.setEmpPassportIssueDate(e.getEmpPassportIssueDate());
|
|
dto.setEmpPassportExpiryDate(e.getEmpPassportExpiryDate());
|
|
dto.setEmpVisaType(e.getEmpVisaType());
|
|
dto.setEmpVisaIssueDate(e.getEmpVisaIssueDate());
|
|
dto.setEmpVisaExpiryDate(e.getEmpVisaExpiryDate());
|
|
dto.setEmpVisaCountry(e.getEmpVisaCountry());
|
|
dto.setEmpDateOfBirth(e.getEmpDateOfBirth());
|
|
dto.setEmpSex(e.getEmpSex());
|
|
dto.setEmpSin(e.getEmpSin());
|
|
dto.setEmpAccountNo(e.getEmpAccountNo());
|
|
dto.setEmpDriverLicenseNo(e.getEmpDriverLicenseNo());
|
|
dto.setEmpPersonalEmail(e.getEmpPersonalEmail());
|
|
dto.setEmpPersonalPhone(e.getEmpPersonalPhone());
|
|
dto.setEmpAddress1(e.getEmpAddress1());
|
|
dto.setEmpAddress2(e.getEmpAddress2());
|
|
dto.setEmpPostalCode(e.getEmpPostalCode());
|
|
dto.setEmpCity(e.getEmpCity());
|
|
dto.setEmpProvince(e.getEmpProvince());
|
|
dto.setEmpContractStartDate(e.getEmpContractStartDate());
|
|
dto.setEmpProbationStartDate(e.getEmpProbationStartDate());
|
|
dto.setEmpProbationEndDate(e.getEmpProbationEndDate());
|
|
dto.setEmpProbationStatus(e.getEmpProbationStatus());
|
|
dto.setEmpJobStartDate(e.getEmpJobStartDate());
|
|
dto.setEmpJobEndDate(e.getEmpJobEndDate());
|
|
dto.setEmpTerminationDate(e.getEmpTerminationDate());
|
|
dto.setEmpTerminationReason(e.getEmpTerminationReason());
|
|
dto.setEmpDeptId(e.getEmpDeptId());
|
|
dto.setEmpRate(e.getEmpRate());
|
|
dto.setEmpRateOt(e.getEmpRateOt());
|
|
dto.setEmpRateDot(e.getEmpRateDot());
|
|
dto.setEmpOfficeEmail(e.getEmpOfficeEmail());
|
|
dto.setEmpOfficeMobile(e.getEmpOfficeMobile());
|
|
dto.setEmpOfficePhone(e.getEmpOfficePhone());
|
|
dto.setEmpExtensionNo(e.getEmpExtensionNo());
|
|
|
|
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);
|
|
}
|
|
}
|