protected boolean periodicalIsFullyInPeriod(
     Date periodBeginDate, Date periodEndDate, K periodical) {
   return (periodical.getBeginDate().after(periodBeginDate)
           || DateUtils.isSameDay(periodical.getBeginDate(), periodBeginDate))
       && (periodical.getEndDate().before(periodEndDate)
           || (DateUtils.isSameDay(periodical.getEndDate(), periodEndDate)));
 }
  protected K makePeriodicalCoversOnlyOneYear(K periodical, Date yearBeginDate, Date yearEndDate) {
    if (periodical.getBeginDate().before(yearBeginDate)
        && periodical.getEndDate().after(yearBeginDate)) {
      periodical.setBeginDate(yearBeginDate);
    }
    if (periodical.getBeginDate().before(yearEndDate)
        && periodical.getEndDate().after(yearEndDate)) {
      periodical.setEndDate(yearEndDate);
    }

    return periodical;
  }
  private T addCommonPartOfPeriodicleToMounthStatistics(T report, K periodical) {
    Long calendarDaysCount =
        calendarService.getAllDaysCount(periodical.getBeginDate(), periodical.getEndDate());
    Integer holidaysCount =
        calendarService.getHolidaysCounForRegion(
            periodical.getBeginDate(),
            periodical.getEndDate(),
            periodical.getEmployee().getRegion());
    Long workingDays = calendarDaysCount - holidaysCount;
    periodical.setWorkingDays(workingDays);
    periodical.setCalendarDays(calendarDaysCount);
    report.getPeriodicalsList().add(periodical);
    report.setMounthCalendarDays(report.getMounthCalendarDays() + calendarDaysCount);
    report.setMounthWorkDays(report.getMounthWorkDays() + workingDays);

    return report;
  }
 private T addCommonPartOfPartOfPeriodicleToMounthStatistics(
     T report, K periodical, Date beginDate, Date endDate) throws CloneNotSupportedException {
   K partOfPeriodical = getPeriodicalWithFakeDates(periodical, beginDate, endDate);
   report = addCommonPartOfPeriodicleToMounthStatistics(report, partOfPeriodical);
   replaseFakeDatesWithRealDates(
       partOfPeriodical, periodical.getBeginDate(), periodical.getEndDate());
   return report;
 }
  public final T generate(
      Employee employee,
      Date periodBeginDate,
      Date periodEndDate,
      Date yearBeginDate,
      Date yearEndDate)
      throws BusinessTripsAndIllnessControllerException {
    try {
      T report = createQuickReport();

      List<K> allPeriodicles = getAllPeriodicals(employee);

      for (K periodical : allPeriodicles) {

        periodical =
            makePeriodicalCoversOnlyOneYear(
                periodical,
                yearBeginDate,
                yearEndDate); // т.к. собираем статистику только по одному году - отрсеиваем
                              // ненужные периоды и отрезаем ненужные части нужных (которые входят в
                              // отчетный год частично)

        if (periodicalIsFullyInPeriod(
            periodBeginDate,
            periodEndDate,
            periodical)) { // период попадает в отчетный месяц, не выходя за его границы
          report = addCommonPartOfPeriodicleToMounthStatistics(report, periodical);
          report = addDifferentPartOfPeriodicleToMounthStatistics(report, periodical);
        } else if (periodicalCrossesTheBeginningOfTheMounth(
            periodBeginDate, periodical)) { // период попадает на отчетный месяц и на предыдущие
          report =
              addCommonPartOfPartOfPeriodicleToMounthStatistics(
                  report, periodical, periodBeginDate, periodical.getEndDate());
          report =
              addCommonPartOfPartOfPeriodicleToMounthStatistics(
                  report,
                  periodical,
                  periodical.getBeginDate(),
                  DateUtils.addDays(periodBeginDate, -1));
        } else if (periodicalCrossesTheEndOfTheMounth(
            periodEndDate, periodical)) { // период попадает на отчетный месяц и следующие за ним
          report =
              addCommonPartOfPartOfPeriodicleToMounthStatistics(
                  report, periodical, periodical.getBeginDate(), periodEndDate);
          report =
              addCommonPartOfPartOfPeriodicleToMounthStatistics(
                  report, periodical, DateUtils.addDays(periodEndDate, 1), periodical.getEndDate());
        } else if (periodicalCoversAllPeriod(
            periodBeginDate,
            periodEndDate,
            periodical)) { // период польностью включает в себя отчетный месяц и захватывает
                           // предыдущие и последующие месяца
          report =
              addPartOfPeriodicleToYearStatistics(
                  report,
                  periodical,
                  periodical.getBeginDate(),
                  DateUtils.addDays(periodBeginDate, -1));
          report =
              addCommonPartOfPartOfPeriodicleToMounthStatistics(
                  report, periodical, periodBeginDate, periodEndDate);
          report =
              addPartOfPeriodicleToYearStatistics(
                  report, periodical, DateUtils.addDays(periodEndDate, 1), periodical.getEndDate());
        } else if (periodicalIsFullyInPeriod(
            yearBeginDate,
            yearEndDate,
            periodical)) { // период попадает в отчетный год и не захватывает отчетный месяц
          report = addPeriodicalToYearStatistics(report, periodical, yearBeginDate, yearEndDate);
        }
      }

      addMounthStatisticsToYearStatistics(report);

      return report;

    } catch (Throwable th) {
      throw new BusinessTripsAndIllnessControllerException(QOICK_REPORT_GENARATE_ERROR_MESSAGE);
    }
  }
 protected boolean periodicalCrossesTheBeginningOfTheMounth(Date periodBeginDate, K periodical) {
   return periodical.getEndDate().after(periodBeginDate)
       && periodical.getBeginDate().before(periodBeginDate);
 }
 protected boolean periodicalCoversAllPeriod(
     Date periodBeginDate, Date periodEndDate, K periodical) {
   return periodical.getBeginDate().before(periodBeginDate)
       && periodical.getEndDate().after(periodEndDate);
 }