Package org.fenixedu.academic.domain

Source Code of org.fenixedu.academic.domain.Grouping

/**
* 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/>.
*/
/*
* Created on 08/Mar/2005
*
*/
package org.fenixedu.academic.domain;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.academic.util.EnrolmentGroupPolicyType;
import org.fenixedu.academic.util.ProposalState;
import org.fenixedu.bennu.core.domain.Bennu;

import pt.ist.fenixframework.FenixFramework;

/**
* @author joaosa & rmalo
*
*/
public class Grouping extends Grouping_Base {

    public static Comparator<Grouping> COMPARATOR_BY_ENROLMENT_BEGIN_DATE = new Comparator<Grouping>() {

        @Override
        public int compare(Grouping g1, Grouping g2) {
            return g1.getEnrolmentBeginDayDateDateTime().compareTo(g2.getEnrolmentBeginDayDateDateTime());
        }

    };

    public Grouping() {
        super();
        setRootDomainObject(Bennu.getInstance());
    }

    public Calendar getEnrolmentBeginDay() {
        if (this.getEnrolmentBeginDayDate() != null) {
            Calendar result = Calendar.getInstance();
            result.setTime(this.getEnrolmentBeginDayDate());
            return result;
        }
        return null;
    }

    public void setEnrolmentBeginDay(Calendar enrolmentBeginDay) {
        if (enrolmentBeginDay != null) {
            this.setEnrolmentBeginDayDate(enrolmentBeginDay.getTime());
        } else {
            this.setEnrolmentBeginDayDate(null);
        }
    }

    public Calendar getEnrolmentEndDay() {
        if (this.getEnrolmentEndDayDate() != null) {
            Calendar result = Calendar.getInstance();
            result.setTime(this.getEnrolmentEndDayDate());
            return result;
        }
        return null;
    }

    public void setEnrolmentEndDay(Calendar enrolmentEndDay) {
        if (enrolmentEndDay != null) {
            this.setEnrolmentEndDayDate(enrolmentEndDay.getTime());
        } else {
            this.setEnrolmentEndDayDate(null);
        }
    }

    public List<ExecutionCourse> getExecutionCourses() {
        final List<ExecutionCourse> result = new ArrayList<ExecutionCourse>();
        for (final ExportGrouping exportGrouping : this.getExportGroupingsSet()) {
            if (exportGrouping.getProposalState().getState() == ProposalState.ACEITE
                    || exportGrouping.getProposalState().getState() == ProposalState.CRIADOR) {
                result.add(exportGrouping.getExecutionCourse());
            }
        }
        return result;
    }

    public List<StudentGroup> getStudentGroupsWithoutShift() {
        final List<StudentGroup> result = new ArrayList<StudentGroup>();
        for (final StudentGroup studentGroup : this.getStudentGroupsSet()) {
            if (studentGroup.getShift() == null) {
                result.add(studentGroup);
            }
        }
        return result;
    }

    public List<StudentGroup> getStudentGroupsWithShift() {
        final List<StudentGroup> result = new ArrayList<StudentGroup>();
        for (final StudentGroup studentGroup : this.getStudentGroupsSet()) {
            if (studentGroup.getShift() != null) {
                result.add(studentGroup);
            }
        }
        return result;
    }

    public Integer getNumberOfStudentsNotInGrouping() {
        int numberOfStudents = 0;
        for (final ExportGrouping exportGrouping : this.getExportGroupingsSet()) {
            if (exportGrouping.getProposalState().getState() == ProposalState.ACEITE
                    || exportGrouping.getProposalState().getState() == ProposalState.CRIADOR) {
                for (final Attends attend : exportGrouping.getExecutionCourse().getAttendsSet()) {
                    if (!this.getAttendsSet().contains(attend)) {
                        numberOfStudents++;
                    }
                }
            }
        }
        return Integer.valueOf(numberOfStudents);
    }

    public void checkShiftCapacity(Shift shift) {
        List shiftStudentGroups = this.readAllStudentGroupsBy(shift);
        Integer groupMaximumNumber;
        if (this.getDifferentiatedCapacity()) {
            groupMaximumNumber = shift.getShiftGroupingProperties().getCapacity();
        } else {
            groupMaximumNumber = this.getGroupMaximumNumber();
        }
        if (shiftStudentGroups != null && groupMaximumNumber != null && shiftStudentGroups.size() == groupMaximumNumber) {
            throw new DomainException(this.getClass().getName(), "error.shift.with.max.number.of.studentGroups");
        }
    }

    public Integer getNumberOfStudentsInGrouping() {
        return this.getAttendsSet().size();
    }

    public Attends getStudentAttend(final Registration registration) {
        for (final Attends attend : this.getAttendsSet()) {
            if (attend.getRegistration().getStudent() == registration.getStudent()) {
                return attend;
            }
        }
        return null;
    }

    public Attends getStudentAttend(String studentUsername) {
        for (final Attends attend : this.getAttendsSet()) {
            if (attend.getRegistration().getPerson().getUsername().equals(studentUsername)) {
                return attend;
            }
        }
        return null;
    }

    public StudentGroup readStudentGroupBy(Integer studentGroupNumber) {
        for (final StudentGroup studentGroup : this.getStudentGroupsSet()) {
            if (studentGroup.getGroupNumber().equals(studentGroupNumber)) {
                return studentGroup;
            }
        }
        return null;
    }

    public List<StudentGroup> readAllStudentGroupsBy(Shift shift) {
        final List<StudentGroup> result = new ArrayList<StudentGroup>();
        for (final StudentGroup studentGroup : this.getStudentGroupsSet()) {
            if (studentGroup.getShift() == shift) {
                result.add(studentGroup);
            }
        }
        return result;
    }

    public static Grouping create(String goupingName, Date enrolmentBeginDay, Date enrolmentEndDay,
            EnrolmentGroupPolicyType enrolmentGroupPolicyType, Integer groupMaximumNumber, Integer idealCapacity,
            Integer maximumCapacity, Integer minimumCapacity, String projectDescription, ShiftType shiftType,
            Boolean automaticEnrolment, Boolean differentiatedCapacity, ExecutionCourse executionCourse,
            Map<String, Integer> shiftCapacityMap) {

        if (goupingName == null || enrolmentBeginDay == null || enrolmentEndDay == null || enrolmentGroupPolicyType == null) {
            throw new NullPointerException();
        }

        checkIfGroupingAlreadyExistInExecutionCourse(goupingName, executionCourse);

        Grouping grouping = new Grouping();
        grouping.setName(goupingName);
        grouping.setEnrolmentBeginDayDate(enrolmentBeginDay);
        grouping.setEnrolmentEndDayDate(enrolmentEndDay);
        grouping.setEnrolmentPolicy(enrolmentGroupPolicyType);
        grouping.setGroupMaximumNumber(groupMaximumNumber);
        grouping.setIdealCapacity(idealCapacity);
        grouping.setMaximumCapacity(maximumCapacity);
        grouping.setMinimumCapacity(minimumCapacity);
        grouping.setProjectDescription(projectDescription);
        grouping.setShiftType(shiftType);
        grouping.setAutomaticEnrolment(automaticEnrolment);
        grouping.setDifferentiatedCapacity(differentiatedCapacity);

        ExportGrouping exportGrouping = new ExportGrouping(grouping, executionCourse);
        exportGrouping.setProposalState(new ProposalState(ProposalState.CRIADOR));

        addGroupingToAttends(grouping, executionCourse.getAttendsSet());
        GroupsAndShiftsManagementLog.createLog(executionCourse, Bundle.MESSAGING,
                "log.executionCourse.groupAndShifts.grouping.added", grouping.getName(), executionCourse.getNome(),
                executionCourse.getDegreePresentationString());

        if (differentiatedCapacity) {
            setDiferentiatedCapacityShiftsGroupingProperties(shiftType, shiftCapacityMap, grouping);
        }
        return grouping;

    }

    private static void addGroupingToAttends(final Grouping grouping, final Collection<Attends> attends) {
        for (final Attends attend : attends) {
            attend.addGroupings(grouping);
        }
    }

    private static void checkIfGroupingAlreadyExistInExecutionCourse(final String goupingName,
            final ExecutionCourse executionCourse) {
        if (executionCourse.getGroupingByName(goupingName) != null) {
            throw new DomainException("error.exception.existing.groupProperties");
        }
    }

    public void edit(String goupingName, Date enrolmentBeginDay, Date enrolmentEndDay,
            EnrolmentGroupPolicyType enrolmentGroupPolicyType, Integer groupMaximumNumber, Integer idealCapacity,
            Integer maximumCapacity, Integer minimumCapacity, String projectDescription, ShiftType shiftType,
            Boolean automaticEnrolment, Boolean differentiatedCapacity, Map<String, Integer> shiftCapacityMap) {

        if (goupingName == null || enrolmentBeginDay == null || enrolmentEndDay == null || enrolmentGroupPolicyType == null) {
            throw new NullPointerException();
        }

        checkIfGroupingAlreadyExists(goupingName);

        if (getDifferentiatedCapacity() && !differentiatedCapacity) {
            if (!super.getStudentGroupsSet().isEmpty()) {
                throw new DomainException(this.getClass().getName(), "error.groupProperties.edit.attendsSet.withGroups");
            }

            Collection<ShiftGroupingProperties> shiftGroupingProperties = this.getShiftGroupingPropertiesSet();
            for (ShiftGroupingProperties shiftGP : shiftGroupingProperties) {
                shiftGP.delete();
            }
        } else if (getDifferentiatedCapacity() && differentiatedCapacity && isShiftTypeDifferent(shiftType)) {
            if (!super.getStudentGroupsSet().isEmpty()) {
                throw new DomainException(this.getClass().getName(), "error.groupProperties.edit.attendsSet.withGroups");
            }

            Collection<ShiftGroupingProperties> shiftGroupingProperties = this.getShiftGroupingPropertiesSet();
            for (ShiftGroupingProperties shiftGP : shiftGroupingProperties) {
                shiftGP.delete();
            }
        }

        Integer groupMaximumNumberFix;

        if (groupMaximumNumber == null) {
            groupMaximumNumberFix = Integer.MAX_VALUE;
        } else {
            groupMaximumNumberFix = groupMaximumNumber;
        }

        if (!differentiatedCapacity && groupMaximumNumberFix < getMaxStudentGroupsCount()) {
            throw new DomainException(this.getClass().getName(),
                    "error.groupProperties.edit.maxGroupCap.inferiorToExistingNumber");
        }

        setName(goupingName);
        setEnrolmentBeginDayDate(enrolmentBeginDay);
        setEnrolmentEndDayDate(enrolmentEndDay);
        setEnrolmentPolicy(enrolmentGroupPolicyType);
        setGroupMaximumNumber(groupMaximumNumber);
        setIdealCapacity(idealCapacity);
        setMaximumCapacity(maximumCapacity);
        setMinimumCapacity(minimumCapacity);
        setProjectDescription(projectDescription);
        setShiftType(shiftType);
        setAutomaticEnrolment(automaticEnrolment);
        setDifferentiatedCapacity(differentiatedCapacity);

        if (!differentiatedCapacity) {
            Collection<ShiftGroupingProperties> shiftGroupingProperties = this.getShiftGroupingPropertiesSet();
            for (ShiftGroupingProperties shiftGP : shiftGroupingProperties) {
                shiftGP.delete();
            }
        } else {
            setDiferentiatedCapacityShiftsGroupingProperties(shiftType, shiftCapacityMap, this);
        }

        if (shiftType == null) {
            unEnrollStudentGroups(this.getStudentGroupsSet());
        }

        List<ExecutionCourse> ecs = getExecutionCourses();
        for (ExecutionCourse ec : ecs) {
            GroupsAndShiftsManagementLog.createLog(ec, Bundle.MESSAGING, "log.executionCourse.groupAndShifts.grouping.edited",
                    getName(), ec.getNome(), ec.getDegreePresentationString());
        }

    }

    private static void setDiferentiatedCapacityShiftsGroupingProperties(ShiftType shiftType,
            Map<String, Integer> shiftCapacityMap, Grouping grouping) {
        shiftCapacityMap.forEach((shiftID, capacity) -> {
            Shift shift = ((Shift) FenixFramework.getDomainObject(shiftID));
            if (shift.getTypes().contains(shiftType)) {
                if (capacity != null && grouping.getStudentGroupsIndexedByShift().get(shift) != null
                        && capacity < grouping.getStudentGroupsIndexedByShift().get(shift).size()) {
                    throw new DomainException("error.groupProperties.edit.maxGroupCap.inferiorToExistingNumber");
                }
                if (shift.getShiftGroupingProperties() == null) {
                    shift.setShiftGroupingProperties(new ShiftGroupingProperties(shift, grouping, capacity));
                } else {
                    shift.getShiftGroupingProperties().setCapacity(capacity);
                }
            }
        });
    }

    private boolean isShiftTypeEqual(ShiftType shiftType) {
        return ((shiftType != null && getShiftType() != null && getShiftType().compareTo(shiftType) == 0) || (shiftType == null && getShiftType() == null));
    }

    private boolean isShiftTypeDifferent(ShiftType shiftType) {
        return (((shiftType == null && getShiftType() != null) || (shiftType != null && getShiftType() == null)) || getShiftType()
                .compareTo(shiftType) != 0);
    }

    private Integer getMaxStudentGroupsCount() {
        final Map<Object, Integer> shiftCountMap = new HashMap<Object, Integer>();
        for (final StudentGroup studentGroup : super.getStudentGroupsSet()) {
            if (!studentGroup.wasDeleted()) {
                final Shift shift = studentGroup.getShift();
                final int count = shiftCountMap.containsKey(shift) ? shiftCountMap.get(shift) + 1 : 1;
                shiftCountMap.put(shift, Integer.valueOf(count));
            }
        }
        int max = 0;
        for (final Integer i : shiftCountMap.values()) {
            if (i.intValue() > max) {
                max = i.intValue();
            }
        }
        return max;
    }

    private void checkIfGroupingAlreadyExists(String groupingName) {
        if (!this.getName().equals(groupingName)) {
            for (final ExecutionCourse executionCourse : this.getExecutionCourses()) {
                if (executionCourse.getGroupingByName(groupingName) != null) {
                    throw new DomainException(this.getClass().getName(), "error.exception.existing.groupProperties");
                }
            }
        }
    }

    private void unEnrollStudentGroups(Collection<StudentGroup> studentGroups) {
        for (final StudentGroup studentGroup : studentGroups) {
            studentGroup.setShift(null);
        }
    }

    public void createStudentGroup(Shift shift, Integer groupNumber, List<Registration> students) {

        if (groupNumber == null || students == null) {
            throw new NullPointerException();
        }

        if (readStudentGroupBy(groupNumber) != null) {
            throw new DomainException(this.getClass().getName(), "error.invalidGroupNumber");
        }

        checkForStudentsInStudentGroupsAndGrouping(students);

        StudentGroup newStudentGroup = null;
        if (shift != null) {
            newStudentGroup = new StudentGroup(groupNumber, this, shift);
        } else {
            newStudentGroup = new StudentGroup(groupNumber, this);
        }

        StringBuilder sbStudentNumbers = new StringBuilder("");
        sbStudentNumbers.setLength(0);
        for (Registration registration : students) {
            Attends attend = getStudentAttend(registration);
            newStudentGroup.addAttends(attend);
            if (sbStudentNumbers.length() != 0) {
                sbStudentNumbers.append(", " + registration.getNumber().toString());
            } else {
                sbStudentNumbers.append(registration.getNumber().toString());
            }
        }

        final String labelKey;
        if (sbStudentNumbers.length() == 0) {
            labelKey = "log.executionCourse.groupAndShifts.grouping.group.added.empty";
        } else {
            labelKey = "log.executionCourse.groupAndShifts.grouping.group.added";
        }

        List<ExecutionCourse> ecs = getExecutionCourses();
        for (ExecutionCourse ec : ecs) {
            GroupsAndShiftsManagementLog.createLog(ec, Bundle.MESSAGING, labelKey, groupNumber.toString(), getName(),
                    Integer.toString(students.size()), sbStudentNumbers.toString(), ec.getNome(),
                    ec.getDegreePresentationString());
        }
    }

    private void checkForStudentsInStudentGroupsAndGrouping(List<Registration> students) {
        for (Registration registration : students) {
            Attends attend = getStudentAttend(registration);
            for (final StudentGroup studentGroup : this.getStudentGroupsSet()) {
                if (studentGroup.getAttendsSet().contains(attend)) {
                    throw new DomainException(this.getClass().getName(), "errors.existing.studentEnrolment");
                } else if (!this.getAttendsSet().contains(attend)) {
                    throw new DomainException(this.getClass().getName(), "errors.notExisting.studentInGrouping");
                }
            }
        }
    }

    public void delete() {

        if (!super.getStudentGroupsSet().isEmpty()) {
            throw new DomainException(this.getClass().getName(), "");
        }

        if (getGroupingGroup() != null) {
            throw new DomainException("error.grouping.cannotDeleteGroupingUsedInAccessControl");
        }

        List<ExecutionCourse> ecs = getExecutionCourses();
        for (ExecutionCourse ec : ecs) {
            GroupsAndShiftsManagementLog.createLog(ec, Bundle.MESSAGING, "log.executionCourse.groupAndShifts.grouping.removed",
                    getName(), ec.getNome(), ec.getDegreePresentationString());
        }

        Collection<Attends> attends = this.getAttendsSet();
        List<Attends> attendsAux = new ArrayList<Attends>();
        attendsAux.addAll(attends);
        for (Attends attend : attendsAux) {
            attend.removeGroupings(this);
        }

        Collection<ExportGrouping> exportGroupings = this.getExportGroupingsSet();
        List<ExportGrouping> exportGroupingsAux = new ArrayList<ExportGrouping>();
        exportGroupingsAux.addAll(exportGroupings);
        for (ExportGrouping exportGrouping : exportGroupingsAux) {
            ExecutionCourse executionCourse = exportGrouping.getExecutionCourse();
            executionCourse.removeExportGroupings(exportGrouping);
            exportGrouping.delete();
        }

        for (ShiftGroupingProperties shiftGP : getShiftGroupingPropertiesSet()) {
            shiftGP.delete();
        }

        for (Project project : getProjectsSet()) {
            project.delete();
        }

        setRootDomainObject(null);
        super.deleteDomainObject();
    }

    public int findMaxGroupNumber() {
        int max = 0;
        for (final StudentGroup studentGroup : super.getStudentGroupsSet()) {
            max = Math.max(max, studentGroup.getGroupNumber().intValue());
        }
        return max;
    }

    public ExportGrouping getExportGrouping(final ExecutionCourse executionCourse) {
        for (final ExportGrouping exportGrouping : this.getExportGroupingsSet()) {
            if (exportGrouping.getExecutionCourse() == executionCourse) {
                return exportGrouping;
            }
        }
        return null;
    }

    public boolean hasExportGrouping(final ExecutionCourse executionCourse) {
        return getExportGrouping(executionCourse) != null;
    }

    public StudentGroup getStudentGroupByAttends(Attends attends) {
        for (StudentGroup studentGroup : getStudentGroupsSet()) {
            if (studentGroup.getAttendsSet().contains(attends)) {
                return studentGroup;
            }
        }

        return null;
    }

    public Map<Shift, SortedSet<StudentGroup>> getStudentGroupsIndexedByShift() {
        final Map<Shift, SortedSet<StudentGroup>> map =
                new TreeMap<Shift, SortedSet<StudentGroup>>(Shift.SHIFT_COMPARATOR_BY_TYPE_AND_ORDERED_LESSONS);
        for (final StudentGroup studentGroup : getStudentGroupsSet()) {
            if (studentGroup.getShift() != null) {
                final Shift shift = studentGroup.getShift();
                final SortedSet<StudentGroup> studentGroups;
                if (map.containsKey(shift)) {
                    studentGroups = map.get(shift);
                } else {
                    studentGroups = new TreeSet<StudentGroup>(StudentGroup.COMPARATOR_BY_GROUP_NUMBER);
                    map.put(shift, studentGroups);
                }
                studentGroups.add(studentGroup);
            }
        }
        return map;
    }

    public SortedSet<StudentGroup> getStudentGroupsOrderedByGroupNumber() {
        final SortedSet<StudentGroup> studentGroups = new TreeSet<StudentGroup>(StudentGroup.COMPARATOR_BY_GROUP_NUMBER);
        studentGroups.addAll(getStudentGroupsSet());
        return studentGroups;
    }

    public boolean isPersonTeacher(Person person) {
        for (ExecutionCourse ec : getExecutionCourses()) {
            for (Professorship professorship : ec.getProfessorshipsSet()) {
                if (professorship.getPerson() == person) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public Set<StudentGroup> getStudentGroupsSet() {
        Set<StudentGroup> result = new HashSet<StudentGroup>();
        for (StudentGroup sg : super.getStudentGroupsSet()) {
            if (!sg.wasDeleted()) {
                result.add(sg);
            }
        }
        return Collections.unmodifiableSet(result);
    }

    public List<StudentGroup> getDeletedStudentGroups() {
        List<StudentGroup> result = new ArrayList<StudentGroup>();
        for (StudentGroup sg : super.getStudentGroupsSet()) {
            if (!sg.getValid()) {
                result.add(sg);
            }
        }
        return result;
    }

    @Deprecated
    public java.util.Date getEnrolmentBeginDayDate() {
        org.joda.time.DateTime dt = getEnrolmentBeginDayDateDateTime();
        return (dt == null) ? null : new java.util.Date(dt.getMillis());
    }

    @Deprecated
    public void setEnrolmentBeginDayDate(java.util.Date date) {
        if (date == null) {
            setEnrolmentBeginDayDateDateTime(null);
        } else {
            setEnrolmentBeginDayDateDateTime(new org.joda.time.DateTime(date.getTime()));
        }
    }

    @Deprecated
    public java.util.Date getEnrolmentEndDayDate() {
        org.joda.time.DateTime dt = getEnrolmentEndDayDateDateTime();
        return (dt == null) ? null : new java.util.Date(dt.getMillis());
    }

    @Deprecated
    public void setEnrolmentEndDayDate(java.util.Date date) {
        if (date == null) {
            setEnrolmentEndDayDateDateTime(null);
        } else {
            setEnrolmentEndDayDateDateTime(new org.joda.time.DateTime(date.getTime()));
        }
    }

}
TOP

Related Classes of org.fenixedu.academic.domain.Grouping

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.