diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AutoCompleterRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AutoCompleterRenderer.java index c72a7e1ec38795507cb938e77f5a0cef9b2734e8..849404396f65f4040ac99df2a9e61c67f3c2f35b 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AutoCompleterRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AutoCompleterRenderer.java @@ -46,60 +46,71 @@ public class AutoCompleterRenderer extends DefaultComponentRenderer { AutoCompleterComponent cmp = (AutoCompleterComponent)source; AutoCompleter autoCompleter = cmp.getAutoCompleter(); - int inputSize = 72; - boolean showDisplayKey = false; + final int inputSize = 72; String id = autoCompleter.getFormDispatchId(); - String mapperUri = autoCompleter.getMapperUri(); - int minLength = autoCompleter.getMinLength(); - StringOutput command = new StringOutput(64); - ubu.createCopyFor(cmp).openXHREvent(command, null, false, false, - new NameValuePair(VelocityContainer.COMMAND_ID, "select")); - - sb.append("<input type='text' class='form-control' size='").append(inputSize).append("' id='").append(id) - .append("' name='").append(id).append("' value=\""); - if(StringHelper.containsNonWhitespace(autoCompleter.getValue())) { - sb.append(StringHelper.escapeHtml(autoCompleter.getValue())); - } - sb.append("\" />"); - sb.append("<script type='text/javascript'>\n") - .append("/* <![CDATA[ */\n") - .append("jQuery(function(){\n") - .append(" var fullNameTypeahead = new Bloodhound({\n") - .append(" datumTokenizer: function (d) {\n") - .append(" return Bloodhound.tokenizers.whitespace(d.value);\n") - .append(" },\n") - .append(" queryTokenizer: Bloodhound.tokenizers.whitespace,\n") - .append(" remote: {\n") - .append(" url: '").append(mapperUri).append("/?place=holder&term=%QUERY',\n")//place holder is useless but for tomcat, sometimes it said that the term parameter is corrupted and will not be part of the request send to OpenOLAT - .append(" wildcard: '%QUERY',\n") - .append(" filter: function ( response ) {\n") - .append(" return jQuery.map(response, function (object) {\n") - .append(" return {\n") - .append(" value: '' + object.key,\n"); - if(showDisplayKey) { - sb.append(" fullName: object.displayKey + ': ' + object.value\n"); + if(autoCompleter.isEnabled()) { + boolean showDisplayKey = false; + String mapperUri = autoCompleter.getMapperUri(); + int minLength = autoCompleter.getMinLength(); + StringOutput command = new StringOutput(64); + ubu.createCopyFor(cmp).openXHREvent(command, null, false, false, + new NameValuePair(VelocityContainer.COMMAND_ID, "select")); + + sb.append("<input type='text' class='form-control' size='").append(inputSize).append("' id='").append(id) + .append("' name='").append(id).append("' value=\""); + if(StringHelper.containsNonWhitespace(autoCompleter.getValue())) { + sb.append(StringHelper.escapeHtml(autoCompleter.getValue())); + } + sb.append("\" />"); + sb.append("<script type='text/javascript'>\n") + .append("/* <![CDATA[ */\n") + .append("jQuery(function(){\n") + .append(" var fullNameTypeahead = new Bloodhound({\n") + .append(" datumTokenizer: function (d) {\n") + .append(" return Bloodhound.tokenizers.whitespace(d.value);\n") + .append(" },\n") + .append(" queryTokenizer: Bloodhound.tokenizers.whitespace,\n") + .append(" remote: {\n") + .append(" url: '").append(mapperUri).append("/?place=holder&term=%QUERY',\n")//place holder is useless but for tomcat, sometimes it said that the term parameter is corrupted and will not be part of the request send to OpenOLAT + .append(" wildcard: '%QUERY',\n") + .append(" filter: function ( response ) {\n") + .append(" return jQuery.map(response, function (object) {\n") + .append(" return {\n") + .append(" value: '' + object.key,\n"); + if(showDisplayKey) { + sb.append(" fullName: object.displayKey + ': ' + object.value\n"); + } else { + sb.append(" fullName: object.value\n"); + } + sb.append(" };\n") + .append(" });\n") + .append(" }\n") + .append(" }\n") + .append(" });\n") + .append(" fullNameTypeahead.initialize();\n") + .append(" jQuery('#").append(id).append("').typeahead({\n") + .append(" hint: false,\n") + .append(" highlight: false,\n") + .append(" minLength: ").append(minLength).append("\n") + .append(" },{\n") + .append(" minLength: ").append(minLength).append(",\n") + .append(" displayKey: 'fullName',\n") + .append(" source: fullNameTypeahead.ttAdapter()\n") + .append(" }).on('typeahead:selected', function (e, object) {\n") + .append(" ").append(command).append(",'key',object.value,'value',object.fullName);\n") + .append(" });\n") + .append("});\n") + .append("/* ]]> */\n") + .append("</script>"); } else { - sb.append(" fullName: object.value\n"); + String value = ""; + if(StringHelper.containsNonWhitespace(autoCompleter.getValue())) { + value = autoCompleter.getValue(); + } + sb.append("<input id=\"").append(id).append("\" type=\"test\" disabled=\"disabled\" class=\"form-control o_disabled\" size=\"") + .append(inputSize) + .append("\" value=\"").append(value).append("\" />") + .append("</span>"); } - sb.append(" };\n") - .append(" });\n") - .append(" }\n") - .append(" }\n") - .append(" });\n") - .append(" fullNameTypeahead.initialize();\n") - .append(" jQuery('#").append(id).append("').typeahead({\n") - .append(" hint: false,\n") - .append(" highlight: false,\n") - .append(" minLength: ").append(minLength).append("\n") - .append(" },{\n") - .append(" minLength: ").append(minLength).append(",\n") - .append(" displayKey: 'fullName',\n") - .append(" source: fullNameTypeahead.ttAdapter()\n") - .append(" }).on('typeahead:selected', function (e, object) {\n") - .append(" ").append(command).append(",'key',object.value,'value',object.fullName);\n") - .append(" });\n") - .append("});\n") - .append("/* ]]> */\n") - .append("</script>"); } } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/lecture/LectureService.java b/src/main/java/org/olat/modules/lecture/LectureService.java index 6fc783dad44db4dbb166506f499a3cec8af17197..9e5aea25d3da19010015206817b60da4368de0fc 100644 --- a/src/main/java/org/olat/modules/lecture/LectureService.java +++ b/src/main/java/org/olat/modules/lecture/LectureService.java @@ -87,6 +87,24 @@ public interface LectureService { */ public LectureBlock save(LectureBlock lectureBlock, List<Group> groups); + /** + * The method will set the status of the lecture block and + * the status of the roll call. + * + * @param lectureBlock The lecture block to close + * @return The updated lecture block + */ + public LectureBlock close(LectureBlock lectureBlock); + + /** + * The method will set the status of the lecture block and + * the status of the roll call. + * + * @param lectureBlock The lecture block to close + * @return The updated lecture block + */ + public LectureBlock cancel(LectureBlock lectureBlock); + /** * Append content to the log saved on the lecture block. * @@ -236,6 +254,15 @@ public interface LectureService { */ public LectureBlockRollCall updateRollCall(LectureBlockRollCall rollCall); + /** + * The method will adapt, trim or add lectures to the roll calls of + * the specified lecture block base on the effective lectures or the planned + * lectures. + * + * @param lectureBlock The lecture block of which roll call need to be adapted + */ + public void adaptRollCalls(LectureBlock lectureBlock); + /** * Add the specified lectures to the ones the identity follows. * diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java index 94f7324dc1d3c8eaec098b035eb768067392f92b..8ac2041b13bf4ddf0eba8cc87acf498de7a2d36d 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureBlockRollCallDAO.java @@ -154,6 +154,49 @@ public class LectureBlockRollCallDAO { } } + public LectureBlockRollCall adaptLecture(LectureBlockRollCall rollCall, int numberOfLectures) { + LectureBlockRollCallImpl call = (LectureBlockRollCallImpl)rollCall; + List<Integer> currentAbsentList = call.getLecturesAbsentList(); + List<Integer> currentAttendedList = call.getLecturesAttendedList(); + + if((currentAbsentList != null && currentAbsentList.size() > 0) || (currentAttendedList != null && currentAttendedList.size() > 0)) { + int currentLectures = currentAbsentList.size() + currentAttendedList.size(); + if(currentLectures > numberOfLectures) { + // need to reduce + List<Integer> absentList = new ArrayList<>(); + for(Integer absence:currentAbsentList) { + if(absence.intValue() < numberOfLectures) { + absentList.add(absence); + } + } + call.setLecturesAbsentList(absentList); + call.setLecturesAbsentNumber(absentList.size()); + + List<Integer> attendedList = new ArrayList<>(); + for(Integer attended:currentAttendedList) { + if(attended.intValue() < numberOfLectures) { + attendedList.add(attended); + } + } + call.setLecturesAttendedList(attendedList); + call.setLecturesAttendedNumber(numberOfLectures - absentList.size()); + call = (LectureBlockRollCallImpl)update(call); + } else if(currentLectures < numberOfLectures) { + //need to add some lecture + + List<Integer> attendedList = new ArrayList<>(currentAttendedList); + for(int i=currentLectures; i<numberOfLectures; i++) { + attendedList.add(i); + } + + call.setLecturesAttendedList(attendedList); + call.setLecturesAttendedNumber(attendedList.size()); + call = (LectureBlockRollCallImpl)update(call); + } + } + return call; + } + private void updateLog(LectureBlockRollCallImpl call, String currentAbsent, String currentAttended) { String log = call.getLog() == null ? "" : call.getLog(); diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java index a480454a95f9eb9f19b73f17594f299f75a66909..8eb40a1e56f1c62a756c330e94a149c4e19a4043 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java @@ -1,4 +1,5 @@ /** + * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> @@ -199,6 +200,35 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable { return block; } + @Override + public LectureBlock close(LectureBlock lectureBlock) { + lectureBlock.setStatus(LectureBlockStatus.done); + lectureBlock.setRollCallStatus(LectureRollCallStatus.closed); + LectureBlockImpl block = (LectureBlockImpl)lectureBlockDao.update(lectureBlock); + List<LectureBlockRollCall> rollCallList = lectureBlockRollCallDao.getRollCalls(lectureBlock); + for(LectureBlockRollCall rollCall:rollCallList) { + int numOfLectures = lectureBlock.getEffectiveLecturesNumber(); + if(numOfLectures <= 0 && lectureBlock.getStatus() != LectureBlockStatus.cancelled) { + numOfLectures = lectureBlock.getPlannedLecturesNumber(); + } + lectureBlockRollCallDao.adaptLecture(rollCall, numOfLectures); + } + dbInstance.commit(); + recalculateSummary(block.getEntry()); + return block; + } + + @Override + public LectureBlock cancel(LectureBlock lectureBlock) { + lectureBlock.setStatus(LectureBlockStatus.cancelled); + lectureBlock.setRollCallStatus(LectureRollCallStatus.closed); + lectureBlock.setEffectiveLecturesNumber(0); + LectureBlockImpl block = (LectureBlockImpl)lectureBlockDao.update(lectureBlock); + dbInstance.commit(); + recalculateSummary(block.getEntry()); + return block; + } + @Override public void appendToLectureBlockLog(LectureBlockRef lectureBlock, Identity user, Identity assessedIdentity, String audit) { Date now = new Date(); @@ -430,6 +460,25 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable { return rollCall; } + @Override + public void adaptRollCalls(LectureBlock lectureBlock) { + LectureBlockStatus status = lectureBlock.getStatus(); + LectureRollCallStatus rollCallStatus = lectureBlock.getRollCallStatus(); + if(status == LectureBlockStatus.done || rollCallStatus == LectureRollCallStatus.closed || rollCallStatus == LectureRollCallStatus.autoclosed) { + log.warn("Try to adapt roll call of a closed lecture block: " + lectureBlock.getKey()); + return; + } + + List<LectureBlockRollCall> rollCallList = lectureBlockRollCallDao.getRollCalls(lectureBlock); + for(LectureBlockRollCall rollCall:rollCallList) { + int numOfLectures = lectureBlock.getEffectiveLecturesNumber(); + if(numOfLectures <= 0 && lectureBlock.getStatus() != LectureBlockStatus.cancelled) { + numOfLectures = lectureBlock.getPlannedLecturesNumber(); + } + lectureBlockRollCallDao.adaptLecture(rollCall, lectureBlock.getPlannedLecturesNumber()); + } + } + @Override public void recalculateSummary(RepositoryEntry entry) { List<LectureBlockStatistics> statistics = getParticipantsLecturesStatistics(entry); @@ -478,16 +527,15 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable { private void autoClose(LectureBlockImpl lectureBlock) { lectureBlock.setStatus(LectureBlockStatus.done); lectureBlock.setRollCallStatus(LectureRollCallStatus.autoclosed); - if(lectureBlock.getEffectiveLecturesNumber() < 0) { + if(lectureBlock.getEffectiveLecturesNumber() <= 0 && lectureBlock.getStatus() != LectureBlockStatus.cancelled) { lectureBlock.setEffectiveLecturesNumber(lectureBlock.getPlannedLecturesNumber()); } lectureBlock.setAutoClosedDate(new Date()); lectureBlock = (LectureBlockImpl)lectureBlockDao.update(lectureBlock); + dbInstance.commit(); List<LectureBlockRollCall> rollCalls = lectureBlockRollCallDao.getRollCalls(lectureBlock); Map<Identity,LectureBlockRollCall> rollCallMap = rollCalls.stream().collect(Collectors.toMap(r -> r.getIdentity(), r -> r)); - - //TODO absence first admission ??? List<ParticipantAndLectureSummary> participantsAndSummaries = lectureParticipantSummaryDao.getLectureParticipantSummaries(lectureBlock); Set<Identity> participants = new HashSet<>(); for(ParticipantAndLectureSummary participantAndSummary:participantsAndSummaries) { @@ -505,6 +553,9 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable { } appendToLectureBlockLog(lectureBlock, null, null, "Auto-closed"); + dbInstance.commit(); + + recalculateSummary(lectureBlock.getEntry()); } @Override diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockVO.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockVO.java index 0a61b15825687e3d43c693422316ba6c0ce1a1c3..09705be5472069b7f44a74b783f262d09ce518ad 100644 --- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockVO.java +++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockVO.java @@ -52,6 +52,9 @@ public class LectureBlockVO implements LectureBlockRef { private Date endDate; private Boolean compulsory; private int plannedLectures; + + private String status; + private String rollCallStatus; private Long repoEntryKey; @@ -74,6 +77,9 @@ public class LectureBlockVO implements LectureBlockRef { compulsory = block.isCompulsory(); plannedLectures = block.getPlannedLecturesNumber(); this.repoEntryKey = repoEntryKey; + + status = block.getStatus() == null ? null : block.getStatus().name(); + rollCallStatus = block.getRollCallStatus() == null ? null : block.getRollCallStatus().name(); } @Override @@ -180,4 +186,20 @@ public class LectureBlockVO implements LectureBlockRef { public void setPlannedLectures(int plannedLectures) { this.plannedLectures = plannedLectures; } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getRollCallStatus() { + return rollCallStatus; + } + + public void setRollCallStatus(String rollCallStatus) { + this.rollCallStatus = rollCallStatus; + } } diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java index 17a7799beea51428fa676638ea876802c9678325..4e431a5794d38d99601a4b338535181dccbdc871 100644 --- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java +++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java @@ -111,10 +111,13 @@ public class LectureBlocksWebService { private LectureBlock saveLectureBlock(LectureBlockVO blockVo) { LectureBlock block; + int currentPlannedLectures; if(blockVo.getKey() != null && blockVo.getKey() > 0) { block = lectureService.getLectureBlock(blockVo); + currentPlannedLectures = block.getPlannedLecturesNumber(); } else { block = lectureService.createLectureBlock(entry); + currentPlannedLectures = -1; } if(blockVo.getExternalId() != null) { @@ -148,7 +151,11 @@ public class LectureBlocksWebService { block.setManagedFlagsString(blockVo.getManagedFlagsString()); } block.setPlannedLecturesNumber(blockVo.getPlannedLectures()); - return lectureService.save(block, null); + LectureBlock savedLectureBlock = lectureService.save(block, null); + if(currentPlannedLectures > 0 && currentPlannedLectures != savedLectureBlock.getPlannedLecturesNumber()) { + lectureService.adaptRollCalls(savedLectureBlock); + } + return savedLectureBlock; } @GET diff --git a/src/main/java/org/olat/modules/lecture/ui/AbstractTeacherOverviewController.java b/src/main/java/org/olat/modules/lecture/ui/AbstractTeacherOverviewController.java index 2ae43105fe74bdedd1bd0ad6b6bd392467175a9a..eee5838290e6aac82646b9b661031732df434f8a 100644 --- a/src/main/java/org/olat/modules/lecture/ui/AbstractTeacherOverviewController.java +++ b/src/main/java/org/olat/modules/lecture/ui/AbstractTeacherOverviewController.java @@ -351,8 +351,10 @@ public abstract class AbstractTeacherOverviewController extends BasicController if(rollCallWizardCtrl != null) return; LectureBlock reloadedBlock = lectureService.getLectureBlock(block); + List<Identity> teachers = lectureService.getTeachers(reloadedBlock); List<Identity> participants = lectureService.startLectureBlock(getIdentity(), reloadedBlock); - rollCallWizardCtrl = new TeacherRollCallWizardController(ureq, getWindowControl(), reloadedBlock, participants); + RollCallSecurityCallback secCallback = getRollCallSecurityCallback(reloadedBlock, teachers.contains(getIdentity())); + rollCallWizardCtrl = new TeacherRollCallWizardController(ureq, getWindowControl(), reloadedBlock, participants, secCallback); if(withRepositoryEntry) { rollCallCtrl.addLoggingResourceable(CoreLoggingResourceable.wrap(reloadedBlock.getEntry().getOlatResource(), OlatResourceableType.course, reloadedBlock.getEntry().getDisplayname())); diff --git a/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java b/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java index 6428e7d7115c332121ef7aa9dbc7bc38ea749eb5..5121e2df26f94bf74e714a590472e4780cb6a957 100644 --- a/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java +++ b/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java @@ -35,8 +35,6 @@ import org.olat.core.logging.activity.LearningResourceLoggingAction; import org.olat.core.logging.activity.OlatResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.modules.lecture.LectureBlock; -import org.olat.modules.lecture.LectureBlockStatus; -import org.olat.modules.lecture.LectureRollCallStatus; import org.olat.modules.lecture.LectureService; import org.olat.modules.lecture.Reason; import org.olat.modules.lecture.RollCallSecurityCallback; @@ -132,11 +130,7 @@ public class CancelRollCallConfirmationController extends FormBasicController { Long reasonKey = new Long(effectiveEndReasonEl.getSelectedKey()); Reason selectedReason = lectureService.getReason(reasonKey); lectureBlock.setReasonEffectiveEnd(selectedReason); - - lectureBlock.setStatus(LectureBlockStatus.cancelled); - lectureBlock.setRollCallStatus(LectureRollCallStatus.closed); - lectureBlock.setEffectiveLecturesNumber(0); - lectureBlock = lectureService.save(lectureBlock, null); + lectureBlock = lectureService.cancel(lectureBlock); fireEvent(ureq, Event.DONE_EVENT); lectureService.appendToLectureBlockLog(lectureBlock, getIdentity(), null, "Cancelled"); diff --git a/src/main/java/org/olat/modules/lecture/ui/CloseRollCallConfirmationController.java b/src/main/java/org/olat/modules/lecture/ui/CloseRollCallConfirmationController.java index 5d09a60fee8cdb31edd4e609d7a1ecf6d09cce76..848f12de3e64d3802ea3e14aaba190ab631b629f 100644 --- a/src/main/java/org/olat/modules/lecture/ui/CloseRollCallConfirmationController.java +++ b/src/main/java/org/olat/modules/lecture/ui/CloseRollCallConfirmationController.java @@ -39,8 +39,6 @@ import org.olat.core.logging.activity.OlatResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; import org.olat.modules.lecture.LectureBlock; -import org.olat.modules.lecture.LectureBlockStatus; -import org.olat.modules.lecture.LectureRollCallStatus; import org.olat.modules.lecture.LectureService; import org.olat.modules.lecture.Reason; import org.olat.modules.lecture.RollCallSecurityCallback; @@ -176,7 +174,15 @@ public class CloseRollCallConfirmationController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { lectureBlock.setComment(blockCommentEl.getValue()); - lectureBlock.setEffectiveLecturesNumber(lectureBlock.getPlannedLecturesNumber());//TODO + + String selectedKey = effectiveLecturesEl.getSelectedKey(); + int effectiveLectures = lectureBlock.getPlannedLecturesNumber(); + try { + effectiveLectures = Integer.parseInt(selectedKey); + } catch(Exception ex) { + logError("", ex); + } + lectureBlock.setEffectiveLecturesNumber(effectiveLectures); Date effectiveEndDate = getEffectiveEndDate(); if(effectiveEndDate == null) { lectureBlock.setReasonEffectiveEnd(null); @@ -190,11 +196,7 @@ public class CloseRollCallConfirmationController extends FormBasicController { lectureBlock.setReasonEffectiveEnd(selectedReason); } } - - lectureBlock.setStatus(LectureBlockStatus.done); - lectureBlock.setRollCallStatus(LectureRollCallStatus.closed); - lectureBlock = lectureService.save(lectureBlock, null); - lectureService.recalculateSummary(lectureBlock.getEntry()); + lectureBlock = lectureService.close(lectureBlock); fireEvent(ureq, Event.DONE_EVENT); lectureService.appendToLectureBlockLog(lectureBlock, getIdentity(), null, "Closed"); diff --git a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java index 275ec4dbd5bc124ae9950e237ed57a87e4ede535..32b3f40b5356a4e5d5caf0ad1698c4e49e6158eb 100644 --- a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java +++ b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java @@ -141,7 +141,6 @@ public class EditLectureBlockController extends FormBasicController { plannedLecturesEl = uifactory.addDropdownSingleselect("planned.lectures", "planned.lectures", formLayout, plannedLecturesKeys, plannedLecturesKeys, null); - plannedLecturesEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.plannedLectures)); plannedLecturesEl.setMandatory(true); String plannedlectures = lectureBlock == null ? "4" : Integer.toString(lectureBlock.getPlannedLecturesNumber()); for(String plannedLecturesKey:plannedLecturesKeys) { @@ -151,10 +150,12 @@ public class EditLectureBlockController extends FormBasicController { } } //freeze it after roll call done - boolean plannedLecturesEditable = lectureBlock == null || + boolean plannedLecturesEditable = (lectureBlock == null || (lectureBlock.getStatus() != LectureBlockStatus.done && lectureBlock.getRollCallStatus() != LectureRollCallStatus.closed - && lectureBlock.getRollCallStatus() != LectureRollCallStatus.autoclosed); + && lectureBlock.getRollCallStatus() != LectureRollCallStatus.autoclosed)) + && !lectureManagementManaged + && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.plannedLectures); plannedLecturesEl.setEnabled(plannedLecturesEditable); String[] onValues = new String[]{ "" }; @@ -352,11 +353,13 @@ public class EditLectureBlockController extends FormBasicController { protected void formOK(UserRequest ureq) { boolean create = false; StringBuilder audit = new StringBuilder(); + int currentPlannedLectures = -1; if(lectureBlock == null) { audit.append("Create;"); lectureBlock = lectureService.createLectureBlock(entry); create = true; } else { + currentPlannedLectures = lectureBlock.getPlannedLecturesNumber(); audit.append("Update;"); } lectureBlock.setTitle(titleEl.getValue()); @@ -424,6 +427,9 @@ public class EditLectureBlockController extends FormBasicController { } dbInstance.commit(); + if(currentPlannedLectures >= 0) { + lectureService.adaptRollCalls(lectureBlock); + } updateLocationsPrefs(ureq); lectureService.syncCalendars(lectureBlock); fireEvent(ureq, Event.DONE_EVENT); diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherCloseRollCallController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherCloseRollCallController.java deleted file mode 100644 index 86d02fa6e0eabc0972e66f3de14fea709ec871f8..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/modules/lecture/ui/TeacherCloseRollCallController.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.modules.lecture.ui; - -import java.util.ArrayList; -import java.util.List; - -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.elements.SingleSelection; -import org.olat.core.gui.components.form.flexible.elements.TextElement; -import org.olat.core.gui.components.form.flexible.impl.FormBasicController; -import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; -import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.Event; -import org.olat.core.gui.control.WindowControl; -import org.olat.modules.lecture.LectureBlock; -import org.olat.modules.lecture.LectureBlockStatus; -import org.olat.modules.lecture.LectureModule; -import org.olat.modules.lecture.LectureService; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Last step of the roll call wizard. - * - * Initial date: 7 avr. 2017<br> - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - * - */ -public class TeacherCloseRollCallController extends FormBasicController { - - private SingleSelection statusEl; - private TextElement blockCommentEl; - - private LectureBlock lectureBlock; - - @Autowired - private LectureModule lectureModule; - @Autowired - private LectureService lectureService; - - public TeacherCloseRollCallController(UserRequest ureq, WindowControl wControl, LectureBlock lectureBlock) { - super(ureq, wControl); - this.lectureBlock = lectureBlock; - initForm(ureq); - } - - @Override - protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - String[] statusKeys = getAvailableStatus(); - String[] statusValues = new String[statusKeys.length]; - for(int i=statusKeys.length; i-->0; ) { - statusValues[i] = translate(statusKeys[i]); - } - statusEl = uifactory.addDropdownSingleselect("lecture.block.status", "lecture.block.status", formLayout, statusKeys, statusValues, null); - boolean statusFound = false; - if(lectureBlock.getStatus() != null) { - String lectureBlockStatus = lectureBlock.getStatus().name(); - for(int i=statusKeys.length; i-->0; ) { - if(lectureBlockStatus.equals(statusKeys[i])) { - statusEl.select(statusKeys[i], true); - statusFound = true; - break; - } - } - } - if(!statusFound) { - statusEl.select(statusKeys[0], true); - } - - String comment = lectureBlock.getComment(); - blockCommentEl = uifactory.addTextAreaElement("comment", "lecture.block.comment", 2000, 4, 36, false, comment, formLayout); - - FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); - formLayout.add(buttonsCont); - uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); - uifactory.addFormSubmitButton("save", buttonsCont); - } - - private String[] getAvailableStatus() { - List<String> statusList = new ArrayList<>(); - statusList.add(LectureBlockStatus.active.name()); - if(lectureModule.isStatusPartiallyDoneEnabled()) { - statusList.add(LectureBlockStatus.partiallydone.name()); - } - statusList.add(LectureBlockStatus.done.name()); - if(lectureModule.isStatusCancelledEnabled()) { - statusList.add(LectureBlockStatus.cancelled.name()); - } - return statusList.toArray(new String[statusList.size()]); - } - - @Override - protected void doDispose() { - // - } - - @Override - protected boolean validateFormLogic(UserRequest ureq) { - boolean allOk = true; - - if(!statusEl.isOneSelected()) { - statusEl.setErrorKey("form.legende.mandatory", null); - allOk &= false; - } - - return allOk & super.validateFormLogic(ureq); - } - - @Override - protected void formCancelled(UserRequest ureq) { - fireEvent(ureq, Event.CANCELLED_EVENT); - } - - @Override - protected void formOK(UserRequest ureq) { - lectureBlock.setStatus(LectureBlockStatus.valueOf(statusEl.getSelectedKey())); - lectureBlock.setComment(blockCommentEl.getValue()); - lectureBlock.setEffectiveLecturesNumber(lectureBlock.getPlannedLecturesNumber()); - lectureBlock = lectureService.save(lectureBlock, null); - fireEvent(ureq, Event.DONE_EVENT); - } -} diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java index 443457c85576b9f46a01c44d30ece10177702745..b85e22decc9f67126dd15207362f90af92a4223f 100644 --- a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java +++ b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java @@ -111,6 +111,7 @@ public class TeacherRollCallController extends FormBasicController { private final boolean authorizedAbsenceEnabled; private final boolean absenceDefaultAuthorized; + private int numOfLectures; private List<Identity> participants; @Autowired @@ -131,6 +132,11 @@ public class TeacherRollCallController extends FormBasicController { this.participants = participants; setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + numOfLectures = lectureBlock.getEffectiveLecturesNumber(); + if(numOfLectures <= 0 && lectureBlock.getStatus() != LectureBlockStatus.cancelled) { + numOfLectures = lectureBlock.getPlannedLecturesNumber(); + } + Roles roles = ureq.getUserSession().getRoles(); isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); userPropertyHandlers = userManager.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser); @@ -200,7 +206,7 @@ public class TeacherRollCallController extends FormBasicController { if(lectureBlock.isCompulsory()) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RollCols.status)); - for(int i=0; i<lectureBlock.getPlannedLecturesNumber(); i++) { + for(int i=0; i<numOfLectures; i++) { FlexiColumnModel col = new DefaultFlexiColumnModel("table.header.lecture." + (i+1), i + CHECKBOX_OFFSET, true, "lecture." + (i+1)); columnsModel.addFlexiColumnModel(col); } @@ -277,7 +283,7 @@ public class TeacherRollCallController extends FormBasicController { private TeacherRollCallRow forgeRow(Identity participant, LectureBlockRollCall rollCall) { TeacherRollCallRow row = new TeacherRollCallRow(rollCall, participant, userPropertyHandlers, getLocale()); - int numOfChecks = lectureBlock.isCompulsory() ? lectureBlock.getPlannedLecturesNumber() : 0; + int numOfChecks = lectureBlock.isCompulsory() ? numOfLectures : 0; MultipleSelectionElement[] checks = new MultipleSelectionElement[numOfChecks]; List<Integer> absences = rollCall == null ? Collections.emptyList() : rollCall.getLecturesAbsentList(); @@ -513,8 +519,8 @@ public class TeacherRollCallController extends FormBasicController { } private void doCheckAllRow(TeacherRollCallRow row) { - List<Integer> allIndex = new ArrayList<>(lectureBlock.getPlannedLecturesNumber()); - for(int i=0; i<lectureBlock.getPlannedLecturesNumber(); i++) { + List<Integer> allIndex = new ArrayList<>(numOfLectures); + for(int i=0; i<numOfLectures; i++) { allIndex.add(i); } LectureBlockRollCall rollCall = lectureService.addRollCall(row.getIdentity(), lectureBlock, row.getRollCall(), null, allIndex); diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallWizardController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallWizardController.java index e90e63411af3beeb6f8e75f3c190b9037804646f..92bc3b4308e2171c8af635e26d5b9bd28b7d78b4 100644 --- a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallWizardController.java +++ b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallWizardController.java @@ -37,6 +37,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.id.Identity; import org.olat.modules.lecture.LectureBlock; +import org.olat.modules.lecture.RollCallSecurityCallback; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -52,17 +53,20 @@ public class TeacherRollCallWizardController extends BasicController { private NextPreviousController nextPreviousCtrl; private SingleParticipantCallController participantCtrl; - private TeacherCloseRollCallController closeRollCallCtrl; + private CloseRollCallConfirmationController closeRollCallCtrl; private LectureBlock lectureBlock; private List<Identity> participants; private Identity calledIdentity; + private RollCallSecurityCallback secCallback; @Autowired private UserManager userManager; - public TeacherRollCallWizardController(UserRequest ureq, WindowControl wControl, LectureBlock lectureBlock, List<Identity> participants) { + public TeacherRollCallWizardController(UserRequest ureq, WindowControl wControl, + LectureBlock lectureBlock, List<Identity> participants, RollCallSecurityCallback secCallback) { super(ureq, wControl); + this.secCallback = secCallback; this.lectureBlock = lectureBlock; this.participants = participants; if(participants.size() > 0) { @@ -112,7 +116,7 @@ public class TeacherRollCallWizardController extends BasicController { removeAsListenerAndDispose(participantCtrl); removeAsListenerAndDispose(closeRollCallCtrl); - closeRollCallCtrl = new TeacherCloseRollCallController(ureq, getWindowControl(), lectureBlock); + closeRollCallCtrl = new CloseRollCallConfirmationController(ureq, getWindowControl(), lectureBlock, secCallback); listenTo(closeRollCallCtrl); calledIdentity = null;