SEBSERV-341 and SEBSERV-343
This commit is contained in:
parent
921595c3b0
commit
224507d849
6 changed files with 76 additions and 97 deletions
|
@ -30,7 +30,6 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
|
|||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
|
@ -89,7 +88,7 @@ public class ExamList implements TemplateComposer {
|
|||
private final TableFilterAttribute institutionFilter;
|
||||
private final TableFilterAttribute lmsFilter;
|
||||
private final TableFilterAttribute nameFilter =
|
||||
new TableFilterAttribute(CriteriaType.TEXT, QuizData.FILTER_ATTR_NAME);
|
||||
new TableFilterAttribute(CriteriaType.TEXT, Domain.EXAM.ATTR_QUIZ_NAME);
|
||||
private final TableFilterAttribute stateFilter;
|
||||
private final TableFilterAttribute typeFilter;
|
||||
|
||||
|
@ -177,21 +176,21 @@ public class ExamList implements TemplateComposer {
|
|||
.sortable())
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
QuizData.QUIZ_ATTR_NAME,
|
||||
Domain.EXAM.ATTR_QUIZ_NAME,
|
||||
COLUMN_TITLE_NAME_KEY,
|
||||
Exam::getName)
|
||||
.withFilter(this.nameFilter)
|
||||
.sortable())
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
QuizData.QUIZ_ATTR_START_TIME,
|
||||
Domain.EXAM.ATTR_QUIZ_START_TIME,
|
||||
new LocTextKey(
|
||||
EXAM_LIST_COLUMN_START_TIME,
|
||||
i18nSupport.getUsersTimeZoneTitleSuffix()),
|
||||
Exam::getStartTime)
|
||||
.withFilter(new TableFilterAttribute(
|
||||
CriteriaType.DATE,
|
||||
QuizData.FILTER_ATTR_START_TIME,
|
||||
Domain.EXAM.ATTR_QUIZ_START_TIME,
|
||||
Utils.toDateTimeUTC(Utils.getMillisecondsNow())
|
||||
.minusYears(1)
|
||||
.toString()))
|
||||
|
|
|
@ -282,10 +282,11 @@ public class PaginationServiceImpl implements PaginationService {
|
|||
final Map<String, String> examTableMap = new HashMap<>();
|
||||
examTableMap.put(Entity.FILTER_ATTR_INSTITUTION, institutionNameRef);
|
||||
examTableMap.put(Domain.EXAM.ATTR_LMS_SETUP_ID, lmsSetupNameRef);
|
||||
|
||||
// NOTE: This seems not to work and I was not able to figure out why.
|
||||
// Now the type sorting is done within secondary sort for exams.
|
||||
//examTableMap.put(Domain.EXAM.ATTR_TYPE, "'" + ExamRecordDynamicSqlSupport.type.name() + "'");
|
||||
examTableMap.put(Domain.EXAM.ATTR_QUIZ_NAME, ExamRecordDynamicSqlSupport.quizName.name());
|
||||
examTableMap.put(Domain.EXAM.ATTR_QUIZ_START_TIME, ExamRecordDynamicSqlSupport.quizStartTime.name());
|
||||
examTableMap.put(Domain.EXAM.ATTR_QUIZ_END_TIME, ExamRecordDynamicSqlSupport.quizEndTime.name());
|
||||
examTableMap.put(Domain.EXAM.ATTR_STATUS, ExamRecordDynamicSqlSupport.status.name());
|
||||
examTableMap.put(Domain.EXAM.ATTR_TYPE, ExamRecordDynamicSqlSupport.type.name());
|
||||
|
||||
this.sortColumnMapping.put(ExamRecordDynamicSqlSupport.examRecord.name(), examTableMap);
|
||||
this.defaultSortColumn.put(ExamRecordDynamicSqlSupport.examRecord.name(), Domain.EXAM.ATTR_ID);
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.springframework.util.MultiValueMap;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||
|
@ -108,7 +109,7 @@ public class FilterMap extends POSTMapper {
|
|||
}
|
||||
|
||||
public DateTime getExamFromTime() {
|
||||
return Utils.toDateTime(getString(QuizData.FILTER_ATTR_START_TIME));
|
||||
return Utils.toDateTime(getString(Domain.EXAM.ATTR_QUIZ_START_TIME));
|
||||
}
|
||||
|
||||
public DateTime getSEBClientConfigFromTime() {
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.mybatis.dynamic.sql.update.UpdateDSL;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
@ -121,42 +120,16 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final Predicate<Exam> examDataFilter = createPredicate(filterMap);
|
||||
return this.examRecordDAO
|
||||
.allMatching(filterMap, null)
|
||||
.flatMap(this::toDomainModel)
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.filter(examDataFilter.and(predicate))
|
||||
.filter(predicate)
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
private Predicate<Exam> createPredicate(final FilterMap filterMap) {
|
||||
final String name = filterMap.getQuizName();
|
||||
final DateTime from = filterMap.getExamFromTime();
|
||||
final Predicate<Exam> quizDataFilter = exam -> {
|
||||
if (StringUtils.isNotBlank(name)) {
|
||||
if (!exam.name.contains(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (from != null && exam.startTime != null) {
|
||||
// always show exams that has not ended yet
|
||||
if (exam.endTime == null || exam.endTime.isAfter(from)) {
|
||||
return true;
|
||||
}
|
||||
if (exam.startTime.isBefore(from)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return quizDataFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Exam> updateState(final Long examId, final ExamStatus status, final String updateId) {
|
||||
return this.examRecordDAO
|
||||
|
@ -268,13 +241,12 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
.stream().map(s -> s.name())
|
||||
.collect(Collectors.toList())
|
||||
: null;
|
||||
final Predicate<Exam> examDataFilter = createPredicate(filterMap);
|
||||
return this.examRecordDAO
|
||||
.allMatching(filterMap, stateNames)
|
||||
.flatMap(this::toDomainModel)
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.filter(examDataFilter.and(predicate))
|
||||
.filter(predicate)
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -172,8 +172,6 @@ public class ExamRecordDAO {
|
|||
ExamRecordDynamicSqlSupport.active,
|
||||
isEqualToWhenPresent(filterMap.getActiveAsInt()));
|
||||
|
||||
//
|
||||
|
||||
whereClause = whereClause
|
||||
.and(
|
||||
ExamRecordDynamicSqlSupport.institutionId,
|
||||
|
@ -209,6 +207,10 @@ public class ExamRecordDAO {
|
|||
.and(
|
||||
ExamRecordDynamicSqlSupport.quizName,
|
||||
isLikeWhenPresent(filterMap.getSQLWildcard(EXAM.ATTR_QUIZ_NAME)))
|
||||
.and(
|
||||
ExamRecordDynamicSqlSupport.quizEndTime,
|
||||
isGreaterThanOrEqualToWhenPresent(filterMap.getExamFromTime()),
|
||||
or(ExamRecordDynamicSqlSupport.quizEndTime, isNull()))
|
||||
.build()
|
||||
.execute();
|
||||
|
||||
|
@ -465,20 +467,20 @@ public class ExamRecordDAO {
|
|||
.execute();
|
||||
|
||||
// check those in not running state (and not archived) and are within the time-frame or on wrong side of the time-frame
|
||||
// if finished but up-coming
|
||||
// if finished but up-coming or running
|
||||
final SqlCriterion<String> finished = or(
|
||||
ExamRecordDynamicSqlSupport.status,
|
||||
isEqualTo(ExamStatus.FINISHED.name()),
|
||||
and(
|
||||
ExamRecordDynamicSqlSupport.quizStartTime,
|
||||
ExamRecordDynamicSqlSupport.quizEndTime,
|
||||
SqlBuilder.isGreaterThanOrEqualToWhenPresent(now.plus(leadTime))));
|
||||
|
||||
// if up-coming but finished
|
||||
// if up-coming but running or finished
|
||||
final SqlCriterion<String> upcoming = or(
|
||||
ExamRecordDynamicSqlSupport.status,
|
||||
isEqualTo(ExamStatus.UP_COMING.name()),
|
||||
and(
|
||||
ExamRecordDynamicSqlSupport.quizEndTime,
|
||||
ExamRecordDynamicSqlSupport.quizStartTime,
|
||||
SqlBuilder.isLessThanWhenPresent(now.minus(followupTime))),
|
||||
finished);
|
||||
|
||||
|
|
|
@ -17,13 +17,12 @@ import java.util.Set;
|
|||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.mybatis.dynamic.sql.SqlTable;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
@ -39,14 +38,13 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
|||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBRestriction;
|
||||
|
@ -120,50 +118,56 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
|||
return ExamRecordDynamicSqlSupport.examRecord;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Override
|
||||
public Page<Exam> getPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber,
|
||||
@RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize,
|
||||
@RequestParam(name = Page.ATTR_SORT, required = false) final String sort,
|
||||
@RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||
final HttpServletRequest request) {
|
||||
|
||||
checkReadPrivilege(institutionId);
|
||||
this.authorization.check(
|
||||
PrivilegeType.READ,
|
||||
EntityType.EXAM,
|
||||
institutionId);
|
||||
|
||||
if (StringUtils.isBlank(sort) ||
|
||||
(this.paginationService.isNativeSortingSupported(ExamRecordDynamicSqlSupport.examRecord, sort))) {
|
||||
|
||||
return super.getPage(institutionId, pageNumber, pageSize, sort, allRequestParams, request);
|
||||
|
||||
} else {
|
||||
|
||||
final Collection<Exam> exams = this.examDAO
|
||||
.allMatching(new FilterMap(
|
||||
allRequestParams,
|
||||
request.getQueryString()),
|
||||
this::hasReadAccess)
|
||||
.getOrThrow();
|
||||
|
||||
return this.paginationService.buildPageFromList(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sort,
|
||||
exams,
|
||||
pageSort(sort));
|
||||
}
|
||||
}
|
||||
// @RequestMapping(
|
||||
// method = RequestMethod.GET,
|
||||
// consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
// produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// @Override
|
||||
// public Page<Exam> getPage(
|
||||
// @RequestParam(
|
||||
// name = API.PARAM_INSTITUTION_ID,
|
||||
// required = true,
|
||||
// defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
// @RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber,
|
||||
// @RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize,
|
||||
// @RequestParam(name = Page.ATTR_SORT, required = false) final String sort,
|
||||
// @RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||
// final HttpServletRequest request) {
|
||||
//
|
||||
// checkReadPrivilege(institutionId);
|
||||
// this.authorization.check(
|
||||
// PrivilegeType.READ,
|
||||
// EntityType.EXAM,
|
||||
// institutionId);
|
||||
//
|
||||
// if (StringUtils.isBlank(sort) ||
|
||||
// (this.paginationService.isNativeSortingSupported(ExamRecordDynamicSqlSupport.examRecord, sort))) {
|
||||
//
|
||||
// System.out.println("*********************** sort, filter on DB");
|
||||
//
|
||||
// return super.getPage(institutionId, pageNumber, pageSize, sort, allRequestParams, request);
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// System.out.println("*********************** sort, filter on List");
|
||||
//
|
||||
// return super.getPage(institutionId, pageNumber, pageSize, sort, allRequestParams, request);
|
||||
//
|
||||
//// final Collection<Exam> exams = this.examDAO
|
||||
//// .allMatching(new FilterMap(
|
||||
//// allRequestParams,
|
||||
//// request.getQueryString()),
|
||||
//// this::hasReadAccess)
|
||||
//// .getOrThrow();
|
||||
////
|
||||
//// return this.paginationService.buildPageFromList(
|
||||
//// pageNumber,
|
||||
//// pageSize,
|
||||
//// sort,
|
||||
//// exams,
|
||||
//// pageSort(sort));
|
||||
// }
|
||||
// }
|
||||
|
||||
@RequestMapping(
|
||||
path = API.MODEL_ID_VAR_PATH_SEGMENT
|
||||
|
@ -586,13 +590,13 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
|||
}
|
||||
|
||||
if (sortBy.equals(Exam.FILTER_ATTR_NAME) || sortBy.equals(QuizData.QUIZ_ATTR_NAME)) {
|
||||
list.sort(Comparator.comparing(exam -> exam.name));
|
||||
list.sort(Comparator.comparing(exam -> (exam.name != null) ? exam.name : StringUtils.EMPTY));
|
||||
}
|
||||
if (sortBy.equals(Exam.FILTER_ATTR_TYPE)) {
|
||||
list.sort(Comparator.comparing(exam -> exam.type));
|
||||
list.sort(Comparator.comparing(exam -> (exam.type != null) ? exam.type : ExamType.UNDEFINED));
|
||||
}
|
||||
if (sortBy.equals(QuizData.FILTER_ATTR_START_TIME) || sortBy.equals(QuizData.QUIZ_ATTR_START_TIME)) {
|
||||
list.sort(Comparator.comparing(exam -> exam.startTime));
|
||||
list.sort(Comparator.comparing(exam -> (exam.startTime != null) ? exam.startTime : new DateTime(0)));
|
||||
}
|
||||
|
||||
if (PageSortOrder.DESCENDING == PageSortOrder.getSortOrder(sort)) {
|
||||
|
|
Loading…
Reference in a new issue