package com.github.kazuki43zoo.domain.model.timecard;
import com.github.kazuki43zoo.domain.model.calendar.Holiday;
import org.joda.time.*;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
@lombok.AllArgsConstructor
@lombok.NoArgsConstructor
@lombok.Data
public class DailyAttendance implements Serializable {
private static final LocalDate BASE_DATE = new LocalDate(0);
private static final long serialVersionUID = 1L;
private String accountUuid;
private LocalDate targetDate;
private LocalTime beginTime;
private LocalTime finishTime;
private boolean paidLeave;
private String specialWorkCode;
private String note;
private WorkPlace workPlace;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private int actualWorkingMinute;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private int compensationMinute;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private int midnightWorkingMinute;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private boolean tardyOrEarlyLeaving;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private boolean absence;
@lombok.Setter(lombok.AccessLevel.NONE)
transient private boolean holiday;
public void calculate(final WorkPlace defaultWorkPlace, final WorkPlace mainOffice) {
Map<LocalDate, Holiday> holidays = Collections.emptyMap();
calculate(defaultWorkPlace, mainOffice, holidays);
}
public void calculate(final WorkPlace defaultWorkPlace, final WorkPlace mainOffice, final Map<LocalDate, Holiday> holidays) {
clearCalculate();
if (targetDate != null) {
if ((targetDate.getDayOfWeek() == DateTimeConstants.SATURDAY)
|| (targetDate.getDayOfWeek() == DateTimeConstants.SUNDAY)
|| holidays.containsKey(targetDate)
|| (holidays.containsKey(targetDate.minusDays(1)) && holidays.containsKey(targetDate.plusDays(1)))) {
this.holiday = true;
}
}
if (paidLeave) {
setBeginTime(mainOffice.getBaseBeginTime());
setFinishTime(mainOffice.getBaseFinishTime());
this.actualWorkingMinute = mainOffice.getBaseWorkTimeMinute();
return;
}
WorkPlace actualWorkPlace = workPlace;
if (actualWorkPlace == null) {
actualWorkPlace = defaultWorkPlace;
}
DateTime beginDateTime = null;
if (beginTime != null) {
beginDateTime = BASE_DATE.toDateTime(beginTime);
}
DateTime finishDateTime = null;
if (finishTime != null) {
finishDateTime = BASE_DATE.toDateTime(finishTime);
}
if (beginDateTime != null && finishDateTime != null) {
// decide work time interval
if (!beginDateTime.isBefore(finishDateTime)) {
finishDateTime = finishDateTime.plusDays(1);
}
final Interval workTimeInterval = new Interval(beginDateTime, finishDateTime);
// calculate working minute
this.actualWorkingMinute = actualWorkPlace.calculateWorkingMinute(workTimeInterval,
mainOffice);
// calculate compensation minute
if (actualWorkingMinute < mainOffice.getBaseWorkTimeMinute() && !holiday) {
this.compensationMinute = mainOffice.getBaseWorkTimeMinute() - actualWorkingMinute;
}
// calculate midnight working minute
this.midnightWorkingMinute = MidnightTime.INSTANCE.calculateContainsMinute(
workTimeInterval, actualWorkPlace);
} else {
if (finishDateTime != null) {
finishDateTime = null;
setFinishTime(null);
}
}
if (!holiday) {
this.tardyOrEarlyLeaving = actualWorkPlace.isTardyOrEarlyLeaving(beginDateTime,
finishDateTime);
if (tardyOrEarlyLeaving) {
this.compensationMinute = 0;
} else if (beginDateTime == null && !StringUtils.hasLength(specialWorkCode)) {
this.absence = true;
}
}
}
public void setDefault(final WorkPlace defaultWorkPlace) {
setBeginTime(defaultWorkPlace.getBaseBeginTime());
setFinishTime(defaultWorkPlace.getBaseFinishTime());
}
private void clearCalculate() {
this.actualWorkingMinute = 0;
this.compensationMinute = 0;
this.midnightWorkingMinute = 0;
this.tardyOrEarlyLeaving = false;
this.absence = false;
}
}