그룹 웨어 - 휴가 관리(3)

김채영·2024년 11월 25일

휴가관리

목록 보기
3/4

1년 미만 월차 지급 스케줄링 조건

  • 1년 미만 재직자와 1년 이상 재직자를 구분
  • 1년 미만 재직자에게 매일 월차 지급 날짜 확인 후, 한 달 초과 시 +1
  • 만약 처음 지급일 경우, 입사일 기준 한 달 후에 +1하고 지급 날짜 업데이트
  • 이후 업데이트 날짜 기준으로 한 달 초과 +1 하도록 조건

1년 미만 월차 지급

if (vacationService.countCheckOneYear() == 1) {
    List<MemberDto> underOneYearMembers = memberService.selectUnderYearMember(1);
    for (MemberDto dto : underOneYearMembers) {
        // 휴가일이 설정되지 않은 경우
        if (dto.getMember_vacation_date() == null || dto.getMember_vacation_date().isEmpty()) {
            if (firstVacation(dto.getMember_hire_date())) {
                double monthDif = (double) Period.between(LocalDate.parse(dto.getMember_hire_date()), LocalDate.now()).toTotalMonths();
                vacationService.incrementVacation(dto.getMember_no(), monthDif);
            }
        } 
        // 휴가일이 설정된 경우
        else {
            if (monthVacation(dto.getMember_vacation_date())) {
                vacationService.incrementVacation(dto.getMember_no(), 1.0);
            }
        }
    }
}

//입사 후 처음 지급 받는 경우
private boolean firstVacation(String joiningDate) {
    try {
        LocalDate joinDate = LocalDate.parse(joiningDate);
        return Period.between(joinDate, LocalDate.now()).toTotalMonths() >= 1;
    } catch (DateTimeParseException e) {
        // 날짜 파싱 실패 시 예외 처리
        return false;
    }
}

//마지막 휴가 지급일 기준으로 한 달 경과
private boolean monthVacation(String lastVacationDateStr) {
    try {
        if (lastVacationDateStr == null || lastVacationDateStr.isEmpty()) {
            return false;
        }
        LocalDate lastVacationDate = LocalDate.parse(lastVacationDateStr);
        return Period.between(lastVacationDate, LocalDate.now()).toTotalMonths() >= 1;
    } catch (DateTimeParseException e) {
        // 날짜 파싱 실패 시 예외 처리
        return false;
    }
}
  • 반복문 안에 있는 조건을 통해 처음 월차를 지급 받는지와 다음 월차를 지급 받는지 구분하여 처리
  • 입사일 기준으로 한 달 초과하면 그 값을 서비스 로직을 통해 디비에 저장
  • 기존 지급한 이력이 있는 경우, +1 하도록 구성
  • 처음 지급 받는 것도 +1로 구성하여도 좋지만, 테스트 때 멤버 테이블에 입사일을 임의로 지정하고 테스트했기에 차이 값으로 구현

연차별 휴가 개수 지급 조건

  • 지정일 기준인지, 입사일 기준인지에 대해 다르게 구성
  • 연차별로 지정한 휴가 개수를 해당 사원 입사일 기준으로 측정하여 지급

연차별 휴가 개수

if (vacationService.countCheckOneYear() == 1 || vacationService.countCheckOneYear() == 0) {
    List<MemberDto> overOneYearMembers = memberService.selectUnderYearMember(0);
    for (MemberDto dto : overOneYearMembers) {
        String vacationDate = vacationService.selectVacationDesignated(1); // 지정일 조회
        int vacationStandardStatus = vacationService.selectVacationStandardStatus();
        String referenceDate = (vacationDate != null) ? vacationDate : dto.getMember_hire_date();

        if (resetDate(referenceDate, vacationStandardStatus)) {
            int yearSinceJoin = Period.between(LocalDate.parse(dto.getMember_hire_date()), LocalDate.now()).getYears();
            double vacationDay = getVacationDaysByYears(yearSinceJoin);
            vacationService.resetVacation(dto.getMember_no(), vacationDay);
        }
    }
}

// 기준일에 맞춰서 휴가 리셋 시점 확인
private boolean resetDate(String referenceDate, int status) {
	try {
    	LocalDate refDate = LocalDate.parse(referenceDate);

        if (status == 1) {
        	// 지정일 기준
        	return LocalDate.now().isEqual(refDate) || LocalDate.now().isAfter(refDate);
        } else if (status == 0) {
        	// 입사일 기준
            return LocalDate.now().isEqual(refDate) || LocalDate.now().isAfter(refDate);
        }

        return false;


	} catch (DateTimeParseException e) {
    	return false;
    }
}

// 연차에 따른 휴가 개수 반환
private int getVacationDaysByYears(int years) {
	// 휴가 일수 저장된 테이블에서 연차에 따른 휴가 개수 조회
    int count = vacationService.contVacationYear(years);
    return count;
}
  • 1년 이상 사원의 리스트를 가져옴
  • 지정일이 있는지 확인하고 없다면 입사일 기준으로 설정
  • 휴가 초기화 조건을 확인
  • 근속 연수에 따라 연차별 휴가 개수를 가져와서 지급

트러블 슈팅

  • 기본적으로 스케줄링이 여러 개 사용되어야 하고, 조건에 따라 다른 값들을 입력해야 하기 때문에 조건 분리에 대한 오류가 많았음
  • 하나씩 플로우 차트도 그리고 값을 넣어서 테스트를 해봄
  • 큰 조건 먼저 나누고 그 조건 안에 세부 조건을 나누는 식이 접근도 편하고 구현도 편했음
  • 특히 입사일 기준과 지정일 기준에 대한 조건은 상태값을 통해 분리하기 위해 서비스 들렸다 가져와야 하는 구성이 어려웠음
  • 이야기를 작성하듯이 코드를 구현하여 해결
profile
백엔드 개발⭐

0개의 댓글