/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FenixEdu Academic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.ui.spring.controller.teacher;
import org.fenixedu.academic.domain.Attends;
import org.fenixedu.academic.domain.ExecutionCourse;
import org.fenixedu.academic.domain.ExportGrouping;
import org.fenixedu.academic.domain.Grouping;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.Professorship;
import org.fenixedu.academic.domain.Shift;
import org.fenixedu.academic.domain.StudentGroup;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.domain.util.email.ExecutionCourseSender;
import org.fenixedu.academic.domain.util.email.Recipient;
import org.fenixedu.academic.ui.struts.action.teacher.ManageExecutionCourseDA;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.bennu.core.domain.User;
import org.fenixedu.bennu.core.groups.Group;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.fenixedu.bennu.spring.security.CSRFTokenBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
import org.springframework.web.servlet.view.RedirectView;
import pt.ist.fenixWebFramework.servlets.filters.contentRewrite.GenericChecksumRewriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.core.UriBuilder;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Controller
@RequestMapping("/teacher/{executionCourse}/student-groups/{grouping}")
public class StudentGroupController extends ExecutionCourseController {
private final StudentGroupService studentGroupService;
@Autowired
public StudentGroupController(StudentGroupService studentGroupService) {
this.studentGroupService = studentGroupService;
}
// hack
@Autowired
CSRFTokenBean csrfTokenBean;
@Override
protected Class<?> getFunctionalityType() {
return ManageExecutionCourseDA.class;
}
@Override
Boolean getPermission(Professorship prof) {
return prof.getPermissions().getGroups();
}
@RequestMapping(value = "/createStudentGroup", method = RequestMethod.POST)
public AbstractUrlBasedView createStudentGroup(Model model, @PathVariable Grouping grouping,
@ModelAttribute("addStudent") @Validated AttendsBean addStudents, BindingResult bindingResult) {
return createStudentGroup(model, grouping, null, addStudents, bindingResult);
}
@RequestMapping(value = "/shift/{shift}/createStudentGroup", method = RequestMethod.POST)
public AbstractUrlBasedView createStudentGroup(Model model, @PathVariable Grouping grouping, @PathVariable Shift shift,
@ModelAttribute("addStudent") @Validated AttendsBean addStudents, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return new RedirectView("/teacher/" + executionCourse.getExternalId() + "/student-groups/view/"
+ grouping.getExternalId(), true);
}
StudentGroup studentgroup = studentGroupService.createStudentGroup(grouping, shift);
return new RedirectView("/teacher/" + executionCourse.getExternalId() + "/student-groups/" + grouping.getExternalId()
+ "/viewStudentGroup/" + studentgroup.getExternalId(), true);
}
@RequestMapping(value = "/viewStudentGroup/{studentGroup}", method = RequestMethod.GET)
public TeacherView viewStudentGroup(Model model, @PathVariable Grouping grouping, @PathVariable StudentGroup studentGroup) {
model.addAttribute("csrf",csrfTokenBean);
model.addAttribute("studentGroup", studentGroup);
ArrayList<Shift> shiftList = new ArrayList<Shift>();
if (grouping.getShiftType() != null) {
for (final ExportGrouping exportGrouping : grouping.getExportGroupingsSet()) {
final ExecutionCourse executionCourse = exportGrouping.getExecutionCourse();
for (final Shift shf : executionCourse.getAssociatedShifts()) {
if (shf.containsType(grouping.getShiftType())) {
shiftList.add(shf);
}
}
}
}
ArrayList<Attends> studentsWithoutStudentGroup = new ArrayList<Attends>();
studentsWithoutStudentGroup.addAll(grouping
.getAttendsSet()
.stream()
.filter(attends -> grouping.getStudentGroupsSet().stream()
.noneMatch(sg -> sg.getAttendsSet().stream().anyMatch(at -> at.equals(attends))))
.collect(Collectors.toList()));
model.addAttribute("newShift", studentGroup.getShift());
model.addAttribute("shifts", shiftList);
model.addAttribute("studentsWithoutStudentGroup", studentsWithoutStudentGroup);
return new TeacherView("executionCourse/groupings/viewStudentGroupInformation");
}
@RequestMapping(value = "/editStudentGroupAttends/{studentGroup}", method = RequestMethod.POST)
public AbstractUrlBasedView editStudentGroupAttends(Model model, @PathVariable Grouping grouping,
@ModelAttribute("attends") @Validated AttendsBean attendsBean, @PathVariable StudentGroup studentGroup,
BindingResult bindingResult) {
Map<String, Boolean> studentsToRemove = attendsBean.getRemoveStudent();
Map<String, Boolean> studentsToAdd = attendsBean.getAddStudent();
if (bindingResult.hasErrors()) {
model.addAttribute("removeStudent", studentsToRemove);
model.addAttribute("addStudent", studentsToAdd);
model.addAttribute("errors", "binding error " + bindingResult.getAllErrors());
return viewStudentGroup(model, grouping, studentGroup);
}
studentGroupService.updateStudentGroupMembers(studentGroup, studentsToRemove, studentsToAdd);
return new RedirectView("/teacher/" + executionCourse.getExternalId() + "/student-groups/" + grouping.getExternalId()
+ "/viewStudentGroup/" + studentGroup.getExternalId(), true);
}
@RequestMapping(value = "/editStudentGroupShift/{studentGroup}", method = RequestMethod.POST)
public AbstractUrlBasedView editStudentGroupShift(@PathVariable Grouping grouping, @PathVariable StudentGroup studentGroup,
@ModelAttribute("newShift") @Validated Shift newShift, BindingResult bindingResult) {
studentGroupService.updateStudentGroupShift(studentGroup, newShift);
return new RedirectView("/teacher/" + executionCourse.getExternalId() + "/student-groups/" + grouping.getExternalId()
+ "/viewStudentGroup/" + studentGroup.getExternalId(), true);
}
@RequestMapping(value = "/sendEmail/{studentGroup}", method = RequestMethod.GET)
public RedirectView sendEmail(Model model, HttpServletRequest request, HttpSession session,
@PathVariable StudentGroup studentGroup) {
String label =
studentGroup.getGrouping().getName() + "-" + BundleUtil.getString(Bundle.APPLICATION, "label.group")
+ studentGroup.getGroupNumber();
ArrayList<Recipient> recipients = new ArrayList<Recipient>();
recipients.add(Recipient.newInstance(
label,
Group.users(studentGroup.getAttendsSet().stream().map(Attends::getRegistration).map(Registration::getPerson)
.map(Person::getUser).filter(Objects::nonNull).sorted(User.COMPARATOR_BY_NAME))));
String sendEmailUrl =
UriBuilder
.fromUri("/messaging/emails.do")
.queryParam("method", "newEmail")
.queryParam("sender", ExecutionCourseSender.newInstance(executionCourse).getExternalId())
.queryParam("recipient", recipients.stream().filter(r -> r != null).map(r -> r.getExternalId()).toArray())
.build().toString();
String sendEmailWithChecksumUrl =
GenericChecksumRewriter.injectChecksumInUrl(request.getContextPath(), sendEmailUrl, session);
return new RedirectView(sendEmailWithChecksumUrl, true);
}
@RequestMapping(value = "/deleteStudentGroup/{studentGroup}", method = RequestMethod.POST)
public AbstractUrlBasedView deleteStudentGroup(Model model, @PathVariable Grouping grouping,
@PathVariable StudentGroup studentGroup) {
if (!studentGroup.getAttendsSet().isEmpty()) {
model.addAttribute("errors", "errors.invalid.delete.not.empty.studentGroup");
return viewStudentGroup(model, grouping, studentGroup);
}
studentGroupService.deleteStudentGroup(studentGroup);
return new RedirectView("/teacher/" + executionCourse.getExternalId() + "/student-groups/view/"
+ grouping.getExternalId(), true);
}
}