Skip to content
Snippets Groups Projects
Commit acfb6bb4 authored by srosse's avatar srosse
Browse files

OO-2636: implements GUI for authorized absence in the roll call list

parent 5a70e3e9
No related branches found
No related tags found
No related merge requests found
Showing
with 457 additions and 19 deletions
......@@ -52,6 +52,8 @@ How to add a new job:
<ref bean="reminderTrigger"/>
<ref bean="videoTranscodingTrigger"/>
<ref bean="automaticLifecycleTrigger"/>
<ref bean="autoCloseLecturesTrigger"/>
<ref bean="reminderLecturesTrigger"/>
</list>
</property>
</bean>
......
......@@ -96,6 +96,7 @@ public class ContactFormController extends BasicController {
private ContactForm cntctForm;
private DialogBoxController noUsersErrorCtr;
private List<String> myButtons;
private Object userObject;
@Autowired
private MailManager mailService;
......@@ -130,6 +131,14 @@ public class ContactFormController extends BasicController {
init(ureq, hasAtLeastOneAddress, cmsg.getDisabledIdentities());
}
public Object getUserObject() {
return userObject;
}
public void setUserObject(Object userObject) {
this.userObject = userObject;
}
private boolean hasAtLeastOneAddress(List<ContactList> recipList) {
boolean hasAtLeastOneAddress = false;
if (recipList != null && recipList.size() > 0 ) {
......
......@@ -60,6 +60,10 @@ public interface LectureBlock extends LectureBlockRef, ModifiedInfo, CreateInfo
public int getPlannedLecturesNumber();
public void setPlannedLecturesNumber(int number);
public int getEffectiveLecturesNumber();
public void setEffectiveLecturesNumber(int effectiveLecturesNumber);
public String getLog();
......
......@@ -67,9 +67,9 @@ public class LectureModule extends AbstractSpringModule implements ConfigOnOff {
@Value("${lecture.rollcall.reminder.enabled:true}")
private boolean rollCallReminderEnabled;
@Value("${lecture.rollcall.reminder.period:5}")
@Value("${lecture.rollcall.reminder.period:3}")
private int rollCallReminderPeriod;
@Value("${lecture.rollcall.autoclose.period:15}")
@Value("${lecture.rollcall.autoclose.period:5}")
private int rollCallAutoClosePeriod;
@Value("${lecture.absence.appeal.enabled:true}")
......
......@@ -139,7 +139,8 @@ public interface LectureService {
* @param authorizedAbsence If there are authorized absence
* @return A new persisted roll call
*/
public LectureBlockRollCall createRollCall(Identity identity, LectureBlock lectureBlock, Boolean authorizedAbsence);
public LectureBlockRollCall createRollCall(Identity identity, LectureBlock lectureBlock,
Boolean authorizedAbsence, String absenceReason);
/**
* Standard merge
......@@ -201,10 +202,13 @@ public interface LectureService {
public List<LectureBlock> getLectureBlocks(RepositoryEntryRef entry, IdentityRef teacher);
/**
* This method will check 2 things. First is the lectures for the specified
* repository entry enabled and if it is the case, it will checks that the
* identity is a teacher in at least one lecture block.
*
* @param entry
* @param identity
* @return
* @param entry The course / repository entry
* @param identity The identity as teacher
* @return true if the lecture is enabled and the identity a teach
*/
public boolean hasLecturesAsTeacher(RepositoryEntryRef entry, Identity identity);
......
/**
* <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;
import org.olat.core.id.CreateInfo;
......
......@@ -49,4 +49,62 @@
</property>
</bean>
<!-- Lectures reminder job -->
<bean id="reminderLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="reminderLecturesJob.${cluster.singleton.services}" />
<!-- adjust cron style syntax for your notification needs
"0 10 0 * *" e.g. 10 minutes after midnight
A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows:
Field Name Allowed Values Allowed Special Characters
Seconds 0-59 , - * /
Minutes 0-59 , - * /
Hours 0-23 , - * /
Day-of-month 1-31 , - * ? / L W C
Month 1-12 or JAN-DEC , - * /
Day-of-Week 1-7 or SUN-SAT , - * ? / L C #
Year (Optional) empty, 1970-2099 , - * /
-->
<property name="cronExpression" value="15 34 */1 * * ?" />
<property name="startDelay" value="60000" />
</bean>
<bean id="reminderLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true">
<property name="jobClass" value="org.olat.modules.lecture.manager.ReminderLecturesJob" />
</bean>
<!-- dummy bean -->
<bean id="reminderLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true">
<property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" />
</bean>
<!-- Lectures auto close job -->
<bean id="autoCloseLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="autoCloseLecturesJob.${cluster.singleton.services}" />
<!-- adjust cron style syntax for your notification needs
"0 10 0 * *" e.g. 10 minutes after midnight
A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows:
Field Name Allowed Values Allowed Special Characters
Seconds 0-59 , - * /
Minutes 0-59 , - * /
Hours 0-23 , - * /
Day-of-month 1-31 , - * ? / L W C
Month 1-12 or JAN-DEC , - * /
Day-of-Week 1-7 or SUN-SAT , - * ? / L C #
Year (Optional) empty, 1970-2099 , - * /
-->
<property name="cronExpression" value="15 34 */1 * * ?" />
<property name="startDelay" value="60000" />
</bean>
<bean id="autoCloseLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true">
<property name="jobClass" value="org.olat.modules.lecture.manager.AutoCloseLecturesJob" />
</bean>
<!-- dummy bean -->
<bean id="autoCloseLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true">
<property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" />
</bean>
</beans>
\ No newline at end of file
/**
* <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.manager;
import org.olat.core.commons.services.scheduler.JobWithDB;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
*
* Initial date: 5 avr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class AutoCloseLecturesJob extends JobWithDB {
@Override
public void executeWithDB(JobExecutionContext arg0) throws JobExecutionException {
//auto close
}
}
......@@ -109,7 +109,10 @@ public class LectureBlockDAO {
sb.append("select block.key from lectureblock block")
.append(" inner join block.teacherGroup teacherGroup")
.append(" inner join teacherGroup.members teachers")
.append(" where block.entry.key=:entryKey and teachers.identity.key=:identityKey");
.append(" where block.entry.key=:entryKey and teachers.identity.key=:identityKey")
.append(" and exists (select config.key from lectureentryconfig config")
.append(" where config.entry.key=:entryKey and config.lectureEnabled=true")
.append(" )");
List<Long> firstKey = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Long.class)
......
......@@ -187,12 +187,15 @@ public class LectureServiceImpl implements LectureService {
}
@Override
public LectureBlockRollCall createRollCall(Identity identity, LectureBlock lectureBlock, Boolean authorizedAbsence) {
public LectureBlockRollCall createRollCall(Identity identity, LectureBlock lectureBlock,
Boolean authorizedAbsence, String reasonAbsence) {
LectureBlockRollCall rollCall = lectureBlockRollCallDao.getRollCall(lectureBlock, identity);
if(rollCall == null) {//reload in case of concurrent usage
rollCall = lectureBlockRollCallDao.createAndPersistRollCall(lectureBlock, identity, authorizedAbsence, null, null);
rollCall = lectureBlockRollCallDao.createAndPersistRollCall(lectureBlock, identity,
authorizedAbsence, reasonAbsence, null);
} else if(authorizedAbsence != null) {
rollCall.setAbsenceAuthorized(authorizedAbsence);
rollCall.setAbsenceReason(reasonAbsence);
rollCall = lectureBlockRollCallDao.update(rollCall);
}
return rollCall;
......
/**
* <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.manager;
import org.olat.core.commons.services.scheduler.JobWithDB;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* A job which send reminders.
*
* Initial date: 5 avr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class ReminderLecturesJob extends JobWithDB {
@Override
public void executeWithDB(JobExecutionContext arg0) throws JobExecutionException {
// reminders
}
}
......@@ -22,6 +22,7 @@ package org.olat.modules.lecture.model;
import java.util.Date;
import org.olat.modules.lecture.LectureBlock;
import org.olat.modules.lecture.LectureBlockRef;
import org.olat.modules.lecture.LectureBlockRollCall;
/**
......@@ -33,8 +34,11 @@ import org.olat.modules.lecture.LectureBlockRollCall;
public class LectureBlockAndRollCall {
private final String entryDisplayname;
private final Long lectureBlockKey;
private final String lectureBlockTitle;
private final int plannedLectures;
private final int effectiveLectures;
private final Date startDate;
private final Long rollCallKey;
......@@ -46,8 +50,10 @@ public class LectureBlockAndRollCall {
this.entryDisplayname = entryDisplayname;
startDate = lectureBlock.getStartDate();
lectureBlockKey = lectureBlock.getKey();
lectureBlockTitle = lectureBlock.getTitle();
plannedLectures = lectureBlock.getPlannedLecturesNumber();
effectiveLectures = lectureBlock.getEffectiveLecturesNumber();
if(rollCall == null) {
rollCallKey = null;
......@@ -66,6 +72,10 @@ public class LectureBlockAndRollCall {
return entryDisplayname;
}
public LectureBlockRef getLectureBlockRef() {
return new LectureBlockRefImpl(lectureBlockKey);
}
public String getLectureBlockTitle() {
return lectureBlockTitle;
}
......@@ -82,6 +92,10 @@ public class LectureBlockAndRollCall {
return plannedLectures;
}
public int getEffectiveLecturesNumber() {
return effectiveLectures;
}
public String getCoach() {
return coach;
}
......
/**
* <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.model;
import org.olat.modules.lecture.LectureBlockRef;
/**
*
* Initial date: 5 avr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class LectureBlockRefImpl implements LectureBlockRef {
private final Long key;
public LectureBlockRefImpl(Long key) {
this.key = key;
}
@Override
public Long getKey() {
return key;
}
}
......@@ -19,6 +19,8 @@
*/
package org.olat.modules.lecture.model;
import java.util.Date;
import org.olat.modules.lecture.LectureBlockRef;
/**
......@@ -32,11 +34,13 @@ public class LectureBlockRow implements LectureBlockRef {
private final Long key;
private final String title;
private final String location;
private final Date startDate;
public LectureBlockRow(Long key, String title, String location) {
public LectureBlockRow(Long key, String title, String location, Date startDate) {
this.key = key;
this.title = title;
this.location = location;
this.startDate = startDate;
}
@Override
......@@ -51,7 +55,8 @@ public class LectureBlockRow implements LectureBlockRef {
public String getLocation() {
return location;
}
public Date getStartDate() {
return startDate;
}
}
/**
* <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.model;
import java.util.Date;
......
/**
* <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 org.olat.modules.lecture.LectureModule;
import org.olat.modules.lecture.RepositoryEntryLectureConfiguration;
/**
* An helper to calculate the configuration with the override.
*
* Initial date: 4 avr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class ConfigurationHelper {
protected static boolean isRollCallEnabled(RepositoryEntryLectureConfiguration lectureConfig, LectureModule lectureModule) {
return (lectureConfig.isOverrideModuleDefault() && lectureConfig.getRollCallEnabled() != null && lectureConfig.getRollCallEnabled().booleanValue())
|| (!lectureConfig.isOverrideModuleDefault() && lectureModule.isRollCallDefaultEnabled());
}
}
......@@ -29,6 +29,7 @@ import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DateFlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
......@@ -81,6 +82,7 @@ public class LectureListRepositoryController extends FormBasicController {
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, BlockCols.id));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.title));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.location));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.date, new DateFlexiCellRenderer(getLocale())));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit"));
tableModel = new LectureListRepositoryDataModel(columnsModel, getLocale());
......@@ -94,7 +96,7 @@ public class LectureListRepositoryController extends FormBasicController {
List<LectureBlock> blocks = lectureService.getLectureBlocks(entry);
List<LectureBlockRow> rows = new ArrayList<>(blocks.size());
for(LectureBlock block:blocks) {
rows.add(new LectureBlockRow(block.getKey(), block.getTitle(), block.getLocation()));
rows.add(new LectureBlockRow(block.getKey(), block.getTitle(), block.getLocation(), block.getStartDate()));
}
tableModel.setObjects(rows);
tableEl.reset(true, true, true);
......
......@@ -63,6 +63,7 @@ public class LectureListRepositoryDataModel extends DefaultFlexiTableDataModel<L
case id: return row.getKey();
case title: return row.getTitle();
case location: return row.getLocation();
case date: return row.getStartDate();
default: return null;
}
}
......@@ -75,7 +76,8 @@ public class LectureListRepositoryDataModel extends DefaultFlexiTableDataModel<L
public enum BlockCols implements FlexiSortableColumnDef {
id("lecture.id"),
title("lecture.title"),
location("lecture.location")
location("lecture.location"),
date("lecture.date")
;
private final String i18nKey;
......
......@@ -156,7 +156,7 @@ public class LectureRepositorySettingsController extends FormBasicController {
overrideModuleDefaults = overrideEl.isSelected(0);
updateOverride();
}
} else if(enableEl == source || rollCallEnabledEl.isAtLeastSelected(1)) {
} else if(enableEl == source || rollCallEnabledEl == source) {
updateVisibility();
}
super.formInnerEvent(ureq, source, event);
......@@ -200,8 +200,8 @@ public class LectureRepositorySettingsController extends FormBasicController {
@Override
protected void formOK(UserRequest ureq) {
lectureConfig.setLectureEnabled(enableEl.isAtLeastSelected(1));
lectureConfig.setOverrideModuleDefault(overrideEl.isSelected(0));
if(enableEl.isAtLeastSelected(1) && overrideEl.isSelected(0)) {
lectureConfig.setOverrideModuleDefault(overrideEl.isSelected(0));
lectureConfig.setRollCallEnabled(rollCallEnabledEl.isAtLeastSelected(1));
//reset values
......@@ -222,6 +222,7 @@ public class LectureRepositorySettingsController extends FormBasicController {
lectureConfig.setTeacherCalendarSyncEnabled(teacherCalendarSyncEl.isAtLeastSelected(1));
lectureConfig.setParticipantCalendarSyncEnabled(participantCalendarSyncEl.isAtLeastSelected(1));
} else {
lectureConfig.setOverrideModuleDefault(false);
lectureConfig.setRollCallEnabled(null);
lectureConfig.setCalculateAttendanceRate(null);
lectureConfig.setRequiredAttendanceRate(null);
......
......@@ -19,30 +19,48 @@
*/
package org.olat.modules.lecture.ui;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.olat.basesecurity.GroupRoles;
import org.olat.commons.calendar.CalendarUtils;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.BooleanCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DateFlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.id.Identity;
import org.olat.core.util.mail.ContactList;
import org.olat.core.util.mail.ContactMessage;
import org.olat.modules.co.ContactFormController;
import org.olat.modules.lecture.LectureBlock;
import org.olat.modules.lecture.LectureModule;
import org.olat.modules.lecture.LectureService;
import org.olat.modules.lecture.model.LectureBlockAndRollCall;
import org.olat.modules.lecture.ui.ParticipantLectureBlocksDataModel.ParticipantCols;
import org.olat.modules.lecture.ui.component.AbsentPresentCellRenderer;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Appeal button: after 5 day (coach can change the block) start, end after 15 day (appeal period)
*
* Initial date: 28 mars 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
......@@ -54,29 +72,50 @@ public class ParticipantLectureBlocksController extends FormBasicController {
private ParticipantLectureBlocksDataModel tableModel;
private final RepositoryEntry entry;
private final boolean appealEnabled;
private final AppealCallback appealCallback;
private CloseableModalController cmc;
private ContactFormController appealCtrl;
@Autowired
private LectureModule lectureModule;
@Autowired
private LectureService lectureService;
@Autowired
private RepositoryService repositoryService;
public ParticipantLectureBlocksController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
super(ureq, wControl, "participant_blocks");
this.entry = entry;
appealEnabled = lectureModule.isAbsenceAppealEnabled();
int appealOffset = lectureModule.getRollCallAutoClosePeriod();//TODO absence or is it reminder period
int appealPeriod = lectureModule.getAbsenceAppealPeriod();
appealCallback = new AppealCallback(appealEnabled, appealOffset, appealPeriod);
initForm(ureq);
loadModel();
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
if(formLayout instanceof FormLayoutContainer) {
FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
layoutCont.contextPut("title", entry.getDisplayname());
}
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ParticipantCols.date, new DateFlexiCellRenderer(getLocale())));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ParticipantCols.entry));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ParticipantCols.lectureBlock));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ParticipantCols.coach));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ParticipantCols.present, new AbsentPresentCellRenderer()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("appeal", ParticipantCols.appeal.ordinal(), "appeal",
if(appealEnabled) {
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("appeal", ParticipantCols.appeal.ordinal(), "appeal",
new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("appeal"), "appeal"), null)));
}
tableModel = new ParticipantLectureBlocksDataModel(columnsModel, getLocale());
tableModel = new ParticipantLectureBlocksDataModel(columnsModel, appealCallback, getLocale());
tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout);
FlexiTableSortOptions options = new FlexiTableSortOptions();
......@@ -96,11 +135,106 @@ public class ParticipantLectureBlocksController extends FormBasicController {
//
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(tableEl == source) {
if(event instanceof SelectionEvent) {
SelectionEvent se = (SelectionEvent)event;
String cmd = se.getCommand();
LectureBlockAndRollCall row = tableModel.getObject(se.getIndex());
if("appeal".equals(cmd)) {
doAppeal(ureq, row);
}
}
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(appealCtrl == source) {
if(event == Event.DONE_EVENT) {
LectureBlockAndRollCall row = (LectureBlockAndRollCall)appealCtrl.getUserObject();
logAudit("Appeal send for lecture block: " + row.getLectureBlockTitle() + " (" + row.getLectureBlockRef().getKey() + ")", null);
}
cmc.deactivate();
cleanUp();
} else if(cmc == source) {
cleanUp();
}
super.event(ureq, source, event);
}
private void cleanUp() {
removeAsListenerAndDispose(appealCtrl);
removeAsListenerAndDispose(cmc);
appealCtrl = null;
cmc = null;
}
@Override
protected void formOK(UserRequest ureq) {
//
}
private void doAppeal(UserRequest ureq, LectureBlockAndRollCall row) {
if(appealCtrl != null) return;
LectureBlock block = lectureService.getLectureBlock(row.getLectureBlockRef());
List<Identity> teachers = lectureService.getTeachers(block);
List<Identity> onwers = repositoryService.getMembers(entry, GroupRoles.owner.name());
ContactList contactList = new ContactList(translate("appeal.contact.list"));
contactList.addAllIdentites(teachers);
contactList.addAllIdentites(onwers);
ContactMessage cmsg = new ContactMessage(getIdentity());
cmsg.addEmailTo(contactList);
cmsg.setSubject(translate("appeal.subject", new String[]{ row.getLectureBlockTitle() }));
appealCtrl = new ContactFormController(ureq, getWindowControl(), true, false, false, cmsg);
appealCtrl.setUserObject(row);
listenTo(appealCtrl);
String title = translate("appeal.title", new String[]{ row.getLectureBlockTitle() });
cmc = new CloseableModalController(getWindowControl(), "close", appealCtrl.getInitialComponent(), true, title);
listenTo(cmc);
cmc.activate();
}
public class AppealCallback {
private final boolean enabled;
private final int appealOffset;
private final int appealPeriod;
private final Date now;
public AppealCallback(boolean enabled, int appealOffset, int appealPeriod) {
this.enabled = enabled;
this.appealOffset = appealOffset;
this.appealPeriod = appealPeriod;
now = new Date();
}
public boolean appealAllowed(LectureBlockAndRollCall row) {
if(enabled) {
int lectures = row.getEffectiveLecturesNumber();
if(lectures <= 0) {
lectures = row.getPlannedLecturesNumber();
}
int attended = row.getLecturesAttendedNumber();
if(attended < lectures) {
Date date = row.getDate();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal = CalendarUtils.getEndOfDay(cal);
cal.add(Calendar.DATE, appealOffset);
Date beginAppeal = cal.getTime();
cal.add(Calendar.DATE, appealPeriod);
Date endAppeal = cal.getTime();
return now.compareTo(beginAppeal) >= 0 && now.compareTo(endAppeal) <= 0;
}
}
return false;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment