Skip to content

Commit

Permalink
Merge pull request #694 from Opetushallitus/fix/OPHKIOS-87
Browse files Browse the repository at this point in the history
VKT(Frontend & Backend): OPHKIOS-87 Jonoilmoittautumisen korjaus ja testejä
  • Loading branch information
pkoivisto authored Sep 11, 2024
2 parents 58347e7 + 7bdae3f commit 43e343b
Show file tree
Hide file tree
Showing 17 changed files with 6,880 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,8 @@ public void validateTicket(

if (enrollmentType.equals(EnrollmentType.QUEUE)) {
publicEnrollmentService.initialiseEnrollmentToQueue(examEventId, person);
SessionUtil.setQueueExamId(session, examEventId);
} else {
publicEnrollmentService.initialiseEnrollment(examEventId, person);
SessionUtil.setQueueExamId(session, null);
}

httpResponse.sendRedirect(uiRouteUtil.getEnrollmentContactDetailsUrl(examEventId));
Expand Down Expand Up @@ -392,8 +390,8 @@ public Map<String, String> getPresignedPostPolicy(
final HttpSession session
) {
if (featureFlagService.isEnabled(FeatureFlag.FREE_ENROLLMENT_FOR_HIGHEST_LEVEL_ALLOWED)) {
Person person = publicPersonService.getPerson(SessionUtil.getPersonId(session));
return publicEnrollmentService.getPresignedPostRequest(examEventId, person, session, filename);
final Person person = publicPersonService.getPerson(SessionUtil.getPersonId(session));
return publicEnrollmentService.getPresignedPostRequest(examEventId, person, filename);
} else {
throw new RuntimeException("Not allowed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public record PublicEnrollmentDTO(
String town,
String country,
Boolean hasPaymentLink,
PublicFreeEnrollmentBasisDTO freeEnrollmentBasis
PublicFreeEnrollmentBasisDTO freeEnrollmentBasis,
Boolean isQueued
)
implements EnrollmentDTOCommonFields {}
3 changes: 3 additions & 0 deletions backend/vkt/src/main/java/fi/oph/vkt/model/Enrollment.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ public class Enrollment extends BaseEntity {
@Column(name = "payment_link_hash", unique = true)
private String paymentLinkHash;

@Column(name = "is_queued")
private Boolean isQueued;

@Column(name = "payment_link_expires_at")
private LocalDateTime paymentLinkExpiresAt;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@
import fi.oph.vkt.util.EnrollmentUtil;
import fi.oph.vkt.util.ExamEventUtil;
import fi.oph.vkt.util.PersonUtil;
import fi.oph.vkt.util.SessionUtil;
import fi.oph.vkt.util.exception.APIException;
import fi.oph.vkt.util.exception.APIExceptionType;
import fi.oph.vkt.util.exception.NotFoundException;
import jakarta.servlet.http.HttpSession;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
Expand Down Expand Up @@ -67,7 +65,7 @@ public PublicEnrollmentInitialisationDTO initialiseEnrollment(final long examEve
final ExamEvent examEvent = examEventRepository.getReferenceById(examEventId);

// Should be done before computing the amount of openings
cancelPotentialUnfinishedEnrollment(examEvent, person);
cancelPotentialUnfinishedEnrollment(examEvent, person, false);

final long openings = ExamEventUtil.getOpenings(examEvent);
if (openings <= 0) {
Expand Down Expand Up @@ -100,11 +98,16 @@ public PublicEnrollmentInitialisationDTO initialiseEnrollment(final long examEve
);
}

private void cancelPotentialUnfinishedEnrollment(final ExamEvent examEvent, final Person person) {
private void cancelPotentialUnfinishedEnrollment(
final ExamEvent examEvent,
final Person person,
final Boolean isQueued
) {
findEnrollment(examEvent, person, enrollmentRepository)
.filter(Enrollment::isUnfinished)
.ifPresent(enrollment -> {
enrollment.setStatus(EnrollmentStatus.CANCELED_UNFINISHED_ENROLLMENT);
enrollment.setIsQueued(isQueued);
enrollmentRepository.saveAndFlush(enrollment);
});
}
Expand Down Expand Up @@ -191,6 +194,7 @@ private PublicEnrollmentDTO createEnrollmentDTO(final Enrollment enrollment) {
.country(enrollment.getCountry())
.hasPaymentLink(enrollment.getPaymentLinkHash() != null)
.freeEnrollmentBasis(createPublicFreeEnrollmentBasisDTO(enrollment))
.isQueued(enrollment.getIsQueued())
.build();
}

Expand Down Expand Up @@ -238,10 +242,15 @@ private PublicEnrollmentInitialisationDTO createEnrollmentInitialisationDTO(
public PublicEnrollmentInitialisationDTO initialiseEnrollmentToQueue(final long examEventId, final Person person) {
final ExamEvent examEvent = examEventRepository.getReferenceById(examEventId);

// If person did not finish payment, allow to continue previous enrollment
// instead of enrolling to queue
if (hasPersonUnfinishedPayment(examEvent, person, enrollmentRepository)) {
return initialiseEnrollment(examEventId, person);
}

// Should be done before computing the amount of openings
cancelPotentialUnfinishedEnrollment(examEvent, person, true);

final long openings = ExamEventUtil.getOpenings(examEvent);
if (openings > 0) {
throw new APIException(APIExceptionType.INITIALISE_ENROLLMENT_TO_QUEUE_HAS_ROOM);
Expand Down Expand Up @@ -276,7 +285,7 @@ protected List<UploadedFileAttachment> validateAndPersistAttachments(
final Person person,
final long examEventId
) {
List<FreeEnrollmentAttachmentDTO> attachmentDTOs = dto.freeEnrollmentBasis().attachments();
final List<FreeEnrollmentAttachmentDTO> attachmentDTOs = dto.freeEnrollmentBasis().attachments();

if (attachmentDTOs.size() > 10) {
throw new APIException(APIExceptionType.TOO_MANY_ATTACHMENTS);
Expand Down Expand Up @@ -364,7 +373,8 @@ public PublicEnrollmentDTO createEnrollment(
examEvent,
person,
EnrollmentStatus.EXPECTING_PAYMENT_UNFINISHED_ENROLLMENT,
null
null,
false
);
reservationRepository.deleteById(reservationId);

Expand All @@ -387,7 +397,14 @@ public PublicEnrollmentDTO createFreeEnrollment(
final FreeEnrollmentDetails freeEnrollmentDetails = enrollmentRepository.countEnrollmentsByPerson(person);
final FreeEnrollment freeEnrollment = saveFreeEnrollment(person, dto, examEvent.getId());
final EnrollmentStatus status = createFreeEnrollmentNextStatus(freeEnrollment, person, dto);
final Enrollment enrollment = createOrUpdateExistingEnrollment(dto, examEvent, person, status, freeEnrollment);
final Enrollment enrollment = createOrUpdateExistingEnrollment(
dto,
examEvent,
person,
status,
freeEnrollment,
false
);
reservationRepository.deleteById(reservationId);

if (status == EnrollmentStatus.COMPLETED || status == EnrollmentStatus.AWAITING_APPROVAL) {
Expand Down Expand Up @@ -422,12 +439,14 @@ private Enrollment createOrUpdateExistingEnrollment(
final ExamEvent examEvent,
final Person person,
final EnrollmentStatus enrollmentStatus,
final FreeEnrollment freeEnrollment
final FreeEnrollment freeEnrollment,
final Boolean isQueued
) {
final Enrollment enrollment = findEnrollment(examEvent, person, enrollmentRepository).orElse(new Enrollment());
enrollment.setExamEvent(examEvent);
enrollment.setPerson(person);
enrollment.setStatus(enrollmentStatus);
enrollment.setIsQueued(isQueued);
enrollment.setFreeEnrollment(freeEnrollment != null ? freeEnrollment : enrollment.getFreeEnrollment());

copyDtoFieldsToEnrollment(enrollment, dto);
Expand Down Expand Up @@ -463,7 +482,8 @@ public PublicEnrollmentDTO createEnrollmentToQueue(
examEvent,
person,
EnrollmentStatus.QUEUED,
freeEnrollment
freeEnrollment,
true
);

if (freeEnrollmentDetails != null && freeEnrollment != null) {
Expand Down Expand Up @@ -520,7 +540,14 @@ public PublicEnrollmentDTO updateEnrollmentForPayment(
status = createFreeEnrollmentNextStatus(freeEnrollment, person, dto);
}

final Enrollment enrollment = createOrUpdateExistingEnrollment(dto, examEvent, person, status, freeEnrollment);
final Enrollment enrollment = createOrUpdateExistingEnrollment(
dto,
examEvent,
person,
status,
freeEnrollment,
false
);
if (
freeEnrollmentDetails != null &&
(status == EnrollmentStatus.COMPLETED || status == EnrollmentStatus.AWAITING_APPROVAL)
Expand All @@ -535,31 +562,12 @@ public PublicEnrollmentDTO updateEnrollmentForPayment(
public Map<String, String> getPresignedPostRequest(
final long examEventId,
final Person person,
final HttpSession session,
final String filename
) {
final ExamEvent examEvent = examEventRepository.getReferenceById(examEventId);

// Allow uploading only if person is actively trying to enroll or reserve a place in the queue
boolean uploadAllowed = false;
final Optional<Enrollment> enrollment = findEnrollment(examEvent, person, enrollmentRepository);
if (enrollment.isPresent()) {
uploadAllowed = enrollment.get().isExpectingPayment();
}
// Enrollment data not yet initialized, so let's check for reservation instead.
if (!uploadAllowed) {
final Optional<Reservation> reservation = reservationRepository.findByExamEventAndPerson(examEvent, person);
if (reservation.isPresent()) {
uploadAllowed = reservation.get().isActive();
}
}
// If enrollment or reservation is not found, user might be enrolling into queue.
if (!uploadAllowed) {
Long queueExamEventId = SessionUtil.getQueueExamId(session);
uploadAllowed = (queueExamEventId == examEventId);
}
if (!uploadAllowed) {
throw new NotFoundException("No unfinished enrollment or reservation for exam event found");
if (person == null || examEvent.getRegistrationCloses().isBefore(LocalDate.now())) {
throw new NotFoundException("Uploading not allowed. Person is null or exam is closed");
}

final String millis = String.valueOf(System.currentTimeMillis());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,22 @@ private String requestWithRetries(final String oid, final int attemptsRemaining)
})
.block();
} catch (final WebClientResponseException e) {
final int retries = attemptsRemaining - 1;
LOG.error(
"KOSKI request for OID {} returned error status {}\n response body: {}",
"KOSKI request for OID {} returned error status {}\n response body: {}, Retries remaining: {}",
oid,
e.getStatusCode().value(),
e.getResponseBodyAsString()
e.getResponseBodyAsString(),
retries
);
throw new RuntimeException(e);
if (retries > 0) {
return requestWithRetries(oid, retries);
} else {
throw e;
}
} catch (final Exception e) {
final int retries = attemptsRemaining - 1;
LOG.error("KOSKI request failed! Retries remaining: {}, OID: {}", retries, e, oid);
LOG.error("KOSKI request failed for unknown reason! Retries remaining: {}, OID: {}", retries, oid, e);
if (retries > 0) {
return requestWithRetries(oid, retries);
} else {
Expand Down Expand Up @@ -122,10 +128,8 @@ public List<PublicEducationDTO> findEducations(final String oid) {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);

final KoskiResponseDTO koskiResponseDTO = objectMapper.readValue(
requestWithRetries(oid, REQUEST_ATTEMPTS),
KoskiResponseDTO.class
);
final String response = requestWithRetries(oid, REQUEST_ATTEMPTS);
final KoskiResponseDTO koskiResponseDTO = objectMapper.readValue(response, KoskiResponseDTO.class);

if (koskiResponseDTO.getHenkilo() == null || !oid.equals(koskiResponseDTO.getHenkilo().getOid())) {
throw new Exception(
Expand Down
15 changes: 0 additions & 15 deletions backend/vkt/src/main/java/fi/oph/vkt/util/SessionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
public class SessionUtil {

private static final String PERSON_ID_SESSION_KEY = "person_id";
private static final String QUEUE_EXAM_ID_SESSION_KEY = "queue_exam_id";

public static boolean hasPersonId(final HttpSession session) {
return session.getAttribute(PERSON_ID_SESSION_KEY) != null;
Expand All @@ -23,21 +22,7 @@ public static Long getPersonId(final HttpSession session) {
return personId;
}

public static Long getQueueExamId(final HttpSession session) {
final Long examId = (Long) session.getAttribute(QUEUE_EXAM_ID_SESSION_KEY);

if (examId == null) {
throw new APIException(APIExceptionType.SESSION_MISSING_QUEUE_EXAM_ID);
}

return examId;
}

public static void setPersonId(final HttpSession session, final Long personId) {
session.setAttribute(PERSON_ID_SESSION_KEY, personId);
}

public static void setQueueExamId(final HttpSession session, final Long examId) {
session.setAttribute(QUEUE_EXAM_ID_SESSION_KEY, examId);
}
}
12 changes: 12 additions & 0 deletions backend/vkt/src/main/resources/db/changelog/db.changelog-1.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -780,4 +780,16 @@
</sql>
<addNotNullConstraint tableName="person" columnName="uuid" />
</changeSet>

<changeSet id="2024-08-14-add-is-queued-to-enrollment" author="jrkkp">
<addColumn tableName="enrollment">
<column name="is_queued" type="BOOLEAN" />
</addColumn>
<sql>
UPDATE enrollment SET is_queued = 't' WHERE status = 'QUEUED'
</sql>
<sql>
UPDATE enrollment SET is_queued = 'f' WHERE status = 'COMPLETED'
</sql>
</changeSet>
</databaseChangeLog>
Loading

0 comments on commit 43e343b

Please sign in to comment.