Skip to content

Commit

Permalink
GAP-2592: daylight savings causing time to be off by one hour (#285)
Browse files Browse the repository at this point in the history
* Making opening and closing date available to advert summary page + sonar suggestions

* Making opening and closing date available to advert summary page + sonar suggestions
  • Loading branch information
GavCookCO authored Apr 16, 2024
1 parent 3aacd5d commit fe37f15
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,21 @@ public ResponseEntity<CreateGrantAdvertResponseDto> create(HttpServletRequest re
public ResponseEntity updatePage(HttpServletRequest request, @PathVariable UUID grantAdvertId,
@PathVariable String sectionId, @PathVariable String pageId,
@RequestBody @NotNull GrantAdvertPagePatchResponseDto patchAdvertPageResponse) {
GrantAdvertPageResponse responseWithId = GrantAdvertPageResponse.builder().id(pageId)
.status(patchAdvertPageResponse.getStatus()).questions(patchAdvertPageResponse.getQuestions()).build();
GrantAdvertPageResponse responseWithId = GrantAdvertPageResponse.builder()
.id(pageId)
.status(patchAdvertPageResponse.getStatus())
.questions(patchAdvertPageResponse.getQuestions())
.build();

GrantAdvertPageResponseValidationDto patchPageDto = GrantAdvertPageResponseValidationDto.builder()
.grantAdvertId(grantAdvertId).sectionId(sectionId).page(responseWithId).build();
// given we need sectionId to validate the Dto, we can't validate in the
// controller method
Set<ConstraintViolation<GrantAdvertPageResponseValidationDto>> validationErrorsSet = validator
.validate(patchPageDto);
.grantAdvertId(grantAdvertId)
.sectionId(sectionId)
.page(responseWithId)
.build();

// given we need sectionId to validate the Dto, we can't validate in the controller method
Set<ConstraintViolation<GrantAdvertPageResponseValidationDto>> validationErrorsSet =
validator.validate(patchPageDto);

if (!validationErrorsSet.isEmpty()) {
List<ValidationError> validationErrorsList = reorderValidationErrors(patchAdvertPageResponse,
Expand All @@ -111,11 +118,13 @@ public ResponseEntity updatePage(HttpServletRequest request, @PathVariable UUID

try {
AdminSession session = HelperUtils.getAdminSessionForAuthenticatedUser();
eventLogService.logAdvertUpdatedEvent(request.getRequestedSessionId(), session.getUserSub(),
session.getFunderId(), grantAdvertId.toString());
}
catch (Exception e) {
// If anything goes wrong logging to event service, log and continue
eventLogService.logAdvertUpdatedEvent(
request.getRequestedSessionId(),
session.getUserSub(),
session.getFunderId(),
grantAdvertId.toString()
);
} catch (Exception e) {
log.error("Could not send to event service. Exception: ", e);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;

Expand All @@ -24,6 +25,9 @@ public class AdvertSummaryPageDTO {

private GrantAdvertStatus status;

private ZonedDateTime openingDate;
private ZonedDateTime closingDate;

@Data
@AllArgsConstructor
@NoArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,42 +179,50 @@ public GetGrantAdvertPageResponseDTO getAdvertBuilderPageData(UUID grantAdvertId
}

public void updatePageResponse(GrantAdvertPageResponseValidationDto pagePatchDto) {
GrantAdvert grantAdvert = grantAdvertRepository.findById(pagePatchDto.getGrantAdvertId())
final GrantAdvert grantAdvert = grantAdvertRepository.findById(pagePatchDto.getGrantAdvertId())
.orElseThrow(() -> new NotFoundException(
String.format("GrantAdvert with id %s not found", pagePatchDto.getGrantAdvertId())));

validateAdvertStatus(grantAdvert);
// adds the static opening and closing time to the date question
addStaticTimeToDateQuestion(pagePatchDto);


// if response/section/page does not exist, create it. If it does exist, update it
GrantAdvertResponse response = Optional.ofNullable(grantAdvert.getResponse()).orElseGet(() -> {
GrantAdvertResponse newResponse = GrantAdvertResponse.builder().build();
final GrantAdvertResponse response = Optional.ofNullable(grantAdvert.getResponse()).orElseGet(() -> {
final GrantAdvertResponse newResponse = GrantAdvertResponse.builder().build();
grantAdvert.setResponse(newResponse);

return newResponse;
});
GrantAdvertSectionResponse section = response.getSectionById(pagePatchDto.getSectionId()).orElseGet(() -> {
GrantAdvertSectionResponse newSection = GrantAdvertSectionResponse.builder().id(pagePatchDto.getSectionId())
.status(GrantAdvertSectionResponseStatus.IN_PROGRESS).build();

final GrantAdvertSectionResponse section = response.getSectionById(pagePatchDto.getSectionId())
.orElseGet(() -> {
final GrantAdvertSectionResponse newSection = GrantAdvertSectionResponse.builder()
.id(pagePatchDto.getSectionId())
.status(GrantAdvertSectionResponseStatus.IN_PROGRESS)
.build();
response.getSections().add(newSection);

return newSection;
});
GrantAdvertPageResponse page = section.getPageById(pagePatchDto.getPage().getId()).orElseGet(() -> {
GrantAdvertPageResponse newPage = GrantAdvertPageResponse.builder().id(pagePatchDto.getPage().getId())

final GrantAdvertPageResponse page = section.getPageById(pagePatchDto.getPage().getId())
.orElseGet(() -> {
final GrantAdvertPageResponse newPage = GrantAdvertPageResponse.builder()
.id(pagePatchDto.getPage().getId())
.build();
section.getPages().add(newPage);

return newPage;
});

// ideally I'd use the mapper to do this but mapstruct seems to struggle
// with updating iterables and maps etc.
page.setQuestions(pagePatchDto.getPage().getQuestions());
page.setStatus(pagePatchDto.getPage().getStatus());

// update section status
updateSectionStatus(section);

if (pagePatchDto.getSectionId().equals(ADVERT_DATES_SECTION_ID)) {
updateGrantAdvertApplicationDates(grantAdvert);
}

save(grantAdvert);
}

Expand Down Expand Up @@ -551,9 +559,7 @@ public void scheduleGrantAdvert(final UUID grantAdvertId) {
save(grantAdvert);
}

private void updateGrantAdvertApplicationDates(final GrantAdvert grantAdvert) {
// these should never be null at this point, but just in case.
// should also keep our test data in check
public void updateGrantAdvertApplicationDates(final GrantAdvert grantAdvert) {
GrantAdvertSectionResponse applicationDatesSection = grantAdvert.getResponse()
.getSectionById(ADVERT_DATES_SECTION_ID)
.orElseThrow(() -> new GrantAdvertException("Advert is missing application dates section"));
Expand All @@ -569,9 +575,11 @@ private void updateGrantAdvertApplicationDates(final GrantAdvert grantAdvert) {
}

// convert the string[] to int[], to easily build Calendars
int[] openingResponse = Arrays.stream(openingDateQuestion.getMultiResponse()).mapToInt(Integer::parseInt)
int[] openingResponse = Arrays.stream(openingDateQuestion.getMultiResponse())
.mapToInt(Integer::parseInt)
.toArray();
int[] closingResponse = Arrays.stream(closingDateQuestion.getMultiResponse()).mapToInt(Integer::parseInt)
int[] closingResponse = Arrays.stream(closingDateQuestion.getMultiResponse())
.mapToInt(Integer::parseInt)
.toArray();

// build ZonedDateTimes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public AdvertSectionOverviewPageDTO buildSectionOverviewPageContent(String schem
final List<AdvertSectionOverviewPageSectionDto> dtoSectionsList = new ArrayList<>();
final List<AdvertDefinitionSection> statelessSections = definition.getSections();

GrantAdvert grantAdvert = grantAdvertService.getAdvertById(advertId);
final GrantAdvert grantAdvert = grantAdvertService.getAdvertById(advertId);

final List<GrantAdvertSectionResponse> sectionsWithStatus = grantAdvert.getResponse() != null
? grantAdvert.getResponse().getSections() : new ArrayList<>();
Expand All @@ -51,18 +51,25 @@ public AdvertSectionOverviewPageDTO buildSectionOverviewPageContent(String schem
populateSectionsListForDto(dtoSectionsList, statelessSections, sectionsWithStatus);

if (!dtoSectionsList.isEmpty()) {
final List<AdvertSectionOverviewPageSectionDto> nonCompletedSections = dtoSectionsList.stream().filter(
joinedSection -> !joinedSection.getStatus().equals(GrantAdvertSectionResponseStatus.COMPLETED))
final List<AdvertSectionOverviewPageSectionDto> nonCompletedSections = dtoSectionsList.stream()
.filter(joinedSection ->
!joinedSection.getStatus().equals(GrantAdvertSectionResponseStatus.COMPLETED)
)
.toList();
isPublishDisabled = !nonCompletedSections.isEmpty();
}

// builds the dto needed to the frontend
final AdvertSectionOverviewPageDTO response = AdvertSectionOverviewPageDTO.builder().sections(dtoSectionsList)
.advertName(grantAdvert.getGrantAdvertName()).grantSchemeName(grantSchemeName)
.isPublishDisabled(isPublishDisabled).build();
final AdvertSectionOverviewPageDTO response = AdvertSectionOverviewPageDTO.builder()
.sections(dtoSectionsList)
.advertName(grantAdvert.getGrantAdvertName())
.grantSchemeName(grantSchemeName)
.isPublishDisabled(isPublishDisabled)
.build();

log.info("{} with id {} and advert id {}, section-overview page content, successfully created", grantSchemeName,
schemeId, advertId);

return response;
}

Expand All @@ -71,12 +78,16 @@ public AdvertSummaryPageDTO buildSummaryPageContent(UUID advertId) {
final AdvertSummaryPageDTO advertSummaryPageDTO = new AdvertSummaryPageDTO();
final GrantAdvert grantAdvert = grantAdvertService.getAdvertById(advertId);
final List<AdvertDefinitionSection> advertDefinitionSections = definition.getSections();
final List<AdvertSummaryPageDTO.AdvertSummaryPageSectionDTO> sections =
mergeDefinitionAndQuestionResponseForSummaryPage(advertDefinitionSections,
advertSummaryPageDTO, grantAdvert);

advertSummaryPageDTO.setId(grantAdvert.getId());
advertSummaryPageDTO.setAdvertName(grantAdvert.getGrantAdvertName());
advertSummaryPageDTO.setSections(mergeDefinitionAndQuestionResponseForSummaryPage(advertDefinitionSections,
advertSummaryPageDTO, grantAdvert));
advertSummaryPageDTO.setSections(sections);
advertSummaryPageDTO.setStatus(grantAdvert.getStatus());
advertSummaryPageDTO.setOpeningDate(grantAdvert.getOpeningDate());
advertSummaryPageDTO.setClosingDate(grantAdvert.getClosingDate());

return advertSummaryPageDTO;
}
Expand Down Expand Up @@ -107,16 +118,17 @@ private List<AdvertSummaryPageDTO.AdvertSummaryPageSectionDTO> mergeDefinitionAn
.getQuestions().stream()
.map(advertDefinitionQuestion -> getAdvertSummaryPageQuestionDTO(advertSummaryPageDTO,
grantAdvertPageResponse, advertDefinitionQuestion))
.collect(Collectors.toList());
.toList();

pageDTO.setQuestions(pageQuestionDTOs);
return pageDTO;
}).collect(Collectors.toList());
})
.toList();

sectionDTO.setPages(pageDTOs);

return sectionDTO;
}).collect(Collectors.toList());
}).toList();
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -614,30 +614,55 @@ void updatePageResponse_DateQuestion() {
final GrantAdvert advert = GrantAdvert.builder().build();

String[] openingMultiResponse = new String[]{"10", "10", "2010", "13:00"};
GrantAdvertQuestionResponse openingDateQuestion = GrantAdvertQuestionResponse.builder().id(OPENING_DATE_ID)
.multiResponse(openingMultiResponse).build();
GrantAdvertQuestionResponse openingDateQuestion = GrantAdvertQuestionResponse.builder()
.id(OPENING_DATE_ID)
.multiResponse(openingMultiResponse)
.build();

String[] closingMultiResponse = new String[]{"12", "12", "2012", "13:00"};
GrantAdvertQuestionResponse closingDateQuestion = GrantAdvertQuestionResponse.builder().id(CLOSING_DATE_ID)
.multiResponse(closingMultiResponse).build();
GrantAdvertQuestionResponse closingDateQuestion = GrantAdvertQuestionResponse.builder()
.id(CLOSING_DATE_ID)
.multiResponse(closingMultiResponse)
.build();

String[] expectedOpeningMultiResponse = new String[]{"10", "10", "2010", "13", "00"};
String[] expectedClosingMultiResponse = new String[]{"12", "12", "2012", "13", "00"};

GrantAdvertPageResponse datePage = GrantAdvertPageResponse.builder().id(pageId)
GrantAdvertPageResponse datePage = GrantAdvertPageResponse.builder()
.id("1")
.status(GrantAdvertPageResponseStatus.COMPLETED)
.questions(List.of(openingDateQuestion, closingDateQuestion)).build();
.questions(List.of(openingDateQuestion, closingDateQuestion))
.build();

GrantAdvertPageResponseValidationDto datePagePatchDto = GrantAdvertPageResponseValidationDto.builder()
.grantAdvertId(grantAdvertId).sectionId(ADVERT_DATES_SECTION_ID).page(datePage).build();
.grantAdvertId(grantAdvertId)
.sectionId(ADVERT_DATES_SECTION_ID)
.page(datePage)
.build();

AdvertDefinitionQuestion openDateDefinitionQuestion = AdvertDefinitionQuestion.builder().id(OPENING_DATE_ID)
AdvertDefinitionQuestion openDateDefinitionQuestion = AdvertDefinitionQuestion.builder()
.id(OPENING_DATE_ID)
.responseType(AdvertDefinitionQuestionResponseType.DATE)
.validation(AdvertDefinitionQuestionValidation.builder().mandatory(true).build()).build();
.validation(AdvertDefinitionQuestionValidation.builder()
.mandatory(true)
.build()
)
.build();
AdvertDefinitionQuestion closeDateDefinitionQuestion = AdvertDefinitionQuestion.builder()
.id(CLOSING_DATE_ID).responseType(AdvertDefinitionQuestionResponseType.DATE)
.validation(AdvertDefinitionQuestionValidation.builder().mandatory(true).build()).build();
AdvertDefinitionSection definitionSection = AdvertDefinitionSection.builder().id(ADVERT_DATES_SECTION_ID)
.pages(List.of(AdvertDefinitionPage.builder().id(pageId)
.questions(List.of(openDateDefinitionQuestion, closeDateDefinitionQuestion)).build()))
.id(CLOSING_DATE_ID)
.responseType(AdvertDefinitionQuestionResponseType.DATE)
.validation(AdvertDefinitionQuestionValidation.builder()
.mandatory(true)
.build()
)
.build();
AdvertDefinitionSection definitionSection = AdvertDefinitionSection.builder()
.id(ADVERT_DATES_SECTION_ID)
.pages(List.of(AdvertDefinitionPage.builder()
.id("1")
.questions(List.of(openDateDefinitionQuestion, closeDateDefinitionQuestion))
.build())
)
.build();

when(grantAdvertRepository.findById(grantAdvertId))
Expand All @@ -655,7 +680,7 @@ void updatePageResponse_DateQuestion() {
Optional<GrantAdvertSectionResponse> sectionById = response.getSectionById(ADVERT_DATES_SECTION_ID);
assertThat(sectionById).isPresent();
assertThat(sectionById.get().getStatus()).isEqualTo(GrantAdvertSectionResponseStatus.COMPLETED);
Optional<GrantAdvertPageResponse> pageById = sectionById.get().getPageById(pageId);
Optional<GrantAdvertPageResponse> pageById = sectionById.get().getPageById("1");
assertThat(pageById).isPresent();
Optional<GrantAdvertQuestionResponse> openingQuestion = pageById.get().getQuestionById(OPENING_DATE_ID);
assertThat(openingQuestion).isPresent();
Expand Down

0 comments on commit fe37f15

Please sign in to comment.