[Authentication]

- 다른 웹서비스 호출을 위해 토큰 저장
[Customer Daily Order]
- 외부 emp id 조회를 위해 hcm-rest-api 연동
[Customer]
- Customer 와 Contact 의 Comment 분리
This commit is contained in:
Hyojin Ahn 2025-12-17 08:28:31 -05:00
parent 06d24c2e6f
commit fab87fe804
13 changed files with 320 additions and 135 deletions

View File

@ -70,7 +70,12 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
// PermissionAuthenticationToken 생성
PermissionAuthenticationToken authToken =
new PermissionAuthenticationToken(loginId, permissionSet, authorities);
new PermissionAuthenticationToken(
loginId,
jwt, // 토큰 저장
permissionSet,
authorities
);
// SecurityContextHolder에 세팅
SecurityContextHolder.getContext().setAuthentication(authToken);

View File

@ -0,0 +1,14 @@
package com.goi.erp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@ -14,41 +14,31 @@ public class CustomerDailyOrderRequestDto {
private LocalDate cdoOrderDate; // 주문 날짜 (YYYY-MM-DD)
private String cdoOrderType; // 주문 타입 ('N' )
private String cdoRequestNote; // 주문 요청 메모
private Long cdoDriverId; // MIS 에서는 driverId 호출해서 employee_external_map 참조해야함
private String cdoExternalDriverId; // MIS 에서 driverId 호출해서 employee_external_map 참조해야함
private Long cdoDriverId; // 배정된 driver id
private UUID cdoDriverUuid; // ERP 에서는 uuid 호출
private Long cdoCustomerId; // 고객 ID
private String cdoCustomerNo;
private UUID cdoCustomerUuid;
private String cdoPaymentType; // 결제 타입
private String cdoCycle; // Cycle (방문 주기)
private BigDecimal cdoRate; // 요율 (리터당 가격 )
private String cdoCreatedBy; // 생성자 ID
private String cdoUpdatedBy; // 수정자 ID
private String cdoStatus; // 상태 ('A', 'F', 'D')
private String cdoVisitFlag; // 방문 여부 Flag
private LocalDateTime cdoInputAt; // 입력 시간
private BigDecimal cdoEstimatedQty; // 예상 수거량
private BigDecimal cdoQuantity; // 실제 수거량
private Integer cdoSludge; // Sludge 여부/수치
private String cdoPayStatus; // 결제 여부 ('N', 'Y')
private BigDecimal cdoPayAmount; // 결제 금액
private String cdoPayeeName; // Payee 이름
private String cdoPayeeSign; // Payee 사인 (이미지 경로 )
private LocalDateTime cdoPickupAt; // 입력 시간
private String cdoPickupNote; // 주문 요청 메모
private BigDecimal cdoPickupLat; // 픽업 위도
private BigDecimal cdoPickupLon; // 픽업 경도
private Integer cdoPickupMin; // 픽업 작업 시간()
private String cdoLoginUser; // 로그인한 User (CreatedBy/UpdatedBy )
}

View File

@ -17,42 +17,30 @@ import java.util.UUID;
public class CustomerDailyOrderResponseDto {
private UUID cdoUuid; // UUID
private LocalDate cdoOrderDate; // YYYYMMDD
private String cdoOrderType; // 주문 타입
private String cdoRequestNote; // 요청 메모
private Long cdoDriverId; // Driver ID
private String cdoCustomerNo; // Customer No
//private Long cdoDriverId; // Driver ID
//private Long cdoCustomerId; //
private String cdoCustomerNo;
private String cdoPaymentType; // 결제 방식
private String cdoCycle; // Cycle
private BigDecimal cdoRate; // 요율
private LocalDateTime cdoCreatedAt; // 생성 시간
private String cdoCreatedBy; // 생성자
private LocalDateTime cdoUpdatedAt; // 수정 시간
private String cdoUpdatedBy; // 수정자
private String cdoStatus; // 상태
private String cdoVisitFlag; // 방문 여부
private LocalDateTime cdoInputAt; // 입력 시간
private BigDecimal cdoEstimatedQty; // 예상 수거량
private BigDecimal cdoQuantity; // 실제 수거량
private Integer cdoSludge; // Sludge
private String cdoPayStatus; // 결제 상태
private BigDecimal cdoPayAmount; // 결제 금액
private String cdoPayeeName; // Payee 이름
private String cdoPayeeSign; // Payee 사인
private LocalDateTime cdoPickupAt; // 입력 시간
private String cdoPickupNote; // 요청 메모
private BigDecimal cdoPickupLat; // 픽업 위도
private BigDecimal cdoPickupLon; // 픽업 경도
private Integer cdoPickupMin; // 픽업 시간()

View File

@ -24,28 +24,22 @@ public class CustomerRequestDto {
private String cusEmail; // c_email
private String cusPhone; // c_phone
private String cusPhoneExt; // c_phoneext
private LocalDate cusContractDate; // c_contractdate
private String cusContractedBy; // c_contractby
private LocalDate cusInstallDate; // c_installdate
private BigDecimal cusFullCycle; // c_fullcycle
private Boolean cusFullCycleFlag; // c_fullcycleflag
private BigDecimal cusFullCycleForced; // c_fullcycleforced
private LocalDate cusFullCycleForcedDate; // c_forceddate
private String cusSchedule; // c_schedule
private String cusScheduledays; // c_scheduleday
private LocalDate cusLastPaidDate; // c_lastpaiddate
private Double cusRate; // c_rate
private String cusPayMethod; // c_paymenttype
private String cusAccountNo; // c_accountno
private LocalDate cusIsccDate; // c_form_eu
private LocalDate cusCorsiaDate; // c_form_corsia
private String cusHstNo; // c_hstno
private LocalDate cusTerminatedDate;
private String cusTerminationReason;
private String cusInstallLocation;
@ -53,12 +47,10 @@ public class CustomerRequestDto {
private Integer cusLastPickupQty;
private Double cusLastPickupLat;
private Double cusLastPickupLon;
private String cusOpenTime;
private String cusComment;
private String cusComment; // c_comment_ri
private String cusContactComment; // c_comment_ci
private Integer cusLastPickupMin;
private String cusLoginUser;
}

View File

@ -53,4 +53,5 @@ public class CustomerResponseDto {
private Integer cusLastPickupMin;
private String cusOpenTime;
private String cusComment;
private String cusContactComment;
}

View File

@ -45,54 +45,42 @@ public class Customer {
@Column(length = 1)
private String cusStatus;
private Long cusAreaId;
private String cusAddress1;
private String cusAddress2;
private String cusPostalCode;
private String cusCity;
private String cusProvince;
private BigDecimal cusGeoLat;
private BigDecimal cusGeoLon;
private String cusEmail;
private String cusPhone;
private String cusPhoneExt;
private String cusOpenTime;
private String cusComment;
private String cusContactComment;
private LocalDate cusContractDate;
private String cusContractedBy;
private LocalDate cusInstallDate;
private String cusInstallLocation;
private LocalDate cusLastPickupDate;
private Integer cusLastPickupQty;
private BigDecimal cusLastPickupLat;
private BigDecimal cusLastPickupLon;
private BigDecimal cusFullCycle;
private Boolean cusFullCycleFlag;
private BigDecimal cusFullCycleForced;
private LocalDate cusFullCycleForcedDate;
private String cusSchedule;
private String cusScheduledays;
private LocalDate cusLastPaidDate;
private BigDecimal cusRate;
private String cusPayMethod;
private String cusAccountNo;
private LocalDate cusIsccDate;
private LocalDate cusCorsiaDate;
private String cusHstNo;
private LocalDate cusTerminatedDate;
private String cusTerminationReason;
private Integer cusLastPickupMin;

View File

@ -76,7 +76,9 @@ public class CustomerDailyOrder {
@Column(length = 1)
private String cdoVisitFlag;
private LocalDateTime cdoInputAt;
private LocalDateTime cdoPickupAt;
private String cdoPickupNote;
private BigDecimal cdoEstimatedQty;

View File

@ -4,6 +4,7 @@ import com.goi.erp.dto.CustomerDailyOrderRequestDto;
import com.goi.erp.dto.CustomerDailyOrderResponseDto;
import com.goi.erp.entity.CustomerDailyOrder;
import com.goi.erp.repository.CustomerDailyOrderRepository;
import com.goi.erp.repository.CustomerRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
@ -22,42 +23,43 @@ import java.util.UUID;
public class CustomerDailyOrderService {
private final CustomerDailyOrderRepository dailyOrderRepository;
private final CustomerRepository customerRepository;
private final HcmEmployeeClient hcmEmployeeClient;
/**
* CREATE
*/
public CustomerDailyOrderResponseDto createDailyOrder(CustomerDailyOrderRequestDto dto) {
// customer id
Long customerId = resolveCustomerId(dto);
// driver id (employee id)
Long driverId = resolveDriverId(dto);
CustomerDailyOrder order = CustomerDailyOrder.builder()
.cdoUuid(UUID.randomUUID())
.cdoOrderDate(dto.getCdoOrderDate())
.cdoOrderType(dto.getCdoOrderType())
.cdoRequestNote(dto.getCdoRequestNote())
.cdoDriverId(dto.getCdoDriverId())
.cdoDriverId(driverId)
.cdoCustomerId(customerId)
.cdoCustomerNo(dto.getCdoCustomerNo())
.cdoPaymentType(dto.getCdoPaymentType())
.cdoCycle(dto.getCdoCycle())
.cdoRate(dto.getCdoRate())
.cdoCreatedAt(LocalDateTime.now())
.cdoCreatedBy(dto.getCdoLoginUser())
.cdoStatus(dto.getCdoStatus())
.cdoVisitFlag(dto.getCdoVisitFlag())
.cdoInputAt(dto.getCdoInputAt())
.cdoEstimatedQty(dto.getCdoEstimatedQty())
.cdoQuantity(dto.getCdoQuantity())
.cdoSludge(dto.getCdoSludge())
.cdoPayStatus(dto.getCdoPayStatus())
.cdoPayAmount(dto.getCdoPayAmount())
.cdoPayeeName(dto.getCdoPayeeName())
.cdoPayeeSign(dto.getCdoPayeeSign())
.cdoPickupAt(dto.getCdoPickupAt())
.cdoPickupNote(dto.getCdoPickupNote())
.cdoPickupLat(dto.getCdoPickupLat())
.cdoPickupLon(dto.getCdoPickupLon())
.cdoPickupMin(dto.getCdoPickupMin())
@ -116,10 +118,6 @@ public class CustomerDailyOrderService {
// 기존 updateInternal 공통 업데이트 처리
updateInternal(existing, dto);
// audit field 업데이트
existing.setCdoUpdatedAt(LocalDateTime.now());
existing.setCdoUpdatedBy(dto.getCdoLoginUser());
// 저장
dailyOrderRepository.save(existing);
@ -160,37 +158,30 @@ public class CustomerDailyOrderService {
* Internal Update Logic (CustomerService 동일 스타일)
*/
private void updateInternal(CustomerDailyOrder order, CustomerDailyOrderRequestDto dto) {
if (dto.getCdoOrderDate() != null) order.setCdoOrderDate(dto.getCdoOrderDate());
if (dto.getCdoOrderType() != null) order.setCdoOrderType(dto.getCdoOrderType());
if (dto.getCdoRequestNote() != null) order.setCdoRequestNote(dto.getCdoRequestNote());
if (dto.getCdoDriverId() != null) order.setCdoDriverId(dto.getCdoDriverId());
if (dto.getCdoCustomerNo() != null) order.setCdoCustomerNo(dto.getCdoCustomerNo());
if (dto.getCdoPaymentType() != null) order.setCdoPaymentType(dto.getCdoPaymentType());
if (dto.getCdoCycle() != null) order.setCdoCycle(dto.getCdoCycle());
if (dto.getCdoRate() != null) order.setCdoRate(dto.getCdoRate());
if (dto.getCdoStatus() != null) order.setCdoStatus(dto.getCdoStatus());
if (dto.getCdoVisitFlag() != null) order.setCdoVisitFlag(dto.getCdoVisitFlag());
if (dto.getCdoInputAt() != null) order.setCdoInputAt(dto.getCdoInputAt());
if (dto.getCdoEstimatedQty() != null) order.setCdoEstimatedQty(dto.getCdoEstimatedQty());
if (dto.getCdoQuantity() != null) order.setCdoQuantity(dto.getCdoQuantity());
if (dto.getCdoSludge() != null) order.setCdoSludge(dto.getCdoSludge());
if (dto.getCdoPayStatus() != null) order.setCdoPayStatus(dto.getCdoPayStatus());
if (dto.getCdoPayAmount() != null) order.setCdoPayAmount(dto.getCdoPayAmount());
if (dto.getCdoPayeeName() != null) order.setCdoPayeeName(dto.getCdoPayeeName());
if (dto.getCdoPayeeSign() != null) order.setCdoPayeeSign(dto.getCdoPayeeSign());
if (dto.getCdoPickupLat() != null) order.setCdoPickupLat(dto.getCdoPickupLat());
if (dto.getCdoPickupLon() != null) order.setCdoPickupLon(dto.getCdoPickupLon());
if (dto.getCdoPickupMin() != null) order.setCdoPickupMin(dto.getCdoPickupMin());
// driver id (employee id)
Long driverId = resolveDriverId(dto);
// null 아닌 경우만 업데이트
if (dto.getCdoOrderType() != null) order.setCdoOrderType(dto.getCdoOrderType());
if (dto.getCdoRequestNote() != null) order.setCdoRequestNote(dto.getCdoRequestNote());
if (dto.getCdoDriverId() != null || dto.getCdoExternalDriverId() != null || dto.getCdoDriverUuid() != null) order.setCdoDriverId(driverId);
if (dto.getCdoPaymentType() != null) order.setCdoPaymentType(dto.getCdoPaymentType());
if (dto.getCdoCycle() != null) order.setCdoCycle(dto.getCdoCycle());
if (dto.getCdoRate() != null) order.setCdoRate(dto.getCdoRate());
if (dto.getCdoStatus() != null) order.setCdoStatus(dto.getCdoStatus());
if (dto.getCdoVisitFlag() != null) order.setCdoVisitFlag(dto.getCdoVisitFlag());
if (dto.getCdoEstimatedQty()!= null) order.setCdoEstimatedQty(dto.getCdoEstimatedQty());
if (dto.getCdoQuantity() != null) order.setCdoQuantity(dto.getCdoQuantity());
if (dto.getCdoSludge() != null) order.setCdoSludge(dto.getCdoSludge());
if (dto.getCdoPayStatus() != null) order.setCdoPayStatus(dto.getCdoPayStatus());
if (dto.getCdoPayAmount() != null) order.setCdoPayAmount(dto.getCdoPayAmount());
if (dto.getCdoPayeeName() != null) order.setCdoPayeeName(dto.getCdoPayeeName());
if (dto.getCdoPayeeSign() != null) order.setCdoPayeeSign(dto.getCdoPayeeSign());
if (dto.getCdoPickupAt() != null) order.setCdoPickupAt(dto.getCdoPickupAt());
if (dto.getCdoPickupNote() != null) order.setCdoPickupNote(dto.getCdoPickupNote());
if (dto.getCdoPickupLat() != null) order.setCdoPickupLat(dto.getCdoPickupLat());
if (dto.getCdoPickupLon() != null) order.setCdoPickupLon(dto.getCdoPickupLon());
if (dto.getCdoPickupMin() != null) order.setCdoPickupMin(dto.getCdoPickupMin());
}
@ -205,38 +196,75 @@ public class CustomerDailyOrderService {
.cdoUuid(order.getCdoUuid())
.cdoOrderDate(order.getCdoOrderDate())
.cdoOrderType(order.getCdoOrderType())
.cdoRequestNote(order.getCdoRequestNote())
.cdoDriverId(order.getCdoDriverId())
// .cdoDriverId(order.getCdoDriverId())
.cdoCustomerNo(order.getCdoCustomerNo())
.cdoPaymentType(order.getCdoPaymentType())
.cdoCycle(order.getCdoCycle())
.cdoRate(order.getCdoRate())
.cdoCreatedAt(order.getCdoCreatedAt())
.cdoCreatedBy(order.getCdoCreatedBy())
.cdoUpdatedAt(order.getCdoUpdatedAt())
.cdoUpdatedBy(order.getCdoUpdatedBy())
.cdoStatus(order.getCdoStatus())
.cdoVisitFlag(order.getCdoVisitFlag())
.cdoInputAt(order.getCdoInputAt())
.cdoEstimatedQty(order.getCdoEstimatedQty())
.cdoQuantity(order.getCdoQuantity())
.cdoSludge(order.getCdoSludge())
.cdoPayStatus(order.getCdoPayStatus())
.cdoPayAmount(order.getCdoPayAmount())
.cdoPayeeName(order.getCdoPayeeName())
.cdoPayeeSign(order.getCdoPayeeSign())
.cdoPickupAt(order.getCdoPickupAt())
.cdoPickupNote(order.getCdoPickupNote())
.cdoPickupLat(order.getCdoPickupLat())
.cdoPickupLon(order.getCdoPickupLon())
.cdoPickupMin(order.getCdoPickupMin())
.build();
}
private Long resolveCustomerId(CustomerDailyOrderRequestDto dto) {
// 1. ERP customerId 직접 전달
if (dto.getCdoCustomerId() != null) {
return dto.getCdoCustomerId();
}
// 2. ERP customerUuid 전달
if (dto.getCdoCustomerUuid() != null) {
return customerRepository.findByCusUuid(dto.getCdoCustomerUuid())
.map(c -> c.getCusId())
.orElseThrow(() -> new RuntimeException("Customer not found by UUID"));
}
// 3. MIS customerNo만 있을
if (dto.getCdoCustomerNo() != null) {
return customerRepository.findByCusNo(dto.getCdoCustomerNo())
.map(c -> c.getCusId())
.orElseThrow(() -> new RuntimeException("Customer not found by customerNo"));
}
return null; // 또는 throw
}
private Long resolveDriverId(CustomerDailyOrderRequestDto dto) {
// 1. driver id
if (dto.getCdoDriverId() != null) {
return dto.getCdoDriverId();
}
// 2. MIS -> externalId (문자열 email or id)
if (dto.getCdoExternalDriverId() != null) {
return hcmEmployeeClient.getEmpIdFromExternalId( dto.getCdoExternalDriverId() );
}
// 3. ERP 내부 요청 (driverUuid 방식)
if (dto.getCdoDriverUuid() != null) {
return hcmEmployeeClient.getEmpIdFromUuid(dto.getCdoDriverUuid());
}
return null;
}
}

View File

@ -21,7 +21,6 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
@Service
@ -37,7 +36,6 @@ public class CustomerService {
.cusNo(dto.getCusNo())
.cusName(dto.getCusName())
.cusStatus(dto.getCusStatus())
.cusAreaId(dto.getCusAreaId())
.cusAddress1(dto.getCusAddress1())
.cusAddress2(dto.getCusAddress2())
@ -49,30 +47,25 @@ public class CustomerService {
.cusEmail(dto.getCusEmail())
.cusPhone(dto.getCusPhone())
.cusPhoneExt(dto.getCusPhoneExt())
.cusContractDate(dto.getCusContractDate())
.cusContractedBy(dto.getCusContractedBy())
.cusInstallDate(dto.getCusInstallDate())
.cusFullCycle(dto.getCusFullCycle())
.cusFullCycleFlag(dto.getCusFullCycleFlag())
.cusFullCycleForced(dto.getCusFullCycleForced())
.cusFullCycleForcedDate(dto.getCusFullCycleForcedDate())
.cusSchedule(dto.getCusSchedule())
.cusScheduledays(dto.getCusScheduledays())
.cusLastPaidDate(dto.getCusLastPaidDate())
.cusRate(dto.getCusRate() != null ? BigDecimal.valueOf(dto.getCusRate()) : null)
.cusPayMethod(dto.getCusPayMethod())
.cusAccountNo(dto.getCusAccountNo())
.cusIsccDate(dto.getCusIsccDate())
.cusCorsiaDate(dto.getCusCorsiaDate())
.cusHstNo(dto.getCusHstNo())
.cusOpenTime(dto.getCusOpenTime())
.cusComment(dto.getCusComment())
.cusContactComment(dto.getCusContactComment())
.cusInstallLocation(dto.getCusInstallLocation())
.build();
@ -115,8 +108,8 @@ public class CustomerService {
if (dto.getCusPostalCode() != null) customer.setCusPostalCode(dto.getCusPostalCode());
if (dto.getCusCity() != null) customer.setCusCity(dto.getCusCity());
if (dto.getCusProvince() != null) customer.setCusProvince(dto.getCusProvince());
customer.setCusGeoLat(dto.getCusGeoLat() != null ? BigDecimal.valueOf(dto.getCusGeoLat()) : null);
customer.setCusGeoLon(dto.getCusGeoLon() != null ? BigDecimal.valueOf(dto.getCusGeoLon()) : null);
if (dto.getCusGeoLat() != null) customer.setCusGeoLat(BigDecimal.valueOf(dto.getCusGeoLat()));
if (dto.getCusGeoLon() != null) customer.setCusGeoLon(BigDecimal.valueOf(dto.getCusGeoLon()));
if (dto.getCusEmail() != null) customer.setCusEmail(dto.getCusEmail());
if (dto.getCusPhone() != null) customer.setCusPhone(dto.getCusPhone());
if (dto.getCusPhoneExt() != null) customer.setCusPhoneExt(dto.getCusPhoneExt());
@ -130,7 +123,7 @@ public class CustomerService {
if (dto.getCusSchedule() != null) customer.setCusSchedule(dto.getCusSchedule());
if (dto.getCusScheduledays() != null) customer.setCusScheduledays(dto.getCusScheduledays());
if (dto.getCusLastPaidDate() != null) customer.setCusLastPaidDate(dto.getCusLastPaidDate());
customer.setCusRate(dto.getCusRate() != null ? BigDecimal.valueOf(dto.getCusRate()) : null);
if (dto.getCusRate() != null) customer.setCusRate(BigDecimal.valueOf(dto.getCusRate()));
if (dto.getCusPayMethod() != null) customer.setCusPayMethod(dto.getCusPayMethod());
if (dto.getCusIsccDate() != null) customer.setCusIsccDate(dto.getCusIsccDate());
if (dto.getCusCorsiaDate() != null) customer.setCusCorsiaDate(dto.getCusCorsiaDate());
@ -139,10 +132,11 @@ public class CustomerService {
if (dto.getCusTerminationReason() != null) customer.setCusTerminationReason(dto.getCusTerminationReason());
if (dto.getCusLastPickupDate() != null) customer.setCusLastPickupDate(dto.getCusLastPickupDate());
if (dto.getCusLastPickupQty() != null) customer.setCusLastPickupQty(dto.getCusLastPickupQty());
customer.setCusLastPickupLat(dto.getCusLastPickupLat() != null ? BigDecimal.valueOf(dto.getCusLastPickupLat()) : null);
customer.setCusLastPickupLon(dto.getCusLastPickupLon() != null ? BigDecimal.valueOf(dto.getCusLastPickupLon()) : null);
if (dto.getCusLastPickupLat() != null) customer.setCusLastPickupLat(BigDecimal.valueOf(dto.getCusLastPickupLat()));
if (dto.getCusLastPickupLon() != null) customer.setCusLastPickupLon(BigDecimal.valueOf(dto.getCusLastPickupLon()));
if (dto.getCusOpenTime() != null) customer.setCusOpenTime(dto.getCusOpenTime());
if (dto.getCusComment() != null) customer.setCusComment(dto.getCusComment());
if (dto.getCusContactComment() != null) customer.setCusContactComment(dto.getCusContactComment());
if (dto.getCusInstallLocation() != null) customer.setCusInstallLocation(dto.getCusInstallLocation());
customerRepository.save(customer);
@ -193,6 +187,7 @@ public class CustomerService {
dto.setCusLastPickupMin(customer.getCusLastPickupMin());
dto.setCusOpenTime(customer.getCusOpenTime());
dto.setCusComment(customer.getCusComment());
dto.setCusContactComment(customer.getCusContactComment());
dto.setCusInstallLocation(customer.getCusInstallLocation());
return dto;
@ -269,6 +264,7 @@ public class CustomerService {
Map.entry("cusHstNo", "cus_hst_no"),
Map.entry("cusOpenTime", "cus_open_time"),
Map.entry("cusComment", "cus_comment"),
Map.entry("cusContactComment", "cus_contact_comment"),
Map.entry("cusInstallLocation", "cus_install_location")
);
@ -285,7 +281,7 @@ public class CustomerService {
Object oldVal = field.get(oldData);
Object newVal = field.get(newData);
if (!Objects.equals(oldVal, newVal)) {
if (valuesAreDifferent(oldVal, newVal)) {
entityChangeLogRepository.save(
EntityChangeLog.builder()
.eclEntityType("Customer")
@ -306,5 +302,38 @@ public class CustomerService {
}
}
}
private boolean valuesAreDifferent(Object oldVal, Object newVal) {
// null 변경 없음
if (oldVal == null && newVal == null) return false;
// 한쪽만 null 변경됨
if (oldVal == null || newVal == null) return true;
// BigDecimal (numeric 비교)
if (oldVal instanceof BigDecimal oldNum && newVal instanceof BigDecimal newNum) {
return oldNum.compareTo(newNum) != 0; // scale 무시 비교
}
// 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);
}
// (String 포함) 기본 equals 비교
return !oldVal.equals(newVal);
}
}

View File

@ -0,0 +1,124 @@
package com.goi.erp.service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.goi.erp.token.PermissionAuthenticationToken;
import java.util.Map;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class HcmEmployeeClient {
private final RestTemplate restTemplate;
@Value("${hcm.api.base-url}")
private String hcmBaseUrl;
public Long getEmpIdFromExternalId(String externalId) {
String url = hcmBaseUrl + "/employee/external" + "?solutionType=MIS&externalId=" + externalId;
try {
// set token in header
String jwt = getCurrentJwt();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + jwt);
HttpEntity<Void> entity = new HttpEntity<>(headers);
// GET
ResponseEntity<Map<String, Object>> response =
restTemplate.exchange(
url,
HttpMethod.GET,
entity,
new ParameterizedTypeReference<Map<String, Object>>() {}
);
Map<String, Object> body = response.getBody();
//System.out.println("RESPONSE ➜ " + body);
if (body != null && body.get("eexEmpId") != null) {
Object raw = body.get("eexEmpId");
if (raw instanceof Number) {
return ((Number) raw).longValue(); // 🔥 모든 숫자를 Long 변환
}
// 예상 타입일 경우
}
return null;
} catch (Exception e) {
// 필요하면 logging
System.out.println("externalId lookup error: " + e.getMessage());
return null;
}
}
public Long getEmpIdFromUuid(UUID uuid) {
String url = hcmBaseUrl + "/employee/" + uuid;
try {
// set token in header
String jwt = getCurrentJwt();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + jwt);
HttpEntity<Void> entity = new HttpEntity<>(headers);
// GET
ResponseEntity<Map<String, Object>> response =
restTemplate.exchange(
url,
HttpMethod.GET,
entity,
new ParameterizedTypeReference<Map<String, Object>>() {}
);
Map<String, Object> body = response.getBody();
//System.out.println("RESPONSE(UUID) ➜ " + body);
if (body != null && body.get("empId") != null) {
Object raw = body.get("empId");
if (raw instanceof Number) {
return ((Number) raw).longValue(); // 🔥 모든 숫자를 Long 변환
}
// 예상 타입일 경우
}
return null;
} catch (Exception e) {
// 필요하면 로깅
System.out.println("UUID lookup error: " + e.getMessage());
return null;
}
}
private String getCurrentJwt() {
var auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof PermissionAuthenticationToken token) {
return token.getJwt();
}
return null;
}
}

View File

@ -8,16 +8,33 @@ import org.springframework.security.core.GrantedAuthority;
import com.goi.erp.common.permission.PermissionSet;
public class PermissionAuthenticationToken extends UsernamePasswordAuthenticationToken {
private static final long serialVersionUID = 1L;
private final PermissionSet permissionSet;
private static final long serialVersionUID = 1L;
public PermissionAuthenticationToken(String principal, PermissionSet permissionSet, Collection<? extends GrantedAuthority> authorities) {
super(principal, null, authorities);
private final PermissionSet permissionSet;
private final String jwt; // JWT 저장
/**
* @param principal 로그인 ID 또는 emp_uuid
* @param jwt 실제 JWT 토큰 문자열
* @param permissionSet 권한 정보
* @param authorities Spring Security Authority
*/
public PermissionAuthenticationToken(
String principal,
String jwt,
PermissionSet permissionSet,
Collection<? extends GrantedAuthority> authorities
) {
super(principal, jwt, authorities); // credentials jwt 넣어줌
this.permissionSet = permissionSet;
this.jwt = jwt; // 여기 저장
}
public PermissionSet getPermissionSet() {
return permissionSet;
}
}
public String getJwt() {
return jwt;
}
}

View File

@ -29,4 +29,11 @@ pagination:
server:
port: 8082
servlet:
context-path: /crm-rest-api
context-path: /crm-rest-api
# ================================
# ADD THIS
# ================================
hcm:
api:
base-url: http://localhost:8081/hcm-rest-api