Skip to content

Commit

Permalink
CSCEXAM-1333 Fix handling of query params / reservation removal
Browse files Browse the repository at this point in the history
  • Loading branch information
lupari committed Jun 7, 2024
1 parent ddaf21c commit e64829d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 84 deletions.
152 changes: 69 additions & 83 deletions app/controllers/ReservationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import models.base.GeneratedIdentityModel;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import play.data.DynamicForm;
import play.libs.Json;
import play.mvc.Http;
import play.mvc.Result;
Expand Down Expand Up @@ -82,15 +83,14 @@ public Result getExams(Http.Request request, Optional<String> filter) {
el = el.ilike("name", String.format("%%%s%%", filter.get()));
}
if (user.hasRole(Role.Name.TEACHER)) {
el =
el
.gt("periodEnd", new Date())
.disjunction()
.eq("creator", user)
.eq("examOwners", user)
.eq("examInspections.user", user)
.eq("shared", true)
.endJunction();
el = el
.gt("periodEnd", new Date())
.disjunction()
.eq("creator", user)
.eq("examOwners", user)
.eq("examInspections.user", user)
.eq("shared", true)
.endJunction();
}
return ok(el.findList(), props);
}
Expand Down Expand Up @@ -140,28 +140,23 @@ public Result getTeachers(Optional<String> filter) {

@Restrict({ @Group("ADMIN") })
public CompletionStage<Result> removeReservation(long id, Http.Request request) throws NotFoundException {
var msg = request.body().asJson().get("msg").asText("");
var enrolment = DB.find(ExamEnrolment.class).where().eq("reservation.id", id).findOne();

if (enrolment == null) {
throw new NotFoundException(String.format("No reservation with id %d for current user.", id));
}

var participation = DB.find(ExamParticipation.class).where().eq("exam", enrolment.getExam()).findOne();

if (participation != null) {
return wrapAsPromise(
forbidden(String.format("i18n_unable_to_remove_reservation (id=%d).", participation.getId()))
);
}

var reservation = enrolment.getReservation();
var msg = formFactory.form().bindFromRequest(request).get("msg");
// Let's not send emails about historical reservations
if (reservation.getEndAt().isAfter(DateTime.now())) {
var student = enrolment.getUser();
emailComposer.composeReservationCancellationNotification(student, reservation, msg, false, enrolment);
}

if (reservation.getExternalReservation() != null) {
return externalReservationHandler.removeReservation(reservation, enrolment.getUser(), msg);
} else {
Expand Down Expand Up @@ -263,8 +258,7 @@ public Result getExaminationEvents(
Optional<String> end,
Http.Request request
) {
var query = DB
.find(ExamEnrolment.class)
var query = DB.find(ExamEnrolment.class)
.fetch("user", "id, firstName, lastName, email, userIdentifier")
.fetch("exam", "id, name, state, trialCount, implementation")
.fetch("exam.course", "code")
Expand All @@ -277,13 +271,12 @@ public Result getExaminationEvents(
.isNotNull("exam");
var user = request.attrs().get(Attrs.AUTHENTICATED_USER);
if (user.hasRole(Role.Name.TEACHER)) {
query =
query
.disjunction()
.eq("exam.parent.examOwners", user)
.eq("exam.examOwners", user)
.endJunction()
.ne("exam.state", Exam.State.DELETED);
query = query
.disjunction()
.eq("exam.parent.examOwners", user)
.eq("exam.examOwners", user)
.endJunction()
.ne("exam.state", Exam.State.DELETED);
}

if (start.isPresent()) {
Expand All @@ -292,12 +285,11 @@ public Result getExaminationEvents(
}

if (state.isPresent()) {
query =
switch (state.get()) {
case "NO_SHOW" -> query.eq("noShow", true);
case "EXTERNAL_UNFINISHED", "EXTERNAL_FINISHED" -> query.isNull("id"); // Deliberately force an empty result set
default -> query.eq("exam.state", Exam.State.valueOf(state.get())).eq("noShow", false);
};
query = switch (state.get()) {
case "NO_SHOW" -> query.eq("noShow", true);
case "EXTERNAL_UNFINISHED", "EXTERNAL_FINISHED" -> query.isNull("id"); // Deliberately force an empty result set
default -> query.eq("exam.state", Exam.State.valueOf(state.get())).eq("noShow", false);
};
}

if (studentId.isPresent()) {
Expand All @@ -308,23 +300,21 @@ public Result getExaminationEvents(
}
}
if (examId.isPresent()) {
query =
query
.ne("exam.state", Exam.State.DELETED) // Local student reservation
.disjunction()
.eq("exam.parent.id", examId.get())
.eq("exam.id", examId.get())
.endJunction();
query = query
.ne("exam.state", Exam.State.DELETED) // Local student reservation
.disjunction()
.eq("exam.parent.id", examId.get())
.eq("exam.id", examId.get())
.endJunction();
}

if (ownerId.isPresent() && user.hasRole(Role.Name.ADMIN)) {
var userId = ownerId.get();
query =
query
.disjunction()
.eq("exam.examOwners.id", userId)
.eq("exam.parent.examOwners.id", userId)
.endJunction();
query = query
.disjunction()
.eq("exam.examOwners.id", userId)
.eq("exam.parent.examOwners.id", userId)
.endJunction();
}
var enrolments = query
.orderBy("examinationEventConfiguration.examinationEvent.start")
Expand Down Expand Up @@ -368,8 +358,7 @@ public Result getReservations(
Optional<String> externalRef,
Http.Request request
) {
var query = DB
.find(Reservation.class)
var query = DB.find(Reservation.class)
.fetch("enrolment", "noShow, retrialPermitted")
.fetch("user", "id, firstName, lastName, email, userIdentifier")
.fetch("enrolment.exam", "id, name, state, trialCount, implementation")
Expand All @@ -387,15 +376,14 @@ public Result getReservations(

var user = request.attrs().get(Attrs.AUTHENTICATED_USER);
if (user.hasRole(Role.Name.TEACHER)) {
query =
query
.isNull("enrolment.externalExam") // Hide reservations of external students (just to be sure)
.isNull("enrolment.collaborativeExam") // Hide collaborative exams from teachers.
.ne("enrolment.exam.state", Exam.State.DELETED) // Hide deleted exams from teachers
.disjunction()
.eq("enrolment.exam.parent.examOwners", user)
.eq("enrolment.exam.examOwners", user)
.endJunction();
query = query
.isNull("enrolment.externalExam") // Hide reservations of external students (just to be sure)
.isNull("enrolment.collaborativeExam") // Hide collaborative exams from teachers.
.ne("enrolment.exam.state", Exam.State.DELETED) // Hide deleted exams from teachers
.disjunction()
.eq("enrolment.exam.parent.examOwners", user)
.eq("enrolment.exam.examOwners", user)
.endJunction();
}

if (start.isPresent()) {
Expand All @@ -411,19 +399,18 @@ public Result getReservations(
}

if (state.isPresent()) {
query =
switch (state.get()) {
case "NO_SHOW" -> query.eq("enrolment.noShow", true);
case "EXTERNAL_UNFINISHED" -> query
.isNotNull("externalUserRef")
.isNull("enrolment.externalExam.finished");
case "EXTERNAL_FINISHED" -> query
.isNotNull("externalUserRef")
.isNotNull("enrolment.externalExam.finished");
default -> query
.eq("enrolment.exam.state", Exam.State.valueOf(state.get()))
.eq("enrolment.noShow", false);
};
query = switch (state.get()) {
case "NO_SHOW" -> query.eq("enrolment.noShow", true);
case "EXTERNAL_UNFINISHED" -> query
.isNotNull("externalUserRef")
.isNull("enrolment.externalExam.finished");
case "EXTERNAL_FINISHED" -> query
.isNotNull("externalUserRef")
.isNotNull("enrolment.externalExam.finished");
default -> query
.eq("enrolment.exam.state", Exam.State.valueOf(state.get()))
.eq("enrolment.noShow", false);
};
}

if (studentId.isPresent()) {
Expand All @@ -444,33 +431,32 @@ public Result getReservations(
query = query.eq("machine.id", machineId.get());
}
if (examId.isPresent()) {
query =
query
.disjunction()
.eq("enrolment.exam.parent.id", examId.get())
.eq("enrolment.exam.id", examId.get())
.endJunction();
query = query
.disjunction()
.eq("enrolment.exam.parent.id", examId.get())
.eq("enrolment.exam.id", examId.get())
.endJunction();
} else if (externalRef.isPresent()) {
query = query.eq("enrolment.collaborativeExam.externalRef", externalRef.get());
}

if (ownerId.isPresent() && user.hasRole(Role.Name.ADMIN)) {
var userId = ownerId.get();
query =
query
.disjunction()
.eq("enrolment.exam.examOwners.id", userId)
.eq("enrolment.exam.parent.examOwners.id", userId)
.endJunction();
query = query
.disjunction()
.eq("enrolment.exam.examOwners.id", userId)
.eq("enrolment.exam.parent.examOwners.id", userId)
.endJunction();
}
var reservations = query.orderBy("startAt").findSet();
var result = ok(reservations);
var anonIds = reservations
.stream()
.filter(r ->
r.getEnrolment() != null &&
r.getEnrolment().getExam() != null &&
r.getEnrolment().getExam().isAnonymous()
.filter(
r ->
r.getEnrolment() != null &&
r.getEnrolment().getExam() != null &&
r.getEnrolment().getExam().isAnonymous()
)
.map(GeneratedIdentityModel::getId)
.collect(Collectors.toSet());
Expand Down
3 changes: 2 additions & 1 deletion ui/src/app/reservation/reservation-details.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Component, Input, OnChanges } from '@angular/core';
import { RouterLink } from '@angular/router';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { ToastrService } from 'ngx-toastr';
import { noop } from 'rxjs';
import { ExamEnrolment } from 'src/app/enrolment/enrolment.model';
import { ApplyDstPipe } from 'src/app/shared/date/apply-dst.pipe';
import { CourseCodeComponent } from 'src/app/shared/miscellaneous/course-code.component';
Expand Down Expand Up @@ -85,7 +86,7 @@ export class ReservationDetailsComponent implements OnChanges {
this.fixedReservations.splice(this.fixedReservations.indexOf(reservation), 1);
this.toast.info(this.translate.instant('i18n_reservation_removed'));
})
.catch((err) => this.toast.error(err));
.catch(noop);
}

permitRetrial(enrolment: ExamEnrolment) {
Expand Down

0 comments on commit e64829d

Please sign in to comment.