Skip to content

Commit

Permalink
Merge pull request #530 from EUSurvey/develop
Browse files Browse the repository at this point in the history
Patches since sprint 29
  • Loading branch information
clam2310 authored Apr 30, 2024
2 parents 8a29f4b + 4322078 commit dad2507
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 21 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<artifactId>eusurvey</artifactId>
<name>eusurvey</name>
<packaging>war</packaging>
<version>1.5.3</version>
<version>1.5.3.1</version>
<properties>
<java-version>11</java-version>
<org.springframework-version>5.3.20</org.springframework-version>
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/ec/survey/controller/RunnerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -1647,7 +1647,17 @@ public ModelAndView processDraftSubmit(@PathVariable String mode, HttpServletReq
&& user != null) {
draft.getAnswerSet().setResponderEmail(user.getEmail());
}


//check that all readonly mandatory questions are answered
Question q = SurveyHelper.getFirstUnansweredMandatoryReadonlyQuestion(draft.getAnswerSet());
if (q != null) {
String errorMessage = "Save as draft rejected as the draft contribution would be missing a value for this mandatory read-only question: " + q.getUniqueId();
logger.error(errorMessage);
ModelAndView model = new ModelAndView(Constants.VIEW_ERROR_GENERIC);
model.addObject(Constants.MESSAGE, errorMessage);
return model;
}

try {
answerService.saveDraft(draft, true);
uid = draft.getUniqueId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.ec.survey.tools.Constants;
import com.ec.survey.tools.ConversionTools;
import com.ec.survey.tools.MissingAnswersForReadonlyMandatoryQuestionException;
import com.ec.survey.tools.SurveyHelper;
import com.ec.survey.tools.Tools;
import com.ec.survey.tools.Ucs2Utf8;
import com.ec.survey.tools.export.XmlExportCreator;
Expand Down Expand Up @@ -1330,6 +1331,14 @@ private Survey getSurvey(String alias, User user, HttpServletRequest request, Ht
response.setStatus(412);
return "";
}

//check that all readonly mandatory questions are answered
Question q = SurveyHelper.getFirstUnansweredMandatoryReadonlyQuestion(draft.getAnswerSet());
if (q != null) {
logger.error("prefill call rejected as the draft contribution would be missing a value for this mandatory read-only question: " + q.getUniqueId());
response.setStatus(412);
return "";
}

try {
answerService.saveDraft(draft, true);
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/ec/survey/tools/SurveyHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,31 @@ public static boolean validateElement(Element element, AnswerSet answerSet,
return false;
}
}

public static Question getFirstUnansweredMandatoryReadonlyQuestion(AnswerSet answerSet) {
//check that all readonly mandatory questions are answered
for (Question question : answerSet.getSurvey().getQuestions()) {
if (question instanceof MatrixOrTable && question.getReadonly()) {
MatrixOrTable m = (MatrixOrTable) question;
for (Element sub : m.getQuestions()) {
if (sub instanceof Text) {
Text t = (Text)sub;
if (!t.getOptional()) {
if (answerSet.getAnswers(t.getUniqueId()).isEmpty()) {
return t;
}
}
}
}
} else if (!question.getOptional() && question.getReadonly()) {
if (answerSet.getAnswers(question.getUniqueId()).isEmpty()) {
return question;
}
}
}

return null;
}

public static boolean checkDependencies(List<Element> questiondependencies, Element element, Question question, Matrix parent, AnswerSet answerSet, Set<String> invisibleElements) {
boolean found = false;
Expand Down
75 changes: 58 additions & 17 deletions src/main/java/com/ec/survey/tools/export/XmlExportCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import com.ec.survey.model.survey.*;
import com.ec.survey.model.survey.ComplexTableItem.CellType;
import com.ec.survey.model.survey.base.File;
import com.ec.survey.model.survey.quiz.QuizResult;
import com.ec.survey.tools.Constants;
import com.ec.survey.tools.ConversionTools;
import com.ec.survey.tools.QuizHelper;
import com.ec.survey.tools.Tools;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
Expand Down Expand Up @@ -420,13 +422,7 @@ public void exportContent(boolean sync, Export export, boolean fromWebService) t
FilesByType<String> explanationFilesToExport = new FilesByType<>();

HashMap<String, Object> values = new HashMap<>();

Map<String, String> ECASUserLoginsByEmail = null;

if (export.getAddMeta()) {
ECASUserLoginsByEmail = administrationService.getECASUserLoginsByEmail();
}


ResultFilter origFilter = answerService.initialize(export.getResultFilter());
ResultFilter filterWithMeta = export == null ? null : origFilter.copy();

Expand Down Expand Up @@ -461,13 +457,20 @@ public void exportContent(boolean sync, Export export, boolean fromWebService) t
}

filterWithMeta.setExportedQuestions(filterWithMeta.getVisibleQuestions());

List<List<String>> answersets = reportingService.getAnswerSets(form.getSurvey(), filterWithMeta, null, false,

// for quiz surveys we need the original answerSet instances in order to compute the scores
List<List<String>> answersets = form.getSurvey().getIsQuiz() ? null : reportingService.getAnswerSets(form.getSurvey(), filterWithMeta, null, false,
true, true, true, true, false);

Map<String, List<File>> uploadedFilesByQuestionUID = new HashMap<>();

writer.writeStartElement("Answers");

Map<String, String> ECASUserLoginsByEmail = null;

if (export.getAddMeta() || filterWithMeta.exported("user")) {
ECASUserLoginsByEmail = administrationService.getECASUserLoginsByEmail();
}

if (answersets != null) {

Expand Down Expand Up @@ -770,17 +773,25 @@ void parseAnswerSet(Survey survey, XMLStreamWriter writer, List<Element> questio
if (meta || filter == null || filter.exported("languages"))
writer.writeAttribute("lang", answerSet == null ? row.get(rowPosMap.get("languages")) : answerSet.getLanguageCode());

if (meta || filter == null || filter.exported("user"))
writer.writeAttribute("user", answerSet == null ? row.get(rowPosMap.get("user"))
: answerSet.getResponderEmail() != null ? answerSet.getResponderEmail() : "");
if (meta || filter == null || filter.exported("user"))
if (survey.getSecurity().contains("anonymous")) {
writer.writeAttribute("user", "Anonymous");
} else {
writer.writeAttribute("user", answerSet == null ? row.get(rowPosMap.get("user")): answerSet.getResponderEmail() != null ? answerSet.getResponderEmail() : "");
}

if (meta || filter == null || filter.exported("invitation"))
writer.writeAttribute("invitation", answerSet == null ? row.get(rowPosMap.get("invitation"))
: answerSet.getInvitationId() != null ? answerSet.getInvitationId() : "");
if (survey.getIsOPC() && (meta || filter == null || filter.exported("user"))) {
String suser = answerSet == null ? row.get(rowPosMap.get("user")) : answerSet.getResponderEmail();
if (suser != null && suser.contains("@") && ECASUserLoginsByEmail != null
&& ECASUserLoginsByEmail.containsKey(suser)) {
writer.writeAttribute("userlogin", ECASUserLoginsByEmail.get(suser));
if (meta || filter == null || filter.exported("user")) {
if (survey.getSecurity().contains("anonymous")) {
writer.writeAttribute("userlogin", "Anonymous");
} else {
String suser = answerSet == null ? row.get(rowPosMap.get("user")) : answerSet.getResponderEmail();
if (suser != null && suser.contains("@") && ECASUserLoginsByEmail != null
&& ECASUserLoginsByEmail.containsKey(suser)) {
writer.writeAttribute("userlogin", ECASUserLoginsByEmail.get(suser));
}
}
}

Expand Down Expand Up @@ -1160,6 +1171,36 @@ void parseAnswerSet(Survey survey, XMLStreamWriter writer, List<Element> questio
}
}
}

if (survey.getIsQuiz()) {
QuizResult quizResult = QuizHelper.getQuizResult(answerSet, survey);
writer.writeStartElement("Scores");

if (survey.getScoresByQuestion()) {
for (Element element : survey.getQuestionsAndSections()) {
if (element instanceof Section) {
String score = quizResult.getSectionScore(element.getUniqueId());
if (!score.equals("0/0")) {
writer.writeStartElement("Section");
writer.writeAttribute("id", element.getUniqueId());
writer.writeCharacters(score);
writer.writeEndElement(); // Section
}
} else if (element instanceof ChoiceQuestion || element instanceof FreeTextQuestion || element instanceof NumberQuestion || element instanceof DateQuestion) {
Question question = (Question) element;
if (question.getScoring() > 0) {
writer.writeStartElement("Question");
writer.writeAttribute("id", element.getUniqueId());
writer.writeCharacters(quizResult.getQuestionScore(element.getUniqueId()) + "/" + quizResult.getQuestionMaximumScore(element.getUniqueId()));
writer.writeEndElement(); // Question
}
}
}
}

writer.writeEndElement(); // Score
}

writer.writeEndElement(); // AnswerSet
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@
style="margin-top: 5px; display: none;">
</c:when>
<c:when test="${element.getType() == 'Matrix' && element.getAllQuestionsDependent() && ((invisibleElements == null && forpdf == null) || invisibleElements.contains(element.uniqueId))}">
<div class="emptyelement survey-element untriggered dependent 2" data-useAndLogic="${element.useAndLogic}"
<div class="emptyelement survey-element untriggered 2" data-useAndLogic="${element.useAndLogic}"
id="${element.id}" data-id="${element.id}"
data-uid="${element.uniqueId}"
data-triggers="${element.triggers}" style="display: none;">
Expand Down
2 changes: 1 addition & 1 deletion src/main/webapp/resources/js/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ function handleElement(active, elementIds, i) {

if ($(element).hasClass("matrix-question")) {
var matrixItem = $(element).closest(".matrixitem");
if (matrixItem.length > 0 && !isTriggered(matrixItem, true)) {
if (matrixItem.length > 0 && $(matrixItem).hasClass("dependent") && !isTriggered(matrixItem, true)) {
//hide matrix if dependencies of matrix itself aren't fulfilled although a subquestion may be visible
matrixItem.addClass("untriggered").hide();
$(element).find(".matrix-question").each(function(){
Expand Down

0 comments on commit dad2507

Please sign in to comment.