diff --git a/assignment/api/src/resources/assignment.properties b/assignment/api/src/resources/assignment.properties index 89f986437b23..e88ed47392fc 100644 --- a/assignment/api/src/resources/assignment.properties +++ b/assignment/api/src/resources/assignment.properties @@ -673,8 +673,9 @@ range.allgroups = site group = Group groups = Groups +group.sitegradebook.info=This site is configured to have several gradebooks, so you must choose the groups and then their category or a corresponding grade item. group.sitegradebook.items.error=Selected groups must have a gradebook item associated with them -group.sitegradebook.nopermission=Assignments for the entire site cannot be created when using group based gradebooks. +group.sitegradebook.nopermission=Assignments cannot for all sections/groups because the course is set up with different instances per grade group. group.sitegradebook.categories.error=The selected categories must be associated with their corresponding group. group.editsite.nopermission = Cannot edit the group state due to site permissions. group.list.summary = Table contains list of groups. First will contain checkboxes, second will contain the group name, third the group description. Header links can be used to sort diff --git a/assignment/api/src/resources/assignment_ca.properties b/assignment/api/src/resources/assignment_ca.properties index b42c6becc165..ce56ffa1704a 100644 --- a/assignment/api/src/resources/assignment_ca.properties +++ b/assignment/api/src/resources/assignment_ca.properties @@ -647,8 +647,9 @@ range.allgroups=tot l\u2019espai group=Grup groups=Grups -group.sitegradebook.items.error=Els grups seleccionats han de tindre associat un ítem del llibre de qualificacions -group.sitegradebook.nopermission=No es poden crear tasques de lloc en tindre qualificacions de grup. +group.sitegradebook.info=Este lloc est\u00e0 configurat per a tindre diversos llibres de qualificacions, per tant s'hauran de triar els grups i posteriorment la seua categoria o un item de qualificaci\u00f3 corresponent. +group.sitegradebook.items.error=Els grups seleccionats han de tindre associat un \u00edtem del llibre de qualificacions +group.sitegradebook.nopermission=No es poden crear tasques per a totes les seccions/grups perqu\u00e8 el curs est\u00e0 configurat amb inst\u00e0ncies diferents per grup de qualificacions. group.sitegradebook.categories.error=Les categories seleccionades han d'estar associades al seu grup corresponent. group.editsite.nopermission=No teniu els permisos corresponents en aquest espai per editar l\u2019estat del grup group.list.summary=La taula cont\u00e9 una llista de grups. La primera columna contindr\u00e0 caselles de selecci\u00f3; la segona, el nom del grup; la tercera, la descripci\u00f3 del grup. Els enlla\u00e7os de l\u2019encap\u00e7alament es poden utilitzar per ordenar diff --git a/assignment/api/src/resources/assignment_es.properties b/assignment/api/src/resources/assignment_es.properties index bfd351777f45..71d772279368 100644 --- a/assignment/api/src/resources/assignment_es.properties +++ b/assignment/api/src/resources/assignment_es.properties @@ -673,9 +673,10 @@ range.allgroups=sitio group=Grupo groups=Grupos +group.sitegradebook.info=Este sitio est\u00e1 configurado para tener varios libros de calificaciones, por lo tanto se deber\u00e1n escoger los grupos y posteriormente su categor\u00eda o un item de calificaci\u00f3n correspondiente. group.sitegradebook.items.error=Los grupos seleccionados deben tener asociado un item del libro de calificaciones -group.sitegradebook.nopermission=No se pueden crear tareas de sitio al tener calificaciones de grupo. -group.sitegradebook.categories.error=Las categorías seleccionadas deben estar asociadas a su grupo correspondiente. +group.sitegradebook.nopermission=No se pueden crear tareas para todas las secciones/grupos debido a que el curso est\u00e1 configurado con instancias diferentes por grupo de calificaciones +group.sitegradebook.categories.error=Las categor\u00edas seleccionadas deben estar asociadas a su grupo correspondiente. group.editsite.nopermission=No se puede editar el estado del grupo debido a los permisos del sitio. group.list.summary=Lista de grupos. La primera columna contiene casillas de selecci\u00f3n, la segunda el nombre del grupo y la tercera su descripci\u00f3n. Los enlaces de la cabecera de la tabla permiten ordenar sus entradas. group.list.descr=Descripci\u00f3n diff --git a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java index e207839f0df2..ec7d26d984e8 100644 --- a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java +++ b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java @@ -4297,9 +4297,11 @@ protected String build_instructor_grade_submission_context(VelocityPortlet portl } } - Long associateGradebookAssignmentId = gbAssignment.getId(); - context.put("associatedToGbItem", true); - context.put("associatedToGbEntityId", associateGradebookAssignmentId); + if (gbAssignment != null) { + Long associateGradebookAssignmentId = gbAssignment.getId(); + context.put("associatedToGbItem", true); + context.put("associatedToGbEntityId", associateGradebookAssignmentId); + } } catch (AssessmentNotFoundException e) { log.error("Assignment not found while building grade submission context for custom gradebook item due to: {} {}", e.toString(), ExceptionUtils.getStackTrace(e)); } @@ -11037,17 +11039,20 @@ public void doDelete_assignment(RunData data) { } } - String associateGradebookAssignment = properties.get(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT); - String title = assignment.getTitle(); // remove rubric association if there is one rubricsService.softDeleteRubricAssociation(AssignmentConstants.TOOL_ID, id); - // remove from Gradebook - List gradebookUids = gradingService.getGradebookUidByExternalId(associateGradebookAssignment); - for (String gradebookUid : gradebookUids) { - addAlerts(state, assignmentToolUtils.integrateGradebook(stateToMap(state), gradebookUid, ref, associateGradebookAssignment, "remove", null, null, -1, null, null, null, -1)); + String associateGradebookAssignment = properties.get(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT); + List itemList = Arrays.asList(associateGradebookAssignment.split(",")); + Set itemSet = new HashSet<>(itemList); + for (String item : itemSet) { + // remove from Gradebook + List gradebookUids = gradingService.getGradebookUidByExternalId(item); + for (String gradebookUid : gradebookUids) { + addAlerts(state, assignmentToolUtils.integrateGradebook(stateToMap(state), gradebookUid, ref, item, "remove", null, null, -1, null, null, null, -1)); + } } // we use to check "assignment.delete.cascade.submission" setting. But the implementation now is always remove submission objects when the assignment is removed. // delete assignment and its submissions altogether diff --git a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentToolUtils.java b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentToolUtils.java index 567e8987c167..cf01b5b5d534 100644 --- a/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentToolUtils.java +++ b/assignment/tool/src/java/org/sakaiproject/assignment/tool/AssignmentToolUtils.java @@ -454,13 +454,17 @@ public void gradeSubmission(AssignmentSubmission submission, String gradeOption, alerts.addAll(integrateGradebook(options, gradebookUid, aReference, item, null, null, null, -1, null, sReference, op, -1)); } else { // In this case, we need to find the item in the list that matches the group being iterated. - Long itemId = Long.parseLong(item); + try { + Long itemId = Long.parseLong(item); - GradebookAssignment gradebookAssignment = gradingService.getGradebookAssigment(gradebookUid, itemId); + GradebookAssignment gradebookAssignment = gradingService.getGradebookAssigment(gradebookUid, itemId); - if (gradebookAssignment != null && gradebookAssignment.getGradebook() != null && - gradebookAssignment.getGradebook().getUid().equals(gradebookUid)) { - alerts.addAll(integrateGradebook(options, gradebookUid, aReference, item, null, null, null, -1, null, sReference, op, -1)); + if (gradebookAssignment != null && gradebookAssignment.getGradebook() != null && + gradebookAssignment.getGradebook().getUid().equals(gradebookUid)) { + alerts.addAll(integrateGradebook(options, gradebookUid, aReference, item, null, null, null, -1, null, sReference, op, -1)); + } + } catch (NumberFormatException e) { + log.error("Exception trying to parse item value {} : {} ", item, e); } } } diff --git a/assignment/tool/src/webapp/vm/assignment/instructor_new_edit/assignto_section.vm b/assignment/tool/src/webapp/vm/assignment/instructor_new_edit/assignto_section.vm index f7248fc288c5..8e1babb077eb 100644 --- a/assignment/tool/src/webapp/vm/assignment/instructor_new_edit/assignto_section.vm +++ b/assignment/tool/src/webapp/vm/assignment/instructor_new_edit/assignto_section.vm @@ -27,6 +27,10 @@ can be either all members of the site, all members of selected groups, or the se

$tlang.getString("gen.cant.change.after.draft")

+#if ($isGradebookGroupEnabled) +
$tlang.getString("group.sitegradebook.info")
+#end + ## Radio Option 1: Each individual member of the site #if($allowAddSiteAssignment)
diff --git a/lessonbuilder/api/src/resources/lessons.properties b/lessonbuilder/api/src/resources/lessons.properties index f16589d6cd49..43836e72cdba 100644 --- a/lessonbuilder/api/src/resources/lessons.properties +++ b/lessonbuilder/api/src/resources/lessons.properties @@ -826,6 +826,8 @@ simplepage.question-show-poll-option=Show students a graph of how others respond simplepage.missing-question-text=Please supply text for the question simplepage.question-need-2=Please supply at least 2 alternatives for this question +simplepage.multi_gradebook.no_group=This item cannot be published for all sections/groups because the course is set up with different instances per grade group. + simplepage.add_layout=Add Layout simplepage.layoutlinktext=Add Layout simplepage.layout-descrip=Select a preconfigured layout to add to the bottom of this page. diff --git a/lessonbuilder/api/src/resources/lessons_ca.properties b/lessonbuilder/api/src/resources/lessons_ca.properties index d94e316ddb59..e06d91fd6655 100644 --- a/lessonbuilder/api/src/resources/lessons_ca.properties +++ b/lessonbuilder/api/src/resources/lessons_ca.properties @@ -824,6 +824,8 @@ simplepage.question-show-poll-option=Mostra als estudiants, un cop hagin respost simplepage.missing-question-text=Introdu\u00efu un text per a la pregunta simplepage.question-need-2=En aquesta pregunta cal introduir almenys dues alternatives +simplepage.multi_gradebook.no_group=No es puc publicar aquest item per a totes les seccions/grups perqu\u00e8 el curs est\u00e0 configurat amb inst\u00e0ncies diferents per grup de qualificacions. + simplepage.add_layout=Afegeix el format simplepage.layoutlinktext=Afegeix el format simplepage.layout-descrip=Seleccioneu un format preconfigurar per afegir-lo a la part inferior de la p\u00e0gina diff --git a/lessonbuilder/api/src/resources/lessons_es.properties b/lessonbuilder/api/src/resources/lessons_es.properties index 6328b1db6e22..adac30c93bbd 100644 --- a/lessonbuilder/api/src/resources/lessons_es.properties +++ b/lessonbuilder/api/src/resources/lessons_es.properties @@ -825,6 +825,8 @@ simplepage.question-show-poll-option=Mostrar un gr\u00e1fico que indique, tras simplepage.missing-question-text=Por favor, especifique un texto para la pregunta simplepage.question-need-2=Por favor, suministre por lo menos dos alternativas para esta pregunta +simplepage.multi_gradebook.no_group=No se puede publicar este item para todas las secciones/grupos debido a que el curso est\u00e1 configurado con instancias diferentes por grupo de calificaciones + simplepage.add_layout=A\u00f1adir vista simplepage.layoutlinktext=A\u00f1adir vista simplepage.layout-descrip=Seleccionar una maquetaci\u00f3n predise\u00f1ada para a\u00f1adirla al final de la p\u00e1gina. diff --git a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/GradebookIfc.java b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/GradebookIfc.java index 4afe7be81bfd..ee51a5371e5c 100644 --- a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/GradebookIfc.java +++ b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/GradebookIfc.java @@ -85,6 +85,23 @@ public boolean removeExternalAssessment(final String gradebookUid, final String return true; } + public boolean removeExternalAssessmentByGradebookList(List gradebookUidList, final String externalId) { + if (gradebookUidList != null && gradebookUidList.size() > 0) { + for (String gradebookUid : gradebookUidList) { + try { + gradingService.removeExternalAssignment(gradebookUid, externalId, LessonBuilderConstants.TOOL_ID); + } catch (Exception e) { + log.error("Failed removing external gradebook with id {} : {}", externalId, e); + return false; + } + } + + return true; + } else { + return false; + } + } + public boolean updateExternalAssessmentScore(final String gradebookUid, final String siteId, final String externalId, final String studentUid, final String points) { try { diff --git a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/GradingBean.java b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/GradingBean.java index 74eadd6d2b90..f628d0a04d54 100644 --- a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/GradingBean.java +++ b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/GradingBean.java @@ -117,14 +117,18 @@ private boolean gradeComment() { } String gradebookId = null; - Integer maxpoints = null; + + SimplePageItem gbItem; + if (studentPage != null) { gradebookId = topItem.getAltGradebook(); maxpoints = topItem.getAltPoints(); + gbItem = topItem; } else { gradebookId = commentItem.getGradebookId(); maxpoints = commentItem.getGradebookPoints(); + gbItem = commentItem; } Double newpoints = Double.valueOf(points); @@ -140,7 +144,7 @@ private boolean gradeComment() { try { List gradebookUids = Arrays.asList(simplePageBean.getCurrentSiteId()); if (gradebookIfc.isGradebookGroupEnabled(simplePageBean.getCurrentSiteId())) { - gradebookUids = new ArrayList(simplePageBean.getItemGroups(topItem, null, false)); + gradebookUids = new ArrayList(simplePageBean.getItemGroups(gbItem, null, false)); } for (String gradebookUid : gradebookUids) { r = gradebookIfc.updateExternalAssessmentScore(gradebookUid, simplePageBean.getCurrentSiteId(), gradebookId, comment.getAuthor(), Double.toString(newpoints)); diff --git a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java index 30c6649fb6ae..cf7e820f4fe5 100644 --- a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java +++ b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/beans/SimplePageBean.java @@ -7469,91 +7469,116 @@ public String addComment() { return "added-comment"; } - + public String updateComments() { if (!checkCsrf()) return "permission-failed"; if(canEditPage()) { SimplePageItem comment = findItem(itemId); - + comment.setAnonymous(anonymous); - setItemGroups(comment, selectedGroups); comment.setRequired(required); comment.setPrerequisite(prerequisite); - - if(maxPoints == null || maxPoints.equals("")) { + + if (maxPoints == null || maxPoints.equals("")) { maxPoints = "1"; } - - if(graded) { - int points; - try { - points = Integer.valueOf(maxPoints); - }catch(Exception ex) { - setErrMessage(messageLocator.getMessage("simplepage.integer-expected")); + + if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId()) && (selectedGroups == null || selectedGroups.length <= 0)) { + setErrMessage(messageLocator.getMessage("simplepage.multi_gradebook.no_group")); + return "failure"; + } + + Integer points = parseMaxPoints(maxPoints); + + if (graded) { + if (points == null) { return "failure"; } - - if(comment.getGradebookId() == null || !comment.getGradebookPoints().equals(points)) { - String pageTitle; - String gradebookId; - - boolean add = true; - List gradebookUids = Arrays.asList(getCurrentSiteId()); + + String pageTitle; + String gradebookId; + boolean add = true; + + List gradebookUids = Arrays.asList(getCurrentSiteId()); + List commentGroupList = comment.getGroups() != null ? Arrays.asList(comment.getGroups().split(",")) : new ArrayList<>(); + + if (comment.getPageId() >= 0) { + pageTitle = getPage(comment.getPageId()).getTitle(); + gradebookId = "lesson-builder:comment:" + comment.getId(); + + String commentTitle = " Comments (item:" + comment.getId() + ")"; + if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { gradebookUids = Arrays.asList(selectedGroups); - } - if(comment.getPageId() >= 0) { - pageTitle = getPage(comment.getPageId()).getTitle(); - gradebookId = "lesson-builder:comment:" + comment.getId(); - - if(comment.getGradebookId() != null && !comment.getGradebookPoints().equals(points)) { - add = gradebookIfc.updateExternalAssessment(gradebookUids, "lesson-builder:comment:" + comment.getId(), null, - pageTitle + " Comments (item:" + comment.getId() + ")", Integer.valueOf(maxPoints), null); + + List addedGroups = buildGradebookUidList(commentGroupList, gradebookUids, "CREATE"); + List updatedGroups = buildGradebookUidList(commentGroupList, gradebookUids, "UPDATE"); + List deletedGroups = buildGradebookUidList(commentGroupList, gradebookUids, "DELETE"); + + if (addedGroups != null && addedGroups.size() > 0) { + add = gradebookIfc.addExternalAssessment(addedGroups, getCurrentSiteId(), gradebookId, null, + pageTitle + commentTitle, Integer.valueOf(maxPoints), null, LessonBuilderConstants.TOOL_ID); + } + + if (updatedGroups != null && updatedGroups.size() > 0) { + add = gradebookIfc.updateExternalAssessment(updatedGroups, gradebookId, null, + pageTitle + commentTitle, Integer.valueOf(maxPoints), null); + } + + if (deletedGroups != null && deletedGroups.size() > 0) { + add = gradebookIfc.removeExternalAssessmentByGradebookList(deletedGroups, gradebookId); + } + + } else { + if (comment.getGradebookId() != null && !comment.getGradebookPoints().equals(points)) { + add = gradebookIfc.updateExternalAssessment(gradebookUids, gradebookId, null, + pageTitle + commentTitle, Integer.valueOf(maxPoints), null); } else { try { - add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), "lesson-builder:comment:" + comment.getId(), null, - pageTitle + " Comments (item:" + comment.getId() + ")", Integer.valueOf(maxPoints), null, LessonBuilderConstants.TOOL_ID); + add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), gradebookId, null, + pageTitle + commentTitle, Integer.valueOf(maxPoints), null, LessonBuilderConstants.TOOL_ID); } catch(ConflictingAssignmentNameException cane) { add = false; setErrMessage(messageLocator.getMessage("simplepage.existing-gradebook")); } } - if(!add) { - setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); - } else { - comment.setGradebookTitle(pageTitle + " Comments (item:" + comment.getId() + ")"); - } - }else { - // Must be a student page comments tool. - SimpleStudentPage studentPage = simplePageToolDao.findStudentPage(Long.valueOf(comment.getSakaiId())); - SimplePageItem studentPageItem = simplePageToolDao.findItem(studentPage.getItemId()); - - - //pageTitle = simplePageToolDao.findStudentPage(Long.valueOf(comment.getSakaiId())).getTitle(); - gradebookId = "lesson-builder:page-comment:" + studentPageItem.getId(); - } - - if(add) { - comment.setGradebookId(gradebookId); - comment.setGradebookPoints(points); - regradeComments(comment); + + if (!add) { + setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); + } else { + comment.setGradebookTitle(pageTitle + commentTitle); } + } else { + // Must be a student page comments tool. + SimpleStudentPage studentPage = simplePageToolDao.findStudentPage(Long.valueOf(comment.getSakaiId())); + SimplePageItem studentPageItem = simplePageToolDao.findItem(studentPage.getItemId()); + + gradebookId = "lesson-builder:page-comment:" + studentPageItem.getId(); + } + + if (add) { + comment.setGradebookId(gradebookId); + comment.setGradebookPoints(points); + regradeComments(comment); } - }else if(comment.getGradebookId() != null && comment.getPageId() >= 0) { + } else if (comment.getGradebookId() != null && comment.getPageId() >= 0) { gradebookIfc.removeExternalAssessment(getCurrentSiteId(), comment.getGradebookId()); comment.setGradebookId(null); comment.setGradebookPoints(null); + selectedGroups = new String[] {}; } - + + setItemGroups(comment, selectedGroups); + // Create or update a task String reference = "/lessonbuilder/item/" + comment.getId(); String title = getPage(comment.getPageId()).getTitle() + " - " + messageLocator.getMessage("simplepage.comments-task-title"); // Dashboard task widget: When a comment item is added create a task item for the site members. createOrUpdateTask(reference, getCurrentSiteId(), title, null); - + // for forced comments, the UI won't ever do this, but if // it does, update will fail with permissions update(comment); @@ -7909,64 +7934,45 @@ public String updateQuestion() { } - - int pointsInt = 10; - if(StringUtils.isNotBlank(maxPoints)) { - try { - pointsInt = Integer.valueOf(maxPoints); - }catch(Exception ex) { - setErrMessage(messageLocator.getMessage("simplepage.integer-expected")); - // can't fail, because it will leave an inconsistent items. So create one with default point value - // check in UI to make sure it can't happen - // return "failure"; - } + + Integer pointsInt = parseMaxPoints(maxPoints); + + if (pointsInt == null) { + return "failure"; } - - if (!graded || (gradebookTitle != null && gradebookTitle.trim().equals(""))) + + if (!graded || (gradebookTitle != null && gradebookTitle.trim().equals(""))) { gradebookTitle = null; + } + List questionGroupList = item.getGroups() != null ? Arrays.asList(item.getGroups().split(",")) : new ArrayList<>(); List gradebookUids = Arrays.asList(getCurrentSiteId()); + if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { gradebookUids = Arrays.asList(selectedGroups); - } - if(gradebookTitle != null && (item.getGradebookId() == null || item.getGradebookId().equals(""))) { - // Creating new gradebook entry - if (itemId != null && itemId < 0) { - saveItem(item); - } - String gradebookId = "lesson-builder:question:" + item.getId(); - String title = gradebookTitle; - if(title == null || title.equals("")) { - title = questionText; - } + List addedGroups = buildGradebookUidList(questionGroupList, gradebookUids, "CREATE"); + List updatedGroups = buildGradebookUidList(questionGroupList, gradebookUids, "UPDATE"); + List deletedGroups = buildGradebookUidList(questionGroupList, gradebookUids, "DELETE"); - try { - boolean add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), gradebookId, null, title, pointsInt, null, LessonBuilderConstants.TOOL_ID); - if(!add) { - setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); - }else { - item.setGradebookId(gradebookId); - item.setGradebookTitle(title); - } - } catch(ConflictingAssignmentNameException cane) { - setErrMessage(messageLocator.getMessage("simplepage.existing-gradebook")); + if (gradebookTitle != null) { + createGradebookItem(addedGroups, item, pointsInt); + updateGradebookItem(updatedGroups, item, pointsInt); + deleteGradebookItem(deletedGroups, item, questionGroupList); + } else { + deleteGradebookItem(questionGroupList, item, questionGroupList); + selectedGroups = new String[] {}; + } + } else { + if (gradebookTitle != null && (item.getGradebookId() == null || item.getGradebookId().equals(""))) { + createGradebookItem(gradebookUids, item, pointsInt); + } else if (gradebookTitle != null) { + updateGradebookItem(gradebookUids, item, pointsInt); + } else if(gradebookTitle == null && (item.getGradebookId() != null && !item.getGradebookId().equals(""))) { + deleteGradebookItem(gradebookUids, item, new ArrayList<>()); } - }else if(gradebookTitle != null) { - // Updating an old gradebook entry - - gradebookIfc.updateExternalAssessment(gradebookUids, item.getGradebookId(), null, gradebookTitle, pointsInt, null); - - item.setGradebookTitle(gradebookTitle); - }else if(gradebookTitle == null && (item.getGradebookId() != null && !item.getGradebookId().equals(""))) { - // Removing an existing gradebook entry - - gradebookIfc.removeExternalAssessment(getCurrentSiteId(), item.getGradebookId()); - item.setGradebookId(null); - item.setGradebookTitle(null); - } - + item.setAttribute("questionGraded", String.valueOf(graded)); item.setRequired(required); if (graded) @@ -8009,7 +8015,77 @@ public String updateQuestion() { return "success"; } - + + private List buildGradebookUidList(List groupList, List newGroupList, String type) { + if (type != null && !StringUtils.isBlank(type)) { + switch (type) { + case "CREATE": + List addedGroups = new ArrayList<>(newGroupList); + addedGroups.removeAll(groupList); + + return addedGroups; + case "UPDATE": + List updatedGroups = new ArrayList<>(newGroupList); + updatedGroups.retainAll(groupList); + + return updatedGroups; + case "DELETE": + List deletedGroups = new ArrayList<>(groupList); + deletedGroups.removeAll(newGroupList); + + return deletedGroups; + default: + return newGroupList; + } + } else { + return newGroupList; + } + } + + private void createGradebookItem(List creatableList, SimplePageItem item, Integer pointsInt) { + if (itemId != null && itemId < 0) { + saveItem(item); + } + + String gradebookId = "lesson-builder:question:" + item.getId(); + String title = gradebookTitle; + + if (title == null || title.equals("")) { + title = questionText; + } + + try { + boolean add = gradebookIfc.addExternalAssessment(creatableList, getCurrentSiteId(), gradebookId, null, title, pointsInt, null, LessonBuilderConstants.TOOL_ID); + if (!add) { + setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); + } else { + item.setGradebookId(gradebookId); + item.setGradebookTitle(title); + } + } catch(ConflictingAssignmentNameException cane) { + setErrMessage(messageLocator.getMessage("simplepage.existing-gradebook")); + } + } + + private void updateGradebookItem(List updateableList, SimplePageItem item, Integer pointsInt) { + if (updateableList != null && updateableList.size() > 0) { + gradebookIfc.updateExternalAssessment(updateableList, item.getGradebookId(), null, gradebookTitle, pointsInt, null); + + item.setGradebookTitle(gradebookTitle); + } + } + + private void deleteGradebookItem(List deleteableList, SimplePageItem item, List newGroupList) { + if (deleteableList != null && deleteableList.size() > 0) { + gradebookIfc.removeExternalAssessmentByGradebookList(deleteableList, item.getGradebookId()); + + if (newGroupList == null || newGroupList.isEmpty()) { + item.setGradebookId(null); + item.setGradebookTitle(null); + } + } + } + private void regradeAllQuestionResponses(long questionId) { List responses = simplePageToolDao.findQuestionResponses(questionId); for(SimplePageQuestionResponse response : responses) { @@ -8198,7 +8274,6 @@ public String updateStudent() { page.setShowPeerEval(peerEval); - setItemGroups(page, selectedGroups); if (studentSelectedGroups == null || studentSelectedGroups.length == 0) page.setOwnerGroups(""); else { @@ -8217,21 +8292,6 @@ public String updateStudent() { page.setOwnerGroups(ownerGroups.toString()); } - // TODO: this section currently does nothing but do a database call to get an item... Can it be removed? - // Update the comments tools to reflect any changes - if(comments) { - List pages = simplePageToolDao.findStudentPages(itemId); - for(SimpleStudentPage p : pages) { - if(p.getCommentsSection() != null) { - SimplePageItem item = simplePageToolDao.findItem(p.getCommentsSection()); - //if(item.isAnonymous() != forcedAnon) { - //item.setAnonymous(forcedAnon); - //update(item); - //} - } - } - } - // RU Rubrics // This function is called last. By the time this function is called, rubricRows has been created. //the peerEval should not be in here @@ -8249,101 +8309,84 @@ public String updateStudent() { if(StringUtils.isBlank(sMaxPoints)) { sMaxPoints = "1"; } - + + List studentPageGroupList = page.getGroups() != null + ? Arrays.asList(page.getGroups().split(",")) + : new ArrayList<>(); + + List gradebookUids = Arrays.asList(getCurrentSiteId()); + + if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { + gradebookUids = Arrays.asList(selectedGroups); + + if (gradebookUids == null || gradebookUids.size() <= 0) { + setErrMessage(messageLocator.getMessage("simplepage.multi_gradebook.no_group")); + return "failure"; + } + } + // Handle the grading of pages - if(graded) { - int points; - try { - points = Integer.valueOf(maxPoints); - }catch(Exception ex) { - setErrMessage(messageLocator.getMessage("simplepage.integer-expected")); + if (graded) { + Integer points = parseMaxPoints(maxPoints); + + if (points == null) { return "failure"; } - + if (StringUtils.isBlank(gradebookTitle)) { - gradebookTitle = getPage(page.getPageId()).getTitle() + " Student Pages (item:" + page.getId() + ")"; + gradebookTitle = getPage(page.getPageId()).getTitle() + " Student Pages (item:" + page.getId() + + ")"; } - if(page.getGradebookId() == null || !page.getGradebookPoints().equals(points) || - !page.getGradebookTitle().equals(gradebookTitle)) { - boolean add; - - List gradebookUids = Arrays.asList(getCurrentSiteId()); - if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { - gradebookUids = Arrays.asList(selectedGroups); - } - if (page.getGradebookId() != null && - (!page.getGradebookPoints().equals(points) || !page.getGradebookTitle().equals(gradebookTitle))) { - add = gradebookIfc.updateExternalAssessment(gradebookUids, "lesson-builder:page:" + page.getId(), null, gradebookTitle, Integer.valueOf(maxPoints), null); - } else { - try { - add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), "lesson-builder:page:" + page.getId(), null, gradebookTitle, Integer.valueOf(maxPoints), null, LessonBuilderConstants.TOOL_ID); - } catch(ConflictingAssignmentNameException cane) { - add = false; - setErrMessage(messageLocator.getMessage("simplepage.existing-gradebook")); - } - } - if(!add) { - setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); - }else { - page.setGradebookId("lesson-builder:page:" + page.getId()); - page.setGradebookTitle(gradebookTitle); - page.setGradebookPoints(points); - regradeStudentPages(page); - } + + String pageGradebookId = "lesson-builder:page:" + page.getId(); + + boolean add = buildGradebookPageItem(studentPageGroupList, gradebookUids, gradebookTitle, pageGradebookId, page, points, false); + + if (!add) { + setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); + } else { + page.setGradebookId(pageGradebookId); + page.setGradebookTitle(gradebookTitle); + page.setGradebookPoints(points); + regradeStudentPages(page); } - }else if(page.getGradebookId() != null) { + } else if (page.getGradebookId() != null) { gradebookIfc.removeExternalAssessment(getCurrentSiteId(), page.getGradebookId()); page.setGradebookId(null); page.setGradebookPoints(null); page.setGradebookTitle(null); } - + // Handling the grading of comments on pages - if(sGraded) { - int points; - try { - points = Integer.valueOf(sMaxPoints); - }catch(Exception ex) { - setErrMessage(messageLocator.getMessage("simplepage.integer-expected")); + if (sGraded) { + Integer pointsC = parseMaxPoints(sMaxPoints); + + if (pointsC == null) { return "failure"; } - - if(page.getAltGradebook() == null || !page.getAltPoints().equals(points)) { - String title = getPage(page.getPageId()).getTitle() + " Student Page Comments (item:" + page.getId() + ")"; - boolean add; - List gradebookUids = Arrays.asList(getCurrentSiteId()); - if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { - gradebookUids = Arrays.asList(selectedGroups); - } - if(page.getAltGradebook() != null && !page.getAltPoints().equals(points)) { - add = gradebookIfc.updateExternalAssessment(gradebookUids, "lesson-builder:page-comment:" + page.getId(), null, - title, points, null); - } else { - try { - add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), "lesson-builder:page-comment:" + page.getId(), null, - title, points, null, LessonBuilderConstants.TOOL_ID); - } catch(ConflictingAssignmentNameException cane) { - add = false; - setErrMessage(messageLocator.getMessage("simplepage.existing-gradebook")); - } - } - // The assessment couldn't be added - if(!add) { - setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); - }else { - page.setAltGradebook("lesson-builder:page-comment:" + page.getId()); - page.setAltGradebookTitle(title); - page.setAltPoints(points); - regradeStudentPageComments(page); - } + + String title = getPage(page.getPageId()).getTitle() + " Student Page Comments (item:" + page.getId() + ")"; + String pageCommentGradebookId = "lesson-builder:page-comment:" + page.getId(); + + boolean add = buildGradebookPageItem(studentPageGroupList, gradebookUids, title, pageCommentGradebookId, page, pointsC, true); + + if (!add) { + setErrMessage(messageLocator.getMessage("simplepage.no-gradebook")); + } else { + page.setAltGradebook(pageCommentGradebookId); + page.setAltGradebookTitle(title); + page.setAltPoints(pointsC); + regradeStudentPageComments(page); } - }else if(page.getAltGradebook() != null) { + } else if (page.getAltGradebook() != null) { gradebookIfc.removeExternalAssessment(getCurrentSiteId(), page.getAltGradebook()); page.setAltGradebook(null); page.setAltPoints(null); ungradeStudentPageComments(page); } - + + setItemGroups(page, selectedGroups); + // Create or update a task String reference = "/lessonbuilder/item/" + itemId; String title = getPage(page.getPageId()).getTitle() + " - " + messageLocator.getMessage("simplepage.student-contents-task-title"); @@ -8359,6 +8402,79 @@ public String updateStudent() { } } + public boolean buildGradebookPageItem(List groupList, List gradebookUids, + String pageGradebookTitle, String itemGradebookId, SimplePageItem simplePageItem, Integer pageItemPoints, boolean isStudentComment) { + boolean add = true; + + if (gradebookIfc.isGradebookGroupEnabled(getCurrentSiteId())) { + List addedGroups = new ArrayList<>(); + List updatedGroups = buildGradebookUidList(groupList, gradebookUids, "UPDATE"); + List deletedGroups = buildGradebookUidList(groupList, gradebookUids, "DELETE"); + + if (isStudentComment) { + if (simplePageItem.getAltGradebook() == null && simplePageItem.getAltPoints() == null) { + addedGroups = gradebookUids; + } else { + addedGroups = buildGradebookUidList(groupList, gradebookUids, "CREATE"); + } + } else { + if (simplePageItem.getGradebookId() == null && simplePageItem.getGradebookPoints() == null) { + addedGroups = gradebookUids; + } else { + addedGroups = buildGradebookUidList(groupList, gradebookUids, "CREATE"); + } + } + + if (addedGroups != null && addedGroups.size() > 0) { + add = gradebookIfc.addExternalAssessment(addedGroups, getCurrentSiteId(), itemGradebookId, + null, pageGradebookTitle, pageItemPoints, null, LessonBuilderConstants.TOOL_ID); + } + + if (updatedGroups != null && updatedGroups.size() > 0) { + add = gradebookIfc.updateExternalAssessment(updatedGroups, itemGradebookId, + null, pageGradebookTitle, pageItemPoints, null); + } + + if (deletedGroups != null && deletedGroups.size() > 0) { + add = gradebookIfc.removeExternalAssessmentByGradebookList(deletedGroups, itemGradebookId); + } + } else { + if (!isStudentComment) { + if (simplePageItem.getGradebookId() == null && simplePageItem.getGradebookPoints() == null && !StringUtils.isBlank(pageGradebookTitle)) { + add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), + itemGradebookId, null, pageGradebookTitle, + pageItemPoints, null, LessonBuilderConstants.TOOL_ID); + } else if (simplePageItem.getGradebookId() != null && (!simplePageItem.getGradebookPoints().equals(pageItemPoints) || + !simplePageItem.getGradebookTitle().equals(pageGradebookTitle))) { + add = gradebookIfc.updateExternalAssessment(gradebookUids, itemGradebookId, null, pageGradebookTitle, + pageItemPoints, null); + } + } else { + if (simplePageItem.getAltGradebook() == null && simplePageItem.getAltPoints() == null && + !StringUtils.isBlank(pageGradebookTitle)) { + add = gradebookIfc.addExternalAssessment(gradebookUids, getCurrentSiteId(), + itemGradebookId, null, pageGradebookTitle, + pageItemPoints, null, LessonBuilderConstants.TOOL_ID); + } else if (simplePageItem.getAltGradebook() != null && (!simplePageItem.getAltPoints().equals(pageItemPoints) || + !simplePageItem.getAltGradebook().equals(pageGradebookTitle))) { + add = gradebookIfc.updateExternalAssessment(gradebookUids, itemGradebookId, null, pageGradebookTitle, + pageItemPoints, null); + } + } + } + + return add; + } + + public Integer parseMaxPoints(String maxPoints) { + try { + return Integer.valueOf(maxPoints); + } catch (Exception ex) { + setErrMessage(messageLocator.getMessage("simplepage.integer-expected")); + return null; + } + } + public String missingStudentSetZero() { if (!checkCsrf()) return "permission-failed"; diff --git a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/producers/ShowPageProducer.java b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/producers/ShowPageProducer.java index f41df2fb3f68..50afe7ba86d6 100644 --- a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/producers/ShowPageProducer.java +++ b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/tool/producers/ShowPageProducer.java @@ -66,6 +66,7 @@ import org.sakaiproject.lessonbuildertool.SimpleStudentPage; import org.sakaiproject.lessonbuildertool.model.SimplePageToolDao; import org.sakaiproject.lessonbuildertool.service.BltiInterface; +import org.sakaiproject.lessonbuildertool.service.GradebookIfc; import org.sakaiproject.lessonbuildertool.service.LessonBuilderAccessService; import org.sakaiproject.lessonbuildertool.service.LessonEntity; import org.sakaiproject.lessonbuildertool.tool.beans.SimplePageBean; @@ -146,6 +147,7 @@ public class ShowPageProducer implements ViewComponentProducer, DefaultView, Nav private SimplePageBean simplePageBean; private SimplePageToolDao simplePageToolDao; + @Setter private GradebookIfc gradebookIfc; @Setter private AuthzGroupService authzGroupService; @Setter private SecurityService securityService; @Setter ContentHostingService contentHostingService; @@ -5284,7 +5286,9 @@ private void createQuestionDialog(UIContainer tofill, SimplePage currentPage) { UIBoundBoolean.make(form, "question-graded", "#{simplePageBean.graded}"); UIInput.make(form, "question-gradebook-title", "#{simplePageBean.gradebookTitle}"); UIInput.make(form, "question-max", "#{simplePageBean.maxPoints}"); - + + UIInput.make(form, "multi_gradebook", String.valueOf(gradebookIfc.isGradebookGroupEnabled(simplePageBean.getCurrentSiteId()))); + UIInput.make(form, "question-multiplechoice-answer-complete", "#{simplePageBean.addAnswerData}"); UIInput.make(form, "question-multiplechoice-answer-id", null); UIBoundBoolean.make(form, "question-multiplechoice-answer-correct"); diff --git a/lessonbuilder/tool/src/webapp/WEB-INF/requestContext.xml b/lessonbuilder/tool/src/webapp/WEB-INF/requestContext.xml index aee3f3172a9d..5174952da055 100644 --- a/lessonbuilder/tool/src/webapp/WEB-INF/requestContext.xml +++ b/lessonbuilder/tool/src/webapp/WEB-INF/requestContext.xml @@ -38,6 +38,7 @@ + diff --git a/lessonbuilder/tool/src/webapp/js/show-page.js b/lessonbuilder/tool/src/webapp/js/show-page.js index 76630afbd087..061b614393de 100644 --- a/lessonbuilder/tool/src/webapp/js/show-page.js +++ b/lessonbuilder/tool/src/webapp/js/show-page.js @@ -3453,6 +3453,11 @@ function prepareQuestionDialog() { $('#question-error').text(msg("simplepage.gbname-expected")); $('#question-error-container').show(); return false; + } else if ($("input[name='multi_gradebook-fossil']").length > 0 && $("input[name='multi_gradebook-fossil']").val().includes("true") && + $("input[name='group-list-span-selection']:checked").length === 0) { + $('#question-error').text(msg("simplepage.multi_gradebook.no_group")); + $('#question-error-container').show(); + return false; } else if ($("#question-text-area-evolved\\:\\:input").val() === '') { $('#question-error').text(msg("simplepage.missing-question-text")); $('#question-error-container').show(); diff --git a/lessonbuilder/tool/src/webapp/templates/ShowPage.html b/lessonbuilder/tool/src/webapp/templates/ShowPage.html index fc7026174742..97573da38a21 100644 --- a/lessonbuilder/tool/src/webapp/templates/ShowPage.html +++ b/lessonbuilder/tool/src/webapp/templates/ShowPage.html @@ -1343,6 +1343,8 @@

+ +

@@ -3310,6 +3312,9 @@

+ +

+

diff --git a/lti/lti-portlet/src/bundle/basiclti.properties b/lti/lti-portlet/src/bundle/basiclti.properties index b70dbff694af..ef95f4468d02 100644 --- a/lti/lti-portlet/src/bundle/basiclti.properties +++ b/lti/lti-portlet/src/bundle/basiclti.properties @@ -113,3 +113,5 @@ error.gradable.badcreate=Unable to create Gradebook item error.submit.timeout=Unable to send launch to remote URL +multi_gradebook.use_info=This site is configured to have several gradebooks, so you must choose the groups and then their category or a corresponding grade item. + diff --git a/lti/lti-portlet/src/bundle/basiclti_ca.properties b/lti/lti-portlet/src/bundle/basiclti_ca.properties index 60b7c0d67ceb..903b336fd8e5 100644 --- a/lti/lti-portlet/src/bundle/basiclti_ca.properties +++ b/lti/lti-portlet/src/bundle/basiclti_ca.properties @@ -114,3 +114,5 @@ error.gradable.badcreate=No s\u2019ha pogut crear l\u2019element de qualificaci\ error.submit.timeout=No s\u2019ha pogut enviar l\u2019ordre d\u2019inici a l\u2019adre\u00e7a URL remota +multi_gradebook.use_info=Este lloc està configurat per a tindre diversos llibres de qualificacions, per tant s'hauran de triar els grups i posteriorment la seua categoria o un item de qualificació corresponent. + diff --git a/lti/lti-portlet/src/bundle/basiclti_es.properties b/lti/lti-portlet/src/bundle/basiclti_es.properties index b7243144cc96..481ab707d16f 100644 --- a/lti/lti-portlet/src/bundle/basiclti_es.properties +++ b/lti/lti-portlet/src/bundle/basiclti_es.properties @@ -114,3 +114,5 @@ error.gradable.badcreate=No pudo crearse un \u00edtem de calificaci\u00f3n error.submit.timeout=Imposible realizar el lanzamiento a la URL remota +multi_gradebook.use_info=Este sitio está configurado para tener varios libros de calificaciones, por lo tanto se deberán escoger los grupos y posteriormente su categoría o un item de calificación correspondiente. + diff --git a/lti/lti-portlet/src/java/org/sakaiproject/portlets/IMSLTIPortlet.java b/lti/lti-portlet/src/java/org/sakaiproject/portlets/IMSLTIPortlet.java index 231aef206446..486fe12a42aa 100644 --- a/lti/lti-portlet/src/java/org/sakaiproject/portlets/IMSLTIPortlet.java +++ b/lti/lti-portlet/src/java/org/sakaiproject/portlets/IMSLTIPortlet.java @@ -343,6 +343,9 @@ public void prepareEdit(RenderRequest request) // For outcomes we check for tools in the site before offering the options String allowOutcomes = ServerConfigurationService.getString(SakaiLTIUtil.LTI_OUTCOMES_ENABLED, SakaiLTIUtil.LTI_OUTCOMES_ENABLED_DEFAULT); + GradingService gradingService = (GradingService) ComponentManager.get("org.sakaiproject.grading.api.GradingService"); + request.setAttribute("isGradebookGroupEnabled", gradingService.isGradebookGroupEnabled(getContext())); + boolean foundLessons = false; boolean foundGradebook = false; ToolConfiguration toolConfig = SiteService.findTool(placement.getId()); diff --git a/lti/lti-portlet/src/webapp/edit.jsp b/lti/lti-portlet/src/webapp/edit.jsp index 4486e15a49ec..fd5e7e19e0da 100644 --- a/lti/lti-portlet/src/webapp/edit.jsp +++ b/lti/lti-portlet/src/webapp/edit.jsp @@ -52,6 +52,8 @@ List assignments = (List) rReq.getAttribute("assignments"); Boolean allowOutcomes = (Boolean) rReq.getAttribute("allowOutcomes"); +Boolean isGradebookGroupEnabled = (Boolean) rReq.getAttribute("isGradebookGroupEnabled"); + Boolean allowRoster = (Boolean) rReq.getAttribute("allowRoster"); %> @@ -180,6 +182,12 @@ if ( document.getElementById("UISwitcher") ) switchui(); <%=rb.getString("gradable.newassignment.detail") %>

+<% if ( isGradebookGroupEnabled ) { %> +
+ <%=rb.getString("multi_gradebook.use_info") %> +
+<% } %> + <% } %> <% if ( allowOutcomes && allow(sp,"allowoutcomes") && assignments != null ) { %> diff --git a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages.properties b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages.properties index b2cd36537b83..0eb90e00b99a 100644 --- a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages.properties +++ b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages.properties @@ -1006,4 +1006,13 @@ pvt_enter_search_tags=Please select tags for search. cdfm_gradebook_group_selector_instructions=Please, select only one item from the gradebook for groups selector cdfm_gradebook_group_selector_error=You have selected more than one item in the gradebook for groups selector -cdfm_gradebook_group_selector_select_button=Select Item +cdfm_gradebook_group_selector_send_button=Select Item + +# MULTI GRADEBOOK +group_sitegradebook_group_error=The site is configured with different instances per gradebook group, so the "Automatically create forums for groups" option must be selected. +group_sitegradebook_items_must_select=At least one gradebook item must be selected. +group_sitegradebook_items_error=The selected groups must have an associated gradebook item. +group_sitegradebook_info=This site is configured to have multiple gradebooks, so groups must be selected first, followed by their category or the corresponding gradebook item. +group_sitegradebook_group_items_error=Group gradebook items cannot be assigned to generic forums. +group_sitegradebook_simple_forum=This forum has been created generically, so group gradebook items cannot be assigned. +group_sitegradebook_forum_group_item_error=The selected item must belong to the configured group. diff --git a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_ca.properties b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_ca.properties index 87267f41056f..83071432e31b 100644 --- a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_ca.properties +++ b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_ca.properties @@ -996,3 +996,12 @@ pvt_read_receipt_email_subject={0} ha estat llegit pvt_tags_header=Etiquetes pvt_tags_save=Desar Etiquetes pvt_enter_search_tags=Introdu\u00efu etiquetes per a la cerca. + +# MULTI GRADEBOOK +group_sitegradebook_group_error=El curs est\u00e0 configurat amb inst\u00e0ncies diferents per grups de qualificacions, per la qual cosa cal seleccionar l\u2019opci\u00f3 "Crea autom\u00e0ticament diversos f\u00f2rums pels grups". +group_sitegradebook_items_must_select=Heu de seleccionar almenys un item del llibre de qualificacions. +group_sitegradebook_items_error=Els grups seleccionats han de tindre associat un \u00edtem del llibre de qualificacions. +group_sitegradebook_info=Este lloc est\u00e0 configurat per a tindre diversos llibres de qualificacions, per tant s'hauran de triar els grups i posteriorment la seua categoria o un item de qualificaci\u00f3 corresponent. +group_sitegradebook_group_items_error=No es poden assignar \u00edtems de llibre de qualificacions grupals a f\u00f2rums gen\u00e8rics. +group_sitegradebook_simple_forum=Aquest f\u00f2rum s\u0027ha creat de manera gen\u00e8rica, per la qual cosa no es poden assignar \u00edtems de llibres de qualificacions grupals. +group_sitegradebook_forum_group_item_error=L\u0027\u00edtem seleccionat ha de pert\u00e0nyer al grup configurat. diff --git a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_es.properties b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_es.properties index 569979c09cfc..5430c9abbf0a 100644 --- a/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_es.properties +++ b/msgcntr/messageforums-api/src/bundle/org/sakaiproject/api/app/messagecenter/bundle/Messages_es.properties @@ -1000,4 +1000,13 @@ pvt_enter_search_tags=Introduzca etiquetas de b\u00fasqueda. cdfm_gradebook_group_selector_instructions=Por favor, elija s\u00f3lo un elemento en el selector de calificaciones por grupos cdfm_gradebook_group_selector_error=Has seleccionado m\u00e1s de un elemento en el selector de calificaciones por grupos -cdfm_gradebook_group_selector_select_button=Seleccionar elemento +cdfm_gradebook_group_selector_send_button=Seleccionar elemento + +# MULTI GRADEBOOK +group_sitegradebook_group_error=El curso est\u00e1 configurado con instancias diferentes por grupo de calificaciones por lo que se debe seleccionar la opción "Crear foros para grupos autom\u00e1ticamente". +group_sitegradebook_items_must_select=Se debe seleccionar al menos un item de calificaciones. +group_sitegradebook_items_error=Los grupos seleccionados deben tener asociado un item del libro de calificaciones. +group_sitegradebook_info=Este sitio est\u00e1 configurado para tener varios libros de calificaciones, por lo tanto se deber\u00e1n escoger los grupos y posteriormente su categor\u00eda o un item de calificaci\u00f3n correspondiente. +group_sitegradebook_group_items_error=No se pueden asignar items de libro de calificaciones grupales a foros genéricos. +group_sitegradebook_simple_forum=Este foro se ha creado de forma gen\u00e9rica, por lo que no se pueden asignar items de libros de calificaciones grupales. +group_sitegradebook_forum_group_item_error=El item seleccionado debe pertenecer al grupo configurado. diff --git a/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/DiscussionForumTool.java b/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/DiscussionForumTool.java index 0a99b8460307..ee00a4a51032 100644 --- a/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/DiscussionForumTool.java +++ b/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/DiscussionForumTool.java @@ -132,6 +132,7 @@ import org.sakaiproject.grading.api.AssessmentNotFoundException; import org.sakaiproject.grading.api.Assignment; import org.sakaiproject.grading.api.model.Gradebook; +import org.sakaiproject.grading.api.model.GradebookAssignment; import org.sakaiproject.grading.api.GradeDefinition; import org.sakaiproject.grading.api.GradingService; import org.sakaiproject.grading.api.SortType; @@ -159,6 +160,7 @@ import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.util.ResourceLoader; +import org.sakaiproject.util.StringUtil; import org.sakaiproject.util.api.FormattedText; import org.sakaiproject.util.comparator.GroupTitleComparator; import org.sakaiproject.util.comparator.RoleIdComparator; @@ -329,7 +331,12 @@ public class DiscussionForumTool { private static final String TASK_NOT_CREATED = "cdfm_cant_create_task"; private static final String MSG_PVT_ANSWER_PREFIX = "pvt_answer_title_prefix"; private static final String MSG_PVT_QUESTION_PREFIX = "pvt_question_title_prefix"; - + private static final String MULTI_GRADEBOOK_ITEMS_ERROR = "group_sitegradebook_items_error"; + private static final String MULTI_GRADEBOOK_ITEMS_MUST_SELECT = "group_sitegradebook_items_must_select"; + private static final String MULTI_GRADEBOOK_GROUP_ITEMS_ERROR = "group_sitegradebook_group_items_error"; + private static final String MULTI_GRADEBOOK_GROUP_FORUM_ITEMS_ERROR = "group_sitegradebook_forum_group_item_error"; + + private static final String FROM_PAGE = "msgForum:mainOrForumOrTopic"; /** * If deleting, the parameter determines where to navigate back to @@ -408,6 +415,9 @@ public class DiscussionForumTool { private boolean gradeByPercent; private boolean gradeByLetter; + private boolean discussionGeneric = false; + private String groupId; + /** * Dependency Injected */ @@ -676,26 +686,16 @@ public List getForums() { //Code to get the gradebook service from ComponentManager GradingService gradingService = getGradingService(); - if (gradingService.isGradebookGroupEnabled(toolManager.getCurrentPlacement().getContext())) { - List gradeAssignments = gradingService.getGradebookGroupInstances(toolManager.getCurrentPlacement().getContext()); - for(int i=0; i groupAssignments = gradingService.getAssignments(gradeAssignments.get(i).getId().toString(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE); - for (Assignment assignment: groupAssignments) { - assignments.add(new SelectItem(Long.toString(assignment.getId()), assignment.getName())); - } - } - } else { - List gradeAssignmentsBeforeFilter = gradingService.getAssignments(toolManager.getCurrentPlacement().getContext(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE); - for (Assignment thisAssign : gradingService.getAssignments(toolManager.getCurrentPlacement().getContext(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE)) { - if (!thisAssign.getExternallyMaintained()) { - try { - assignments.add(new SelectItem(Long.toString(thisAssign.getId()), thisAssign.getName())); - } catch (Exception e) { - log.error("DiscussionForumTool - processDfMsgGrd:" + e); - } - } - } - } + + for (Assignment thisAssign : gradingService.getAssignments(toolManager.getCurrentPlacement().getContext(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE)) { + if (!thisAssign.getExternallyMaintained()) { + try { + assignments.add(new SelectItem(Long.toString(thisAssign.getId()), thisAssign.getName())); + } catch (Exception e) { + log.error("DiscussionForumTool - processDfMsgGrd:" + e); + } + } + } } catch (SecurityException se) { log.debug("SecurityException caught while getting assignments.", se); @@ -734,14 +734,19 @@ public List getForums() { } } - decoForum.setGradeAssign(DEFAULT_GB_ITEM); - for (SelectItem ass : assignments) { - if (ass.getLabel().equals(forum.getDefaultAssignName()) || - ass.getValue().equals(forum.getDefaultAssignName())) { - decoForum.setGradeAssign((String) ass.getValue()); - break; - } - } + if (isGradebookGroupEnabled()) { + decoForum.setGradeAssign(forum.getDefaultAssignName()); + } else { + decoForum.setGradeAssign(DEFAULT_GB_ITEM); + for (SelectItem ass : assignments) { + if (ass.getLabel().equals(forum.getDefaultAssignName()) || + ass.getValue().equals(forum.getDefaultAssignName())) { + decoForum.setGradeAssign((String) ass.getValue()); + break; + } + } + } + forums.add(decoForum); } } @@ -1167,7 +1172,13 @@ public String processActionNewForum() } setNewForumBeanAssign(); - + + if (isGradebookGroupEnabled()) { + selectedForum.setRestrictPermissionsForGroups("true"); + setGroupId(null); + setDiscussionGeneric(false); + } + return FORUM_SETTING_REVISE; } else @@ -1223,9 +1234,24 @@ public String processActionForumSettings() selectedForum.setReadFullDesciption(true); } + String currentDefaultAssignName = forum.getDefaultAssignName(); + + selectedForum.setGradeAssign(currentDefaultAssignName); + + if (isGradebookGroupEnabled()) { + if (currentDefaultAssignName != null && !StringUtils.isBlank(currentDefaultAssignName)) { + GradingService gradingService = getGradingService(); + String gbUid = gradingService.getGradebookUidByAssignmentById(toolManager.getCurrentPlacement().getContext(), Long.parseLong(currentDefaultAssignName)); + setGroupId(gbUid); + setDiscussionGeneric(false); + } else { + setDiscussionGeneric(true); + } + } + setForumBeanAssign(); setFromMainOrForumOrTopic(); - + return FORUM_SETTING_REVISE; } @@ -1315,10 +1341,10 @@ public String processActionSaveForumSettings() setErrorMessage(getResourceBundleString(MULTIPLE_WINDOWS , new Object[] {ServerConfigurationService.getString("ui.service","Sakai")})); return FORUM_SETTING_REVISE; } - + if (selectedForum == null) throw new IllegalStateException("selectedForum == null"); - + if(selectedForum.getForum() != null && selectedForum.getForum().getOpenDate() != null && selectedForum.getForum().getCloseDate() != null && selectedForum.getForum().getAvailabilityRestricted()){ @@ -1356,6 +1382,45 @@ public String processActionSaveForumSettings() return processReturnToOriginatingPage(); } + public boolean checkMultiGradebook(boolean isForum) { + if (isGradebookGroupEnabled()) { + List selectedGroupList = new ArrayList<>(); + + for (SiteGroupBean siteGroup : siteGroups) { + if (siteGroup.getGroup() != null && (isForum && siteGroup.getCreateForumForGroup()) || (!isForum && siteGroup.getCreateTopicForGroup())) { + selectedGroupList.add(siteGroup.getGroup().getId()); + } + } + + String gradeAssign = ""; + + if (isForum) { + gradeAssign = selectedForum.getGradeAssign(); + } else { + gradeAssign = selectedTopic.getGradeAssign(); + } + + if (!StringUtils.isBlank(gradeAssign) && !gradeAssign.equals(DEFAULT_GB_ITEM)) { + GradingService gradingService = getGradingService(); + List gbItemList = Arrays.asList(gradeAssign.split(",")); + + boolean areItemsInGroups = + gradingService.checkMultiSelectorList(toolManager.getCurrentPlacement().getContext(), + selectedGroupList, gbItemList, false); + + if (!areItemsInGroups) { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_ITEMS_ERROR)); + return false; + } + } else { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_ITEMS_MUST_SELECT)); + return false; + } + } + + return true; + } + /** * @return */ @@ -1406,7 +1471,30 @@ public String processActionSaveForumAsDraft() return processReturnToOriginatingPage(); } - private DiscussionForum processForumSettings(boolean draft){ + private DiscussionForum processForumSettings(boolean draft) { + if (isGradebookGroupEnabled()) { + if (selectedForum.getForum().getId() == null) { + String newDefaultAssignName = selectedForum.getGradeAssign(); + + if (!selectedForum.getForum().getRestrictPermissionsForGroups() && + !StringUtils.isBlank(newDefaultAssignName) && !newDefaultAssignName.equals(DEFAULT_GB_ITEM)) { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_GROUP_ITEMS_ERROR)); + return null; + } + } + + String currentDefaultAssignName = selectedForum.getForum().getDefaultAssignName(); + + if (selectedForum.getForum().getId() != null && + currentDefaultAssignName != null && !StringUtils.isBlank(currentDefaultAssignName)) { + if (!checkUpdateSettings(true)) { + return null; + } + + selectedForum.getForum().setDefaultAssignName(selectedForum.getGradeAssign()); + } + } + if (selectedForum.getForum().getRestrictPermissionsForGroups() && selectedForum.getForum().getId() == null) { if (!saveForumsForGroups(draft)) { return null; @@ -1417,8 +1505,42 @@ private DiscussionForum processForumSettings(boolean draft){ return selectedForum.getForum(); } - private DiscussionForum saveForumSettings(boolean draft) - { + private boolean checkUpdateSettings(boolean isForum) { + String defaultAssignName = null; + String newDefaultAssignName = null; + + if (isForum) { + defaultAssignName = selectedForum.getForum().getDefaultAssignName(); + newDefaultAssignName = selectedForum.getGradeAssign(); + } else { + defaultAssignName = selectedTopic.getTopic().getDefaultAssignName(); + newDefaultAssignName = selectedTopic.getGradeAssign(); + } + + if (StringUtils.isBlank(newDefaultAssignName) || newDefaultAssignName.equals(DEFAULT_GB_ITEM)) { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_ITEMS_MUST_SELECT)); + return false; + } + + GradingService gradingService = getGradingService(); + Long itemId = Long.parseLong(defaultAssignName); + + GradebookAssignment gradebookAssignment = gradingService.getGradebookAssigment( + toolManager.getCurrentPlacement().getContext(), itemId); + + String groupId = gradebookAssignment.getGradebook().getUid(); + + String gbUid = gradingService.getGradebookUidByAssignmentById(toolManager.getCurrentPlacement().getContext(), Long.parseLong(newDefaultAssignName)); + + if (!gbUid.equals(groupId)) { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_GROUP_FORUM_ITEMS_ERROR)); + return false; + } + + return true; + } + + private DiscussionForum saveForumSettings(boolean draft) { log.debug("saveForumSettings(boolean " + draft + ")"); if (selectedForum == null) @@ -1456,8 +1578,11 @@ private DiscussionForum saveForumSettings(boolean draft) forum.setExtendedDescription(""); } - saveForumSelectedAssignment(forum); - saveForumAttach(forum); + if (!isGradebookGroupEnabled()) { + saveForumSelectedAssignment(forum); + } + + saveForumAttach(forum); setObjectPermissions(forum); processActionSendToCalendar(forum); if (draft) @@ -1474,20 +1599,23 @@ private DiscussionForum saveForumSettings(boolean draft) // Update or create task if needed String gradeAssign = selectedForum.getGradeAssign(); gradeAssign = gradeAssign == null ? selectedForum.getForum().getDefaultAssignName() : gradeAssign; - if (!draft && gradeAssign != null) { - GradingService gradingService = getGradingService(); - String gradebookUid = toolManager.getCurrentPlacement().getContext(); - Assignment assignment = gradingService.getAssignmentByNameOrId(gradebookUid, gradebookUid, gradeAssign); - Date dueDate = (assignment != null ? assignment.getDueDate() : null); - String reference = DiscussionForumService.REFERENCE_ROOT + SEPARATOR + getSiteId() + SEPARATOR + forum.getId(); - Optional optTask = taskService.getTask(reference); - if (optTask.isPresent()) { - this.updateTask(optTask.get(), this.selectedForum.getForum().getTitle(), dueDate); - } else if (this.selectedForum.isCreateTask() && StringUtils.isNotBlank(gradeAssign) && !DEFAULT_GB_ITEM.equals(gradeAssign) ) { - this.createTask(reference, this.selectedForum.getForum().getTitle(), dueDate); - } - } - + + if (!isGradebookGroupEnabled()) { + if (!draft && gradeAssign != null) { + GradingService gradingService = getGradingService(); + String gradebookUid = toolManager.getCurrentPlacement().getContext(); + Assignment assignment = gradingService.getAssignmentByNameOrId(gradebookUid, gradebookUid, gradeAssign); + Date dueDate = (assignment != null ? assignment.getDueDate() : null); + String reference = DiscussionForumService.REFERENCE_ROOT + SEPARATOR + getSiteId() + SEPARATOR + forum.getId(); + Optional optTask = taskService.getTask(reference); + if (optTask.isPresent()) { + this.updateTask(optTask.get(), this.selectedForum.getForum().getTitle(), dueDate); + } else if (this.selectedForum.isCreateTask() && StringUtils.isNotBlank(gradeAssign) && !DEFAULT_GB_ITEM.equals(gradeAssign) ) { + this.createTask(reference, this.selectedForum.getForum().getTitle(), dueDate); + } + } + } + return forum; } @@ -1638,6 +1766,13 @@ public String processActionNewTopic() setErrorMessage(getResourceBundleString(INSUFFICIENT_PRIVILEGES_CREATE_TOPIC)); return gotoMain(); } + + if (isGradebookGroupEnabled()) { + selectedTopic.setRestrictPermissionsForGroups("true"); + setGroupId(null); + setDiscussionGeneric(false); + } + attachments.clear(); prepareRemoveAttach.clear(); siteGroups.clear(); @@ -1914,12 +2049,35 @@ public String processActionSaveTopicAsDraft() } private String processTopicSettings(boolean draft){ - if(selectedTopic.getTopic().getRestrictPermissionsForGroups() && selectedTopic.getTopic().getId() == null) { + if (isGradebookGroupEnabled()) { + if (selectedTopic.getTopic().getId() == null) { + String newDefaultAssignName = selectedTopic.getGradeAssign(); + + if (!selectedTopic.getTopic().getRestrictPermissionsForGroups() && + !StringUtils.isBlank(newDefaultAssignName) && !newDefaultAssignName.equals(DEFAULT_GB_ITEM)) { + setErrorMessage(getResourceBundleString(MULTI_GRADEBOOK_GROUP_ITEMS_ERROR)); + return null; + } + } + + String currentDefaultAssignName = selectedTopic.getTopic().getDefaultAssignName(); + + if (selectedTopic.getTopic().getId() != null && + currentDefaultAssignName != null && !StringUtils.isBlank(currentDefaultAssignName)) { + if (!checkUpdateSettings(false)) { + return null; + } + + selectedTopic.getTopic().setDefaultAssignName(selectedTopic.getGradeAssign()); + } + } + + if (selectedTopic.getTopic().getRestrictPermissionsForGroups() && selectedTopic.getTopic().getId() == null) { if (!saveTopicsForGroups(draft)) { return null; } } else { - saveTopicSettings(draft); + saveTopicSettings(draft); } return gotoMain(); } @@ -1966,7 +2124,11 @@ private String saveTopicSettings(boolean draft) if(topic.getModifiedBy()==null&&this.forumManager.getAnonRole()==true){ topic.setModifiedBy(".anon"); } - saveTopicSelectedAssignment(topic); + + if (!isGradebookGroupEnabled()) { + saveTopicSelectedAssignment(topic); + } + saveTopicAttach(topic); setObjectPermissions(topic); processActionSendToCalendar(topic); @@ -1977,22 +2139,23 @@ private String saveTopicSettings(boolean draft) updateSynopticMessagesForForumComparingOldMessagesCount(getSiteId(), topic.getBaseForum().getId(), topic.getId(), beforeChangeHM, SynopticMsgcntrManager.NUM_OF_ATTEMPTS); } - // Update or create task if needed - String gradeAssign = selectedTopic.getGradeAssign(); - if (!draft) { - GradingService gradingService = getGradingService(); - String gradebookUid = toolManager.getCurrentPlacement().getContext(); - Assignment assignment = gradingService.getAssignmentByNameOrId(gradebookUid, gradebookUid, gradeAssign); - Date dueDate = (assignment != null ? assignment.getDueDate() : null); - String reference = DiscussionForumService.REFERENCE_ROOT + SEPARATOR + getSiteId() + SEPARATOR + topic.getBaseForum().getId() + TOPIC_REF + topic.getId(); - Optional optTask = taskService.getTask(reference); - if (optTask.isPresent()) { - this.updateTask(optTask.get(), topic.getTitle(), dueDate); - } else if (this.selectedTopic.isCreateTask() && StringUtils.isNotBlank(gradeAssign) && !DEFAULT_GB_ITEM.equals(gradeAssign) ) { - this.createTask(reference, topic.getTitle(), dueDate); - } - } - + if (!isGradebookGroupEnabled()) { + // Update or create task if needed + String gradeAssign = selectedTopic.getGradeAssign(); + if (!draft) { + GradingService gradingService = getGradingService(); + String gradebookUid = toolManager.getCurrentPlacement().getContext(); + Assignment assignment = gradingService.getAssignmentByNameOrId(gradebookUid, gradebookUid, gradeAssign); + Date dueDate = (assignment != null ? assignment.getDueDate() : null); + String reference = DiscussionForumService.REFERENCE_ROOT + SEPARATOR + getSiteId() + SEPARATOR + topic.getBaseForum().getId() + TOPIC_REF + topic.getId(); + Optional optTask = taskService.getTask(reference); + if (optTask.isPresent()) { + this.updateTask(optTask.get(), topic.getTitle(), dueDate); + } else if (this.selectedTopic.isCreateTask() && StringUtils.isNotBlank(gradeAssign) && !DEFAULT_GB_ITEM.equals(gradeAssign) ) { + this.createTask(reference, topic.getTitle(), dueDate); + } + } + } } } return gotoMain(); @@ -2138,8 +2301,23 @@ public String processActionTopicSettings() { attachments.add(new DecoratedAttachment((Attachment)attachList.get(i))); } - } - + } + + String currentDefaultAssignName = topic.getDefaultAssignName(); + + selectedTopic.setGradeAssign(currentDefaultAssignName); + + if (isGradebookGroupEnabled()) { + if (currentDefaultAssignName != null && !StringUtils.isBlank(currentDefaultAssignName)) { + GradingService gradingService = getGradingService(); + String gbUid = gradingService.getGradebookUidByAssignmentById(toolManager.getCurrentPlacement().getContext(), Long.parseLong(currentDefaultAssignName)); + setGroupId(gbUid); + setDiscussionGeneric(false); + } else { + setDiscussionGeneric(true); + } + } + siteGroups.clear(); setTopicBeanAssign(); setFromMainOrForumOrTopic(); @@ -6017,7 +6195,7 @@ public void setCurrentChange(String newChange){ public String getCurrentChange(){ return currentChange; } - + public void processGradeAssignSend() { String changeAssign = currentChange; // Set value @@ -6211,25 +6389,25 @@ public String processDfGradeSubmit() { String siteId = toolManager.getCurrentPlacement().getContext(); String gradebookUuid = toolManager.getCurrentPlacement().getContext(); - if (isGradebookGroupEnabled()) { - boolean exit = false; - List gradebookGroupInstances = getGradingService().getGradebookGroupInstances(gradebookUuid); - int i = 0; - while (!exit && i < gradebookGroupInstances.size()) { - Gradebook gradebookGroup = gradebookGroupInstances.get(i); - List groupAssignments = getGradingService().getAssignments(gradebookGroup.getUid().toString(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE); - int z = 0; - while (!exit && z < groupAssignments.size()) { - Assignment assignment = groupAssignments.get(z); - if (assignment.getId().toString().equals(selectedAssign)) { - gradebookUuid = gradebookGroup.getUid().toString(); - exit = true; - } - z++; - } - i++; - } - } + if (isGradebookGroupEnabled()) { + boolean exit = false; + List gradebookGroupInstances = getGradingService().getGradebookGroupInstances(gradebookUuid); + int i = 0; + while (!exit && i < gradebookGroupInstances.size()) { + Gradebook gradebookGroup = gradebookGroupInstances.get(i); + List groupAssignments = getGradingService().getAssignments(gradebookGroup.getUid().toString(), toolManager.getCurrentPlacement().getContext(), SortType.SORT_BY_NONE); + int z = 0; + while (!exit && z < groupAssignments.size()) { + Assignment assignment = groupAssignments.get(z); + if (assignment.getId().toString().equals(selectedAssign)) { + gradebookUuid = gradebookGroup.getUid().toString(); + exit = true; + } + z++; + } + i++; + } + } if(selectedMessage == null && selectedGradedUserId != null && !"".equals(selectedGradedUserId)){ studentUid = selectedGradedUserId; }else{ @@ -8292,6 +8470,14 @@ private List getSiteRolesNames() { */ private boolean saveForumsForGroups(boolean draft) { log.debug("saveForumsForGroups()"); + + boolean isCorrect = checkMultiGradebook(true); + String oldGradeAssign = selectedForum.getGradeAssign(); + + if (!isCorrect) { + return false; + } + if (siteGroups == null || siteGroups.isEmpty()) { setErrorMessage(getResourceBundleString(NO_GROUP_SELECTED, new Object[]{getResourceBundleString("cdfm_discussions")})); return false; @@ -8336,6 +8522,10 @@ private boolean saveForumsForGroups(boolean draft) { thisForum.setOpenDate(forumTemplate.getForum().getOpenDate()); thisForum.setCloseDate(forumTemplate.getForum().getCloseDate()); + if (isGradebookGroupEnabled()) { + thisForum.setDefaultAssignName(getNewAssignName(currentGroup, oldGradeAssign)); + } + // Attachments attachments.clear(); for (Iterator attachmentIterator = attachmentsTemplate.iterator(); attachmentIterator.hasNext();) { @@ -8381,6 +8571,14 @@ private boolean saveForumsForGroups(boolean draft) { */ private boolean saveTopicsForGroups(boolean draft) { log.debug("saveTopicsForGroup()"); + + boolean isCorrect = checkMultiGradebook(false); + String oldGradeAssign = selectedTopic.getGradeAssign(); + + if (!isCorrect) { + return false; + } + if (siteGroups == null || siteGroups.isEmpty()) { setErrorMessage(getResourceBundleString(NO_GROUP_SELECTED, new Object[]{getResourceBundleString("topics")})); return false; @@ -8425,6 +8623,10 @@ private boolean saveTopicsForGroups(boolean draft) { thisTopic.setAutoMarkThreadsRead(topicTempate.getTopic().getAutoMarkThreadsRead()); thisTopic.setGradebookAssignment(topicTempate.getTopic().getGradebookAssignment()); + if (isGradebookGroupEnabled()) { + thisTopic.setDefaultAssignName(getNewAssignName(currentGroup, oldGradeAssign)); + } + // Attachments attachments.clear(); for (Iterator attachmentIterator = attachmentsTemplate.iterator(); attachmentIterator.hasNext();) { @@ -8461,6 +8663,28 @@ private boolean saveTopicsForGroups(boolean draft) { return true; } + private String getNewAssignName(SiteGroupBean currentGroup, String gradeAssign) { + String topicAssignName = ""; + + String groupId = currentGroup.getGroup().getId(); + List gbItemList = Arrays.asList(gradeAssign.split(",")); + GradingService gradingService = getGradingService(); + + for (String gbItem : gbItemList) { + String gbUid = gradingService.getGradebookUidByAssignmentById(toolManager.getCurrentPlacement().getContext(), Long.parseLong(gbItem)); + + if (gbUid.equals(groupId)) { + if (StringUtils.isBlank(topicAssignName)) { + topicAssignName += gbItem; + } else { + topicAssignName += ("," + gbItem); + } + } + } + + return topicAssignName; + } + /** * * @return list of role titles appropriate to this site which should be set to None when autocreating topics @@ -9555,5 +9779,4 @@ public String getAttachmentReadableSize(final String attachmentSize) { public boolean isGradebookGroupEnabled() { return getGradingService().isGradebookGroupEnabled(toolManager.getCurrentPlacement().getContext()); } - -} +} \ No newline at end of file diff --git a/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/ui/MessageForumStatisticsBean.java b/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/ui/MessageForumStatisticsBean.java index 78190757a8fa..d22e52ff628f 100644 --- a/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/ui/MessageForumStatisticsBean.java +++ b/msgcntr/messageforums-app/src/java/org/sakaiproject/tool/messageforums/ui/MessageForumStatisticsBean.java @@ -262,6 +262,9 @@ public void setGradebookAssignment( public DecoratedCompiledMessageStatistics userInfo = null; public UserStatistics userAuthoredInfo = null; + private boolean discussionGeneric = true; + private String groupId = ""; + private Map courseMemberMap; protected boolean ascending = true; protected boolean ascendingForUser = false; @@ -425,6 +428,26 @@ public void setGradebookAssignment( private UIPermissionsManager uiPermissionsManager; @ManagedProperty(value="#{Components[\"org.sakaiproject.util.api.FormattedText\"]}") private FormattedText formattedText; + + public boolean getDiscussionGeneric() { + return this.discussionGeneric; + } + + public void setDiscussionGeneric(boolean discussionGeneric) { + this.discussionGeneric = discussionGeneric; + } + + public void setGroupId(boolean discussionGeneric) { + this.discussionGeneric = discussionGeneric; + } + + public String getGroupId() { + return this.groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } public void setMessageManager(MessageForumsMessageManager messageManager){ this.messageManager = messageManager; @@ -2681,8 +2704,9 @@ public String processActionStatisticsByTopic() selectedAllTopicsTopicId = getExternalParameterByKey(TOPIC_ID); selectedAllTopicsForumId = getExternalParameterByKey(FORUM_ID); + if(newForum){ - if(selectedAllTopicsForumId != null && !"".equals(selectedAllTopicsForumId)){ + if (selectedAllTopicsForumId != null && !"".equals(selectedAllTopicsForumId)) { try{ DiscussionForum df = forumManager.getForumById(Long.parseLong(selectedAllTopicsForumId)); selectedAllTopicsForumTitle = df.getTitle(); @@ -2692,7 +2716,7 @@ public String processActionStatisticsByTopic() } } if(newTopic){ - if(selectedAllTopicsTopicId != null && !"".equals(selectedAllTopicsTopicId)){ + if (selectedAllTopicsTopicId != null && !"".equals(selectedAllTopicsTopicId)) { try{ DiscussionTopic dt = forumManager.getTopicById(Long.parseLong(selectedAllTopicsTopicId)); selectedAllTopicsTopicTitle = dt.getTitle(); @@ -2701,7 +2725,30 @@ public String processActionStatisticsByTopic() } } } - + + boolean isGradebookGroupEnabled = getGradingService().isGradebookGroupEnabled(toolManager.getCurrentPlacement().getContext()); + + if (isGradebookGroupEnabled) { + GradingService gradingService = getGradingService(); + String selectedEntityDefaultAssignName = null; + + if (selectedAllTopicsTopicId != null && !StringUtils.isBlank(selectedAllTopicsTopicId)) { + DiscussionTopic dt = forumManager.getTopicById(Long.parseLong(selectedAllTopicsTopicId)); + selectedEntityDefaultAssignName = dt.getDefaultAssignName(); + } else if (selectedAllTopicsForumId != null && !StringUtils.isBlank(selectedAllTopicsForumId)) { + DiscussionForum df = forumManager.getForumById(Long.parseLong(selectedAllTopicsForumId)); + selectedEntityDefaultAssignName = df.getDefaultAssignName(); + } + + if (selectedEntityDefaultAssignName != null && !StringUtils.isBlank(selectedEntityDefaultAssignName)) { + String gbUid = gradingService.getGradebookUidByAssignmentById(toolManager.getCurrentPlacement().getContext(), Long.parseLong(selectedEntityDefaultAssignName)); + setGroupId(gbUid); + setDiscussionGeneric(false); + } else { + setDiscussionGeneric(true); + } + } + // Get topic statistics. For performance, we want this information up front and cached before we render the jsp files. // The default gradebook assignment must be known before we get the statistics, since grades will be included setDefaultSelectedAssign(); diff --git a/msgcntr/messageforums-app/src/webapp/jsp/dfReviseForumSettingsAttach.jsp b/msgcntr/messageforums-app/src/webapp/jsp/dfReviseForumSettingsAttach.jsp index d199fe757d1f..61e5fa676a75 100644 --- a/msgcntr/messageforums-app/src/webapp/jsp/dfReviseForumSettingsAttach.jsp +++ b/msgcntr/messageforums-app/src/webapp/jsp/dfReviseForumSettingsAttach.jsp @@ -17,9 +17,17 @@ + <% + FacesContext facesContext = FacesContext.getCurrentInstance(); + Application appContext = facesContext.getApplication(); + ValueBinding valueBinding = appContext.createValueBinding("#{ForumTool}"); + DiscussionForumTool discussionForumTool = (DiscussionForumTool) valueBinding.getValue(facesContext); + + boolean isGradebookGroupEnabled = discussionForumTool.isGradebookGroupEnabled(); + String thisId = request.getParameter("panel"); if (thisId == null) { @@ -33,6 +41,8 @@ - + + + <% + FacesContext facesContext = FacesContext.getCurrentInstance(); + Application appContext = facesContext.getApplication(); + ValueBinding valueBinding = appContext.createValueBinding("#{ForumTool}"); + DiscussionForumTool discussionForumTool = (DiscussionForumTool) valueBinding.getValue(facesContext); + + boolean isGradebookGroupEnabled = discussionForumTool.isGradebookGroupEnabled(); + String thisId = request.getParameter("panel"); if (thisId == null) { thisId = "Main" + org.sakaiproject.tool.cover.ToolManager.getCurrentPlacement().getId(); @@ -95,6 +104,21 @@ includeContentsInEmails.css("display", "none"); } } + + function disableFieldsBeforeSubmit() { + if ('<%= isGradebookGroupEnabled %>' == 'true') { + $('select[id^="revise\\:perm"]').each(function() { + let elementId = $(this).attr("id"); + let rowIndex = elementId.split(":")[2]; + + const element = $("#revise\\:perm\\" + ":" + rowIndex + "\\:level"); + + if (element) { + element.prop("disabled", false); + } + }); + } + } <% @@ -107,7 +131,7 @@ - + <%@ include file="/jsp/discussionForum/menu/forumsMenu.jsp" %>

- + + + + + - - - - - - - - - + + + <% if (!isGradebookGroupEnabled) { %> + + + + + + + + + + + <% } else { %> + + + + <% } %> + @@ -466,6 +510,8 @@
@@ -70,12 +88,11 @@ - - + diff --git a/msgcntr/messageforums-app/src/webapp/jsp/discussionForum/statistics/dfStatisticsListByTopic.jsp b/msgcntr/messageforums-app/src/webapp/jsp/discussionForum/statistics/dfStatisticsListByTopic.jsp index 4b7bec1787d1..074cb2cf020d 100644 --- a/msgcntr/messageforums-app/src/webapp/jsp/discussionForum/statistics/dfStatisticsListByTopic.jsp +++ b/msgcntr/messageforums-app/src/webapp/jsp/discussionForum/statistics/dfStatisticsListByTopic.jsp @@ -259,21 +259,6 @@ - - - - - - - @@ -296,6 +281,26 @@
+
+ +
+ + + +
+ + +
+
<%-- Use cahcedTopicStatistics - value is cached from #{!empty mfStatisticsBean.groupForStatisticsByTopic} above. @@ -407,7 +412,7 @@ - + diff --git a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages.properties b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages.properties index 96bb2c7bb669..6dc769dfc13d 100644 --- a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages.properties +++ b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages.properties @@ -278,6 +278,11 @@ submissions_allowed_error=Please enter a number for Submissions Allowed that is validateURL=Validate URL has_time_limit=Time limit +multi_gradebook_use_info=This site is configured to have several gradebooks, so you must choose the groups and then their category or a corresponding grade item. +multi_gradebook.release_to.error=Quizzes cannot be created for all sections/groups because the course is set up with different instances per grade group. +multi_gradebook.items.error=Selected groups must have a gradebook item associated with them +multi_gradebook.categories.error=The selected categories must be associated with their corresponding group. + # signs for author tool separator=| column=\: diff --git a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_ca.properties b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_ca.properties index 5ae06b4a1046..e3a42138f6d1 100644 --- a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_ca.properties +++ b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_ca.properties @@ -277,6 +277,11 @@ submissions_allowed_error=Introdu\u00efu el nombre de enviaments permesos. Aques validateURL=Valida l\u2019adre\u00e7a URL has_time_limit=Temps l\u00edmit +multi_gradebook_use_info=Este lloc est\u00e0 configurat per a tindre diversos llibres de qualificacions, per tant s'hauran de triar els grups i posteriorment la seua categoria o un item de qualificaci\u00f3 corresponent. +multi_gradebook.release_to.error=No es poden crear ex\u00e0mens per a totes les seccions/grups perqu\u00e8 el curs est\u00e0 configurat amb inst\u00e0ncies diferents per grup de qualificacions. +multi_gradebook.items.error=Els grups seleccionats han de tindre associat un \u00edtem del llibre de qualificacions +multi_gradebook.categories.error=Les categories seleccionades han d'estar associades al seu grup corresponent. + # signs for author tool separator=| column=\: diff --git a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_es.properties b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_es.properties index 806eaf6e8bec..fd8d002a26c4 100644 --- a/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_es.properties +++ b/samigo/samigo-app/src/java/org/sakaiproject/tool/assessment/bundle/AssessmentSettingsMessages_es.properties @@ -277,9 +277,11 @@ date_error=Por favor, indique la fecha de liberaci\u00f3n de los comentarios. submissions_allowed_error=Por favor, introduzca el n\u00famero de env\u00edos permitidos. Este n\u00famero ha de ser mayor o igual a uno (1). validateURL=Validar la URL has_time_limit=y tiene un l\u00edmite de tiempo de -multi_gradebook.release_to.error=No se pueden crear tareas de sitio al tener calificaciones de grupo. + +multi_gradebook_use_info=Este sitio est\u00e1 configurado para tener varios libros de calificaciones, por lo tanto se deber\u00e1n escoger los grupos y posteriormente su categor\u00eda o un item de calificaci\u00f3n correspondiente. +multi_gradebook.release_to.error=No se pueden crear ex\u00e1menes para todas las secciones/grupos debido a que el curso est\u00e1 configurado con instancias diferentes por grupo de calificaciones multi_gradebook.items.error=Los grupos seleccionados deben tener asociado un item del libro de calificaciones. -multi_gradebook.categories.error=Las categorías seleccionadas deben estar asociadas a su grupo correspondiente. +multi_gradebook.categories.error=Las categor\u00cdas seleccionadas deben estar asociadas a su grupo correspondiente. # signs for author tool separator=| diff --git a/samigo/samigo-app/src/webapp/jsf/author/authorSettings.jsp b/samigo/samigo-app/src/webapp/jsf/author/authorSettings.jsp index 7b86dd7f2318..3687256a34d4 100644 --- a/samigo/samigo-app/src/webapp/jsf/author/authorSettings.jsp +++ b/samigo/samigo-app/src/webapp/jsf/author/authorSettings.jsp @@ -549,6 +549,13 @@ styleClass="d-block info-text small" value="#{assessmentSettingsMessages.released_to_help}" /> + + +
+ +
+
+
diff --git a/samigo/samigo-app/src/webapp/jsf/author/publishedSettings.jsp b/samigo/samigo-app/src/webapp/jsf/author/publishedSettings.jsp index 7b55f866075a..048c39245388 100644 --- a/samigo/samigo-app/src/webapp/jsf/author/publishedSettings.jsp +++ b/samigo/samigo-app/src/webapp/jsf/author/publishedSettings.jsp @@ -544,6 +544,13 @@ styleClass="help-block info-text small" value="#{assessmentSettingsMessages.released_to_help}" />
+ + +
+ +
+
+
diff --git a/vuecomponents/tool/src/main/frontend/src/components/multi-gradebook.vue b/vuecomponents/tool/src/main/frontend/src/components/multi-gradebook.vue index cc9f5d5fc029..90a2145ff68a 100644 --- a/vuecomponents/tool/src/main/frontend/src/components/multi-gradebook.vue +++ b/vuecomponents/tool/src/main/frontend/src/components/multi-gradebook.vue @@ -95,6 +95,8 @@ export default { tool: { type: String }, selectedTemp: { type: String }, isCategory: { type: Boolean }, + groupId: { type: String}, + multipleSelection: { type: Boolean }, userId: { type: String }, appName: { type: String }, }, @@ -132,13 +134,20 @@ export default { } }, async mounted() { - var endpoint = this.isCategory ? "/categories" : "/items/" + this.appName; - console.debug("ENDPOINT: " + endpoint); + var endpoint = this.isCategory ? "/categories" : "/items"; + + if (!this.isCategory) { + endpoint += "/" + this.appName; + } if (this.userId) { endpoint += "/" + this.userId; } + if (this.groupId && this.groupId.trim() !== "") { + endpoint += "/" + this.groupId; + } + await fetch('/api/sites/' + this.siteId + endpoint) .then((r) => { if (r.ok) { diff --git a/webapi/src/main/java/org/sakaiproject/webapi/controllers/GradesController.java b/webapi/src/main/java/org/sakaiproject/webapi/controllers/GradesController.java index 9573585a1159..23c7d7e349e3 100644 --- a/webapi/src/main/java/org/sakaiproject/webapi/controllers/GradesController.java +++ b/webapi/src/main/java/org/sakaiproject/webapi/controllers/GradesController.java @@ -175,8 +175,10 @@ public List getSiteGrades(@PathVariable String siteId) throws Use return gradeDataSupplierForSite.apply(siteId); } - @GetMapping(value = {"/sites/{siteId}/items/{appName}", "/sites/{siteId}/items/{appName}/{userId}"}, produces = MediaType.APPLICATION_JSON_VALUE) - public List getSiteItems(@PathVariable String siteId, @PathVariable String appName, @PathVariable Optional userId) throws UserNotDefinedException { + @GetMapping(value = {"/sites/{siteId}/items/{appName}", "/sites/{siteId}/items/{appName}/{userId}", "/sites/{siteId}/items/{appName}/{userId}/{gbUid}"}, produces = MediaType.APPLICATION_JSON_VALUE) + public List getSiteItems(@PathVariable String siteId, @PathVariable String appName, @PathVariable Optional gbUid, + @PathVariable Optional userId) throws UserNotDefinedException { + checkSakaiSession(); List gbWithItems = new ArrayList<>(); @@ -185,15 +187,36 @@ public List getSiteItems(@PathVariable String siteId, @PathVa user = userId.get(); } - Map gradebookGroupMap = returnFoundGradebooks(siteId, user); + boolean isGradebookGroupEnabled = gradingService.isGradebookGroupEnabled(siteId); + Map gradebookGroupMap = new HashMap<>(); + + if (isGradebookGroupEnabled && gbUid.isPresent() && userId.isPresent()) { + try { + Site site = siteService.getSite(siteId); + Collection groupList = site.getGroups(); + + Optional foundedGroup = groupList.stream().filter(group -> group.getId().equals(gbUid.get())).findFirst(); + + boolean isInstructor = userId.get().equals(userDirectoryService.getCurrentUser().getId()) && (securityService.isSuperUser() || securityService.unlock("section.role.instructor", site.getReference())); + List groupIds = site.getGroupsWithMember(userId.get()).stream().map(Group::getId).collect(Collectors.toList()); + + if (foundedGroup.isPresent() && (isInstructor || groupIds.contains(foundedGroup.get().getId()))) { + gradebookGroupMap.put(gbUid.get(), foundedGroup.get().getTitle()); + } + } catch (IdUnusedException e) { + log.error("Error while trying to get gradebooks for site {} : {}", siteId, e.getMessage()); + } + } else { + gradebookGroupMap = returnFoundGradebooks(siteId, user); + } for (Map.Entry entry : gradebookGroupMap.entrySet()) { List gbItems = new ArrayList<>(); - String gbUid = entry.getKey(); + String gradebookUid = entry.getKey(); String groupTitle = entry.getValue(); - List gradebookAssignments = gradingService.getAssignments(gbUid, siteId, SortType.SORT_BY_NONE); + List gradebookAssignments = gradingService.getAssignments(gradebookUid, siteId, SortType.SORT_BY_NONE); for (Assignment gAssignment : gradebookAssignments) { if (!gAssignment.getExternallyMaintained() || gAssignment.getExternallyMaintained() && gAssignment.getExternalAppName().equals(appName)) { @@ -207,7 +230,7 @@ public List getSiteItems(@PathVariable String siteId, @PathVa } } - GradebookRestBean gbDto = new GradebookRestBean(gbUid, groupTitle, gbItems); + GradebookRestBean gbDto = new GradebookRestBean(gradebookUid, groupTitle, gbItems); gbWithItems.add(gbDto); }