package sample.model; import java.time.LocalDate; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.*; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import lombok.Setter; import sample.context.Timestamper; import sample.context.orm.DefaultRepository; import sample.model.master.Holiday; import sample.model.master.Holiday.RegHoliday; import sample.util.DateUtils; /** * ドメインに依存する営業日関連のユーティリティハンドラ。 */ @Component @Setter public class BusinessDayHandler { @Autowired private Timestamper time; @Autowired(required = false) @Lazy private HolidayAccessor holidayAccessor; /** 営業日を返します。 */ public LocalDate day() { return time.day(); } /** 営業日を返します。 */ public LocalDate day(int daysToAdd) { LocalDate day = day(); if (0 < daysToAdd) { for (int i = 0; i < daysToAdd; i++) day = dayNext(day); } else if (daysToAdd < 0) { for (int i = 0; i < (-daysToAdd); i++) day = dayPrevious(day); } return day; } private LocalDate dayNext(LocalDate baseDay) { LocalDate day = baseDay.plusDays(1); while (isHolidayOrWeeekDay(day)) day = day.plusDays(1); return day; } private LocalDate dayPrevious(LocalDate baseDay) { LocalDate day = baseDay.minusDays(1); while (isHolidayOrWeeekDay(day)) day = day.minusDays(1); return day; } /** 祝日もしくは週末時はtrue。 */ private boolean isHolidayOrWeeekDay(LocalDate day) { return (DateUtils.isWeekend(day) || isHoliday(day)); } private boolean isHoliday(LocalDate day) { return holidayAccessor == null ? false : holidayAccessor.getHoliday(day).isPresent(); } /** 祝日マスタを検索/登録するアクセサ。 */ @Component @Setter public static class HolidayAccessor { @Autowired private DefaultRepository rep; @Transactional(DefaultRepository.BeanNameTx) @Cacheable(cacheNames = "HolidayAccessor.getHoliday") public Optional<Holiday> getHoliday(LocalDate day) { return Holiday.get(rep, day); } @Transactional(DefaultRepository.BeanNameTx) @CacheEvict(cacheNames = "HolidayAccessor.getHoliday", allEntries = true) public void register(final DefaultRepository rep, final RegHoliday p) { Holiday.register(rep, p); } } }