package gov.nysenate.openleg.service.spotcheck.calendar; import gov.nysenate.openleg.config.Environment; import gov.nysenate.openleg.dao.spotcheck.CalendarAlertReportDao; import gov.nysenate.openleg.dao.spotcheck.SpotCheckReportDao; import gov.nysenate.openleg.model.calendar.Calendar; import gov.nysenate.openleg.model.calendar.CalendarId; import gov.nysenate.openleg.model.spotcheck.*; import gov.nysenate.openleg.service.spotcheck.base.BaseSpotCheckReportService; import gov.nysenate.openleg.util.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Service public abstract class BaseCalendarReportService extends BaseSpotCheckReportService<CalendarId> { private static final Logger logger = LoggerFactory.getLogger(BaseCalendarReportService.class); @Autowired private CalendarAlertReportDao reportDao; @Autowired private CalendarCheckService checkService; @Autowired private Environment environment; protected abstract String getNotes(); protected abstract void markAsChecked(CalendarId id); protected abstract List<Calendar> getReferences(LocalDateTime start, LocalDateTime end); /** * @return The actual calendar or null if it doesn't exist. */ protected abstract Calendar getActualCalendar(CalendarId id, LocalDate calDate); @Override public SpotCheckRefType getSpotcheckRefType() { return SpotCheckRefType.LBDC_CALENDAR_ALERT; } @Override protected SpotCheckReportDao<CalendarId> getReportDao() { return reportDao; } @Override public SpotCheckReport<CalendarId> generateReport(LocalDateTime start, LocalDateTime end) throws ReferenceDataNotFoundEx, Exception { List<Calendar> references = retrieveReferences(start, end); LocalDateTime referenceDateTime = getMostRecentReference(references); SpotCheckReportId reportId = new SpotCheckReportId(getSpotcheckRefType(), referenceDateTime, LocalDateTime.now()); SpotCheckReport<CalendarId> report = new SpotCheckReport<>(reportId); report.setNotes(getNotes()); report.addObservations(createObservations(references)); return report; } private List<Calendar> retrieveReferences(LocalDateTime start, LocalDateTime end) throws ReferenceDataNotFoundEx { List<Calendar> references = getReferences(start, end); if (references.isEmpty()) { throw new ReferenceDataNotFoundEx( String.format("No calendar alerts references were found between %s and %s", start, end)); } return references; } private List<SpotCheckObservation<CalendarId>> createObservations(List<Calendar> references) { List<SpotCheckObservation<CalendarId>> observations = new ArrayList<>(); for (Calendar reference : references) { CalendarId id = reference.getId(); Calendar actual = getActualCalendar(id, reference.getCalDate()); if (actual == null) { if (LocalDateTime.now() .minus(environment.getSpotcheckAlertGracePeriod()) .isBefore(reference.getPublishedDateTime())) { continue; // Do not add a not found mismatch if reference publish date is within grace period } recordMismatch(observations, reference, id); } else { observations.add(checkService.check(actual, reference)); } markAsChecked(id); } // Cancel the report if there are no observations if (observations.isEmpty()) { throw new SpotCheckAbortException(); } return observations; } private void recordMismatch(List<SpotCheckObservation<CalendarId>> observations, Calendar reference, CalendarId id) { SpotCheckReferenceId obsRefId = new SpotCheckReferenceId( getSpotcheckRefType(), reference.getPublishedDateTime()); SpotCheckObservation<CalendarId> observation = new SpotCheckObservation<>(obsRefId, id); observation.addMismatch(new SpotCheckMismatch(SpotCheckMismatchType.OBSERVE_DATA_MISSING, "", id.toString())); observations.add(observation); } private LocalDateTime getMostRecentReference(List<Calendar> references) { LocalDateTime dateTime = LocalDateTime.from(DateUtils.LONG_AGO.atStartOfDay()); for (Calendar cal : references) { if (cal.getPublishedDateTime().isAfter(dateTime)) { dateTime = cal.getPublishedDateTime(); } } return dateTime; } }