정산 관련 논의 내용

  1. 출근을 눌렀을 때, 정산 테이블의 값을 생성한다. time_record : 출퇴근기록 테이블

    회원아이디(user_id) time_record.user_id
    날짜(date) time_record.date
    근무시작시간(start_time) time_record.start_work
    근무종료시간(end_time) null
    소정근로시간(working_time) 00:00
    초과근무시간(overtime) 00:00
    근무/유급/무급(day_type) null
    생성일자(date_created) now()
    수정일자(date_updated) now()
    근로제 이력 아이디(work_group_id) 1
  2. 근로제 변경을 하는 경우, 언제 적용할 지 팝업창을 띄운다. 정산에 당일/다음날 을 결정해서 정산목록의 근로제 이력 아이디에도 업데이트를 한다.(당일 적용한다고 결정한 경우)


정산 프로세스

⚠️ 하나의 번호에 적어놓은 프로세스들은 하나의 메서드안에서 실행됩니다.

  1. 근로제 테이블에서 회사 id 별로 오름 차순으로 정렬하고, 그 뒤 근로제 id 별로 오름 차순으로 정렬한 뒤, SettlementSearchDto의 List형태로 각각의 id를 저장합니다. request : X response : List<SettlementSearchDto> (회사 id , 근로제 id)

  2. 1번에서 찾은 List의 원소들을 하나하나 가져옵니다.(회사 id, 근로제 id) 배포 테이블에서 반복문으로 가져온 근로제 id와 일치하는 회원 id들을 찾습니다. 정산테이블에서 정산하려는 날짜 date에 해당 회원 id가 없으면 3번 로직으로, 있으면 4번 로직으로 갑니다. (정산하려는 date는 현재 날짜를 기준으로 하루전, 이틀전 입니다.) request : date, List<SettlementSearchDto> response : date, 회원 id

  3. 회원 id가 없으면 date의 회원의 근로제를 확인하고 “근무”상태이면 출퇴근 기록에 회원의 현재 상태를 insert하고 근태이상으로 정산에 insert 합니다. request : date response : SettlementResponse

  4. 회원 id가 있으면 우선 해당 date의 회원 id를 가지는 출퇴근 기록에서 근무상태가 미처리인 회원을 찾고 해당 정산 id에 매칭되는 근로제 이력 id를 보고 근무, 유급, 무급 여부를 판단합니다. request : date, 회원 id response : 근무/유급/무급, date, 근로제 이력 id

  5. 무급일때, 즉시 정산 테이블에서 해당 정보를 삭제합니다. request : 무급, date

  6. 유급일때, 해당되는 date, 회원 id의 출퇴근 기록을 보고 근무시작시간 = 실제출근시간 근무종료시간 = 실제퇴근시간 소정근로 = 00:00 초과근무 = 실제퇴근시간 - 실제출근시간 day_type = 유급 수정일자 = now()로 Update를 합니다. request : 유급, date response : SettlementResponse

  7. 근무일때, 해당되는 date, 회원 id의 출퇴근 기록과 근로제 이력 id를 부릅니다. 근로제 이력에서 work_group_type을 확인하고 일반,시차 여부를 확인합니다. request : 근무, date, 근로제 이력 id, 회원 id response : SettlementResponse

  8. 출퇴근 인정시간 계산 로직

근로제 이력에서 time_range_type을 참고해서 “근무”인 index값을 찾습니다. index의 갯수가 1개면 반복문을 돌면서 start[index]와 실제 출근 시간(start_work)를 비교합니다. start_work ≤ start[index]면 정산의 start_time을 start[index]로 넣습니다. start_work > start[index]면 정산의 start_time을 start_work로 넣고, 출퇴근기록의 work_state를 근태이상으로 바꿉니다.

index의 갯수가 1개 이상이면 모든 start[index] 중에 제일 큰 값과 제일 작은 값을 찾고 해당 index(maxIndex, minIndex)도 찾습니다. 반복문을 돌면서 start[index]와 실제 출근 시간(start_work)를 비교합니다.

  1. start_work ≤ start[minIndex] ⇒ 정산의 start_time을 start[minIndex]로 넣습니다. end_time에는 end[minIndex]를 넣습니다.
  2. start[minIndex] < start_work ≤ start[maxIndex] ⇒ 정산의 start_time을 start_work로 넣습니다.
  3. start[maxIndex] < start_work ⇒ 정산의 start_time을 제일 큰 값으로 넣고 출퇴근기록의 work_state를 근태이상으로 업데이트 합니다.

leave_work가 null일때, 해당 date가 현재랑 이틀 차이면 workState를 근태이상, 소정근로, 초과근무 모두 00:00으로 만든 뒤 정산을 마칩니다. null이 아니면 end_time에 leave_work를 넣습니다.

소정 근로시간 계산 로직

근로제 이력에서 time_range_type을 참고해서 “휴게”인 index값들을 찾습니다. start_time ≤ start[index] && end_time ≥ end[index]인 조건에 만족하면 그때, end[index] - start[index]를 임의의 합 변수 sum에 더해줍니다.

start_time > start[index] && end_time ≥ end[index]일땐, end[index] - start_time을 임의의 합 변수 sum에 더해줍니다.

start_time ≤ start[index] && end_time < end[index]일떈, end_time - start[index]를 임의의 합 변수 sum에 더해줍니다.

working_time의 end_time - start_time이 end[0] - start[0]보다 작을 경우, working_time에 end_time - start_time - sum을 넣어주고 work_state를 근태이상으로 기록합니다.

working_time의 end_time - start_time이 end[0] - start[0]보다 크거나 같을 경우, → 1번 사례 (end_time - start_time) - (end[0] - start[0])만큼 differ이라는 변수에 저장하고 working_time에 end[0] - start[0] - sum을 넣어주고 work_state를 정상처리로 기록하고 초과 근무 시간을 계산하는 로직으로 이어집니다.

#초과 근무 시간 계산 로직 (1번 사례 인 경우에만 실행됩니다.) 근로제 이력의 time_range_type를 참고해서 “승인”인 index값들을 찾습니다. start[index] ≤ end_time ≤ end[index]일 경우, overtime에 differ의 값을 넣어줍니다.

end[index] < end_time일 경우, overtime에 end[index] - start_time - working_time의 값을 넣어줍니다.

end_time < start[index] 일 경우, overtime에 00:00을 넣어줍니다.