Skip to content

Commit

Permalink
Implement preparer for applicant education schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
Shawn Tabai committed May 9, 2024
1 parent fd644e3 commit c809fa2
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.ilgcc.app.pdf;

import formflow.library.data.Submission;
import formflow.library.pdf.PdfMap;
import formflow.library.pdf.SubmissionField;
import formflow.library.pdf.SubmissionFieldPreparer;
import org.ilgcc.app.utils.DayOfWeekOption;
import org.springframework.stereotype.Component;

import java.time.format.DateTimeFormatter;
import java.util.*;

import static org.ilgcc.app.utils.SubmissionUtilities.*;

@Component
public class ApplicantEducationSchedulePreparer implements SubmissionFieldPreparer {
private final DateTimeFormatter CLOCK_TIME_OF_AM_PM = DateTimeFormatter.ofPattern("hh:mm");
private final DateTimeFormatter AM_PM_OF_DAY = DateTimeFormatter.ofPattern("a");

@Override
public Map<String, SubmissionField> prepareSubmissionFields(Submission submission, PdfMap pdfMap) {
var results = new HashMap<String, SubmissionField>();

Optional<HourlySchedule> activitiesClassSchedule =
getHourlySchedule(submission, "activitiesClass", "weeklySchedule[]");
if (activitiesClassSchedule.isPresent()) {
var dayMap = activitiesClassSchedule.get().toDayMap();
for (var day : DayOfWeekOption.values()) {
var schedule = dayMap.get(day);
if (schedule == null) {
continue;
}
String fieldPrefix = "applicantEducationSchedule" + day.name();
putSingleFieldResult(
results,
fieldPrefix + "Start",
schedule.startTime().format(CLOCK_TIME_OF_AM_PM));
putSingleFieldResult(
results,
fieldPrefix + "StartAmPm",
schedule.startTime().format(AM_PM_OF_DAY));
putSingleFieldResult(
results,
fieldPrefix + "End",
schedule.endTime().format(CLOCK_TIME_OF_AM_PM));
putSingleFieldResult(
results,
fieldPrefix + "EndAmPm",
schedule.endTime().format(AM_PM_OF_DAY));
}
}
return results;
}
}
113 changes: 110 additions & 3 deletions src/main/java/org/ilgcc/app/utils/SubmissionUtilities.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package org.ilgcc.app.utils;

import com.google.common.collect.ImmutableMap;
import formflow.library.data.Submission;
import formflow.library.inputs.FieldNameMarkers;
import formflow.library.pdf.SingleField;
import formflow.library.pdf.SubmissionField;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.function.Function;

import static java.lang.Integer.parseInt;

Expand Down Expand Up @@ -92,6 +95,26 @@ public static Optional<LocalDate> getDateInput(Submission submission, String inp
return Optional.of(LocalDate.of(parseInt(year), parseInt(month), parseInt(day)));
}

public static Optional<LocalTime> getTimeInput(Submission submission, String inputName) {
String rawValue = (String) submission.getInputData().getOrDefault(inputName, "");
if (rawValue.isBlank()) {
return Optional.empty();
} else {
LocalTime time = LocalTime.parse((String) submission.getInputData().get(inputName));
return Optional.of(time);
}
}

public static Optional<LocalTimeRange> getTimeRangeInput(Submission submission, String inputName, String suffix) {
Optional<LocalTime> start = getTimeInput(submission, "%sStartTime%s".formatted(inputName, suffix));
Optional<LocalTime> end = getTimeInput(submission, "%sEndTime%s".formatted(inputName, suffix));
if (start.isEmpty() && end.isEmpty()) {
return Optional.empty();
} else {
return Optional.of(new LocalTimeRange(start.orElseThrow(), end.orElseThrow()));
}
}

public static String formatToStringFromLocalDate(Optional<LocalDate> date){
if(date.isPresent()){
return date.get().format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
Expand All @@ -107,4 +130,88 @@ public static String selectedYes(String selected){
return "false";
}
}

public record LocalTimeRange(LocalTime startTime, LocalTime endTime) { }

public interface HourlySchedule {
ImmutableMap<DayOfWeekOption, LocalTimeRange> toDayMap();
}

public record ConsistentHourlySchedule(List<DayOfWeekOption> weekdays, LocalTimeRange allDays) implements HourlySchedule {
@Override
public ImmutableMap<DayOfWeekOption, LocalTimeRange> toDayMap() {
ImmutableMap.Builder<DayOfWeekOption, LocalTimeRange> map = ImmutableMap.builder();
for (DayOfWeekOption day : weekdays) {
map.put(day, allDays);
}
return map.build();
}
}

public record PerDayHourlySchedule(
ImmutableMap<DayOfWeekOption, LocalTimeRange> dayMap
) implements HourlySchedule {
public static PerDayHourlySchedule fromEntries(Iterable<ImmutableMap.Entry<DayOfWeekOption, LocalTimeRange>> dayEntries) {
ImmutableMap.Builder<DayOfWeekOption, LocalTimeRange> map = ImmutableMap.builder();
for (var entry : dayEntries) {
map.put(entry.getKey(), entry.getValue());
}
return new PerDayHourlySchedule(map.build());
}
@Override
public ImmutableMap<DayOfWeekOption, LocalTimeRange> toDayMap() {
return dayMap;
}
}

public static Optional<List<DayOfWeekOption>> getDaysOfWeekField(Submission submission, String inputName) {
Object value = submission.getInputData().get(inputName);
if (value == null) {
return Optional.empty();
} else if (value instanceof List<?> valueList) {
return Optional.of(valueList.stream().map(d -> DayOfWeekOption.valueOf(d.toString())).toList());
} else {
throw new IllegalArgumentException("Weekdays field does not contain a list");
}
}

public static Optional<HourlySchedule> getHourlySchedule(
Submission submission, String inputName, String weeklyScheduleInputName) {
Optional<List<DayOfWeekOption>> days = getDaysOfWeekField(submission, weeklyScheduleInputName);
if (days.isEmpty()) {
return Optional.empty();
}

List<String> sameEveryDayField = getOptionalListField(
submission, "%sHoursSameEveryDay[]".formatted(inputName), Object::toString).orElse(List.of());
boolean sameEveryDay = !sameEveryDayField.isEmpty() && sameEveryDayField.get(0).equalsIgnoreCase("Yes");

if (sameEveryDay) {
LocalTimeRange allDays = getTimeRangeInput(submission, inputName, "AllDays").orElseThrow();
return Optional.of(new ConsistentHourlySchedule(days.get(), allDays));
} else {
List<ImmutableMap.Entry<DayOfWeekOption, LocalTimeRange>> ranges = new ArrayList<>();
for (var day : days.get()) {
LocalTimeRange range = getTimeRangeInput(submission, inputName, day.name()).orElseThrow();
ranges.add(Map.entry(day, range));
}
return Optional.of(PerDayHourlySchedule.fromEntries(ranges));
}
}

public static <T> Optional<List<T>> getOptionalListField(
Submission submission, String fieldName, Function<Object, T> converter) {
Object value = submission.getInputData().get(fieldName);
if (value== null) {
return Optional.empty();
} else if (value instanceof List<?> valueList) {
return Optional.of(valueList.stream().map(converter).toList());
} else {
throw new IllegalArgumentException("List field does not contain a list");
}
}

public static void putSingleFieldResult(Map<String, SubmissionField> results, String fieldName, String value) {
results.put(fieldName, new SingleField(fieldName, value, null));
}
}
31 changes: 31 additions & 0 deletions src/main/resources/pdf-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,37 @@ inputFields:
phoneNumber: APPLICANT_EDUCATION_SCHOOL_PHONE
applicantSchoolStartDate: APPLICANT_EDUCATION_SCHOOL_TERM_BEGIN_DATE
applicantSchoolEndDate: APPLICANT_EDUCATION_SCHOOL_TERM_END_DATE

applicantEducationScheduleMondayStart: APPLICANT_EDUCATION_SCHEDULE_MONDAY_START
applicantEducationScheduleMondayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_MONDAY_START_AM_PM
applicantEducationScheduleTuesdayStart: APPLICANT_EDUCATION_SCHEDULE_TUESDAY_START
applicantEducationScheduleTuesdayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_TUESDAY_START_AM_PM
applicantEducationScheduleWednesdayStart: APPLICANT_EDUCATION_SCHEDULE_WEDNESDAY_START
applicantEducationScheduleWednesdayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_WEDNESDAY_START_AM_PM
applicantEducationScheduleThursdayStart: APPLICANT_EDUCATION_SCHEDULE_THURSDAY_START
applicantEducationScheduleThursdayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_THURSDAY_START_AM_PM
applicantEducationScheduleFridayStart: APPLICANT_EDUCATION_SCHEDULE_FRIDAY_START
applicantEducationScheduleFridayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_FRIDAY_START_AM_PM
applicantEducationScheduleSaturdayStart: APPLICANT_EDUCATION_SCHEDULE_SATURDAY_START
applicantEducationScheduleSaturdayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_SATURDAY_START_AM_PM
applicantEducationScheduleSundayStart: APPLICANT_EDUCATION_SCHEDULE_SUNDAY_START
applicantEducationScheduleSundayStartAmPm: APPLICANT_EDUCATION_SCHEDULE_SUNDAY_START_AM_PM

applicantEducationScheduleMondayEnd: APPLICANT_EDUCATION_SCHEDULE_MONDAY_END
applicantEducationScheduleMondayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_MONDAY_END_AM_PM
applicantEducationScheduleTuesdayEnd: APPLICANT_EDUCATION_SCHEDULE_TUESDAY_END
applicantEducationScheduleTuesdayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_TUESDAY_END_AM_PM
applicantEducationScheduleWednesdayEnd: APPLICANT_EDUCATION_SCHEDULE_WEDNESDAY_END
applicantEducationScheduleWednesdayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_WEDNESDAY_END_AM_PM
applicantEducationScheduleThursdayEnd: APPLICANT_EDUCATION_SCHEDULE_THURSDAY_END
applicantEducationScheduleThursdayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_THURSDAY_END_AM_PM
applicantEducationScheduleFridayEnd: APPLICANT_EDUCATION_SCHEDULE_FRIDAY_END
applicantEducationScheduleFridayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_FRIDAY_END_AM_PM
applicantEducationScheduleSaturdayEnd: APPLICANT_EDUCATION_SCHEDULE_SATURDAY_END
applicantEducationScheduleSaturdayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_SATURDAY_END_AM_PM
applicantEducationScheduleSundayEnd: APPLICANT_EDUCATION_SCHEDULE_SUNDAY_END
applicantEducationScheduleSundayEndAmPm: APPLICANT_EDUCATION_SCHEDULE_SUNDAY_END_AM_PM

subflowInfo:
otherFamilyMembers:
totalIterations: 5
Expand Down
Binary file modified src/test/resources/output/test_filled_ccap.pdf
Binary file not shown.

0 comments on commit c809fa2

Please sign in to comment.