diff --git a/src/main/java/com/goi/erp/service/EmployeeService.java b/src/main/java/com/goi/erp/service/EmployeeService.java index 090d058..525ced7 100644 --- a/src/main/java/com/goi/erp/service/EmployeeService.java +++ b/src/main/java/com/goi/erp/service/EmployeeService.java @@ -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")); - + + // 기존 값 복사본 생성 + Employee beforeUpdate = new Employee(); + BeanUtils.copyProperties(oldEmployee, beforeUpdate); + // 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()); + 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(employee); + return mapToDto(oldEmployee); } @@ -275,4 +291,125 @@ public class EmployeeService { return dto; } + + private void compareAndLogChanges(Employee oldData, Employee newData, String changedBy) { + + Map 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); + } }