Package org.fenixedu.academic.domain

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

/**
* 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.domain;

import static org.fenixedu.academic.predicate.AccessControl.check;

import java.math.BigDecimal;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.lang.StringUtils;
import org.fenixedu.academic.domain.degree.DegreeType;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.person.RoleType;
import org.fenixedu.academic.domain.student.Registration;
import org.fenixedu.academic.domain.util.email.ExecutionCourseSender;
import org.fenixedu.academic.domain.util.email.Message;
import org.fenixedu.academic.domain.util.email.Recipient;
import org.fenixedu.academic.predicate.AccessControl;
import org.fenixedu.academic.predicate.ResourceAllocationRolePredicates;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.academic.util.DiaSemana;
import org.fenixedu.academic.util.WeekDay;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.groups.UserGroup;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.joda.time.Duration;

import pt.ist.fenixframework.Atomic;
import pt.ist.fenixframework.dml.runtime.RelationAdapter;

public class Shift extends Shift_Base {

    public static final Comparator<Shift> SHIFT_COMPARATOR_BY_NAME = new Comparator<Shift>() {

        @Override
        public int compare(Shift o1, Shift o2) {
            return Collator.getInstance().compare(o1.getNome(), o2.getNome());
        }

    };

    public static final Comparator<Shift> SHIFT_COMPARATOR_BY_TYPE_AND_ORDERED_LESSONS = new Comparator<Shift>() {

        @Override
        public int compare(Shift o1, Shift o2) {
            final int ce = o1.getExecutionCourse().getNome().compareTo(o2.getExecutionCourse().getNome());
            if (ce != 0) {
                return ce;
            }
            final int cs = o1.getShiftTypesIntegerComparator().compareTo(o2.getShiftTypesIntegerComparator());
            if (cs != 0) {
                return cs;
            }
            final int cl = o1.getLessonsStringComparator().compareTo(o2.getLessonsStringComparator());
            return cl == 0 ? DomainObjectUtil.COMPARATOR_BY_ID.compare(o1, o2) : cl;
        }

    };

    static {
        Registration.getRelationShiftStudent().addListener(new ShiftStudentListener());
    }

    public Shift(final ExecutionCourse executionCourse, Collection<ShiftType> types, final Integer lotacao) {
//        check(this, ResourceAllocationRolePredicates.checkPermissionsToManageShifts);
        super();
        setRootDomainObject(Bennu.getInstance());
        shiftTypeManagement(types, executionCourse);
        setLotacao(lotacao);
        executionCourse.setShiftNames();

        if (getCourseLoadsSet().isEmpty()) {
            throw new DomainException("error.Shift.empty.courseLoads");
        }
    }

    public void edit(List<ShiftType> newTypes, Integer newCapacity, ExecutionCourse newExecutionCourse, String newName,
            String comment) {
        check(this, ResourceAllocationRolePredicates.checkPermissionsToManageShifts);

        ExecutionCourse beforeExecutionCourse = getExecutionCourse();

        final Shift otherShiftWithSameNewName = newExecutionCourse.findShiftByName(newName);
        if (otherShiftWithSameNewName != null && otherShiftWithSameNewName != this) {
            throw new DomainException("error.Shift.with.this.name.already.exists");
        }

        if (newCapacity != null && getStudentsSet().size() > newCapacity.intValue()) {
            throw new DomainException("errors.exception.invalid.finalAvailability");
        }

        setLotacao(newCapacity);
        shiftTypeManagement(newTypes, newExecutionCourse);

        beforeExecutionCourse.setShiftNames();
        if (!beforeExecutionCourse.equals(newExecutionCourse)) {
            newExecutionCourse.setShiftNames();
        }

        if (getCourseLoadsSet().isEmpty()) {
            throw new DomainException("error.Shift.empty.courseLoads");
        }

        setComment(comment);
    }

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

    public void delete() {
        check(this, ResourceAllocationRolePredicates.checkPermissionsToManageShifts);
        DomainException.throwWhenDeleteBlocked(getDeletionBlockers());
        final ExecutionCourse executionCourse = getExecutionCourse();

        for (; !getAssociatedLessonsSet().isEmpty(); getAssociatedLessonsSet().iterator().next().delete()) {
            ;
        }
        for (; !getAssociatedShiftProfessorshipSet().isEmpty(); getAssociatedShiftProfessorshipSet().iterator().next().delete()) {
            ;
        }
        for (; !getShiftDistributionEntriesSet().isEmpty(); getShiftDistributionEntriesSet().iterator().next().delete()) {
            ;
        }

        getAssociatedClassesSet().clear();
        getCourseLoadsSet().clear();
        if (getShiftGroupingProperties() != null) {
            getShiftGroupingProperties().delete();
        }
        setRootDomainObject(null);
        super.deleteDomainObject();

        executionCourse.setShiftNames();
    }

    @jvstm.cps.ConsistencyPredicate
    protected boolean checkRequiredParameters() {
        return getLotacao() != null && !StringUtils.isEmpty(getNome());
    }

    @Deprecated
    public ExecutionCourse getDisciplinaExecucao() {
        return getExecutionCourse();
    }

    public ExecutionCourse getExecutionCourse() {
        CourseLoad courseLoad = getCourseLoadsSet().iterator().next();
        if (courseLoad != null) {
            return courseLoad.getExecutionCourse();
        } else {
            return null;
        }
    }

    public ExecutionSemester getExecutionPeriod() {
        return getExecutionCourse().getExecutionPeriod();
    }

    private void shiftTypeManagement(Collection<ShiftType> types, ExecutionCourse executionCourse) {
        if (executionCourse != null) {
            getCourseLoadsSet().clear();
            for (ShiftType shiftType : types) {
                CourseLoad courseLoad = executionCourse.getCourseLoadByShiftType(shiftType);
                if (courseLoad != null) {
                    addCourseLoads(courseLoad);
                }
            }
        }
    }

    public List<ShiftType> getTypes() {
        List<ShiftType> result = new ArrayList<ShiftType>();
        for (CourseLoad courseLoad : getCourseLoadsSet()) {
            result.add(courseLoad.getType());
        }
        return result;
    }

    public SortedSet<ShiftType> getSortedTypes() {
        SortedSet<ShiftType> result = new TreeSet<ShiftType>();
        for (CourseLoad courseLoad : getCourseLoadsSet()) {
            result.add(courseLoad.getType());
        }
        return result;
    }

    public boolean containsType(ShiftType shiftType) {
        if (shiftType != null) {
            for (CourseLoad courseLoad : getCourseLoadsSet()) {
                if (courseLoad.getType().equals(shiftType)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    protected void checkForDeletionBlockers(Collection<String> blockers) {
        super.checkForDeletionBlockers(blockers);
        if (!getAssociatedStudentGroupsSet().isEmpty()) {
            blockers.add(BundleUtil.getString(Bundle.RESOURCE_ALLOCATION, "error.deleteShift.with.studentGroups", getNome()));
        }
        if (!getStudentsSet().isEmpty()) {
            blockers.add(BundleUtil.getString(Bundle.RESOURCE_ALLOCATION, "error.deleteShift.with.students", getNome()));
        }
        if (!getAssociatedSummariesSet().isEmpty()) {
            blockers.add(BundleUtil.getString(Bundle.RESOURCE_ALLOCATION, "error.deleteShift.with.summaries", getNome()));
        }
    }

    public BigDecimal getTotalHours() {
        Collection<Lesson> lessons = getAssociatedLessonsSet();
        BigDecimal lessonTotalHours = BigDecimal.ZERO;
        for (Lesson lesson : lessons) {
            lessonTotalHours = lessonTotalHours.add(lesson.getTotalHours());
        }
        return lessonTotalHours;
    }

    public Duration getTotalDuration() {
        Duration duration = Duration.ZERO;
        Collection<Lesson> lessons = getAssociatedLessonsSet();
        for (Lesson lesson : lessons) {
            duration = duration.plus(lesson.getTotalDuration());
        }
        return duration;
    }

    public BigDecimal getMaxLessonDuration() {
        BigDecimal maxHours = BigDecimal.ZERO;
        for (Lesson lesson : getAssociatedLessonsSet()) {
            BigDecimal lessonHours = lesson.getUnitHours();
            if (maxHours.compareTo(lessonHours) == -1) {
                maxHours = lessonHours;
            }
        }
        return maxHours;
    }

    public BigDecimal getUnitHours() {
        BigDecimal hours = BigDecimal.ZERO;
        Collection<Lesson> lessons = getAssociatedLessonsSet();
        for (Lesson lesson : lessons) {
            hours = hours.add(lesson.getUnitHours());
        }
        return hours;
    }

    public double getHoursOnSaturdaysOrNightHours(int nightHour) {
        double hours = 0;
        Collection<Lesson> lessons = this.getAssociatedLessonsSet();
        for (Lesson lesson : lessons) {
            if (lesson.getDiaSemana().equals(new DiaSemana(DiaSemana.SABADO))) {
                hours += lesson.getUnitHours().doubleValue();
            } else {
                hours += lesson.hoursAfter(nightHour);
            }
        }
        return hours;
    }

    public int getNumberOfLessonInstances() {
        Collection<Lesson> lessons = getAssociatedLessonsSet();
        int totalLessonsDates = 0;
        for (Lesson lesson : lessons) {
            totalLessonsDates += lesson.getFinalNumberOfLessonInstances();
        }
        return totalLessonsDates;
    }

    public BigDecimal getCourseLoadWeeklyAverage() {
        BigDecimal weeklyHours = BigDecimal.ZERO;
        for (CourseLoad courseLoad : getCourseLoadsSet()) {
            weeklyHours = weeklyHours.add(courseLoad.getWeeklyHours());
        }
        return weeklyHours;
    }

    public BigDecimal getCourseLoadTotalHours() {
        BigDecimal weeklyHours = BigDecimal.ZERO;
        for (CourseLoad courseLoad : getCourseLoadsSet()) {
            weeklyHours = weeklyHours.add(courseLoad.getTotalQuantity());
        }
        return weeklyHours;
    }

    public void associateSchoolClass(SchoolClass schoolClass) {
        if (schoolClass == null) {
            throw new NullPointerException();
        }
        if (!this.getAssociatedClassesSet().contains(schoolClass)) {
            this.getAssociatedClassesSet().add(schoolClass);
        }
        if (!schoolClass.getAssociatedShiftsSet().contains(this)) {
            schoolClass.getAssociatedShiftsSet().add(this);
        }
    }

    public SortedSet<Lesson> getLessonsOrderedByWeekDayAndStartTime() {
        final SortedSet<Lesson> lessons = new TreeSet<Lesson>(Lesson.LESSON_COMPARATOR_BY_WEEKDAY_AND_STARTTIME);
        lessons.addAll(getAssociatedLessonsSet());
        return lessons;
    }

    public String getLessonsStringComparator() {
        final StringBuilder stringBuilder = new StringBuilder();
        for (final Lesson lesson : getLessonsOrderedByWeekDayAndStartTime()) {
            stringBuilder.append(lesson.getDiaSemana().getDiaSemana().toString());
            stringBuilder.append(lesson.getBeginHourMinuteSecond().toString());
        }
        return stringBuilder.toString();
    }

    public Integer getShiftTypesIntegerComparator() {
        final StringBuilder stringBuilder = new StringBuilder();
        for (ShiftType shiftType : getSortedTypes()) {
            stringBuilder.append(shiftType.ordinal() + 1);
        }
        return Integer.valueOf(stringBuilder.toString());
    }

    public boolean reserveForStudent(final Registration registration) {
        final boolean result = getLotacao().intValue() > getStudentsSet().size();
        if (result || isResourceAllocationManager()) {
            GroupsAndShiftsManagementLog.createLog(getExecutionCourse(), Bundle.MESSAGING,
                    "log.executionCourse.groupAndShifts.shifts.attends.added", registration.getNumber().toString(), getNome(),
                    getExecutionCourse().getNome(), getExecutionCourse().getDegreePresentationString());
            addStudents(registration);
        }
        return result;
    }

    private boolean isResourceAllocationManager() {
        final Person person = AccessControl.getPerson();
        return person != null && person.hasRole(RoleType.RESOURCE_ALLOCATION_MANAGER);
    }

    public SortedSet<ShiftEnrolment> getShiftEnrolmentsOrderedByDate() {
        final SortedSet<ShiftEnrolment> shiftEnrolments = new TreeSet<ShiftEnrolment>(ShiftEnrolment.COMPARATOR_BY_DATE);
        shiftEnrolments.addAll(getShiftEnrolmentsSet());
        return shiftEnrolments;
    }

    public String getClassesPrettyPrint() {
        StringBuilder builder = new StringBuilder();
        int index = 0;
        for (SchoolClass schoolClass : getAssociatedClassesSet()) {
            builder.append(schoolClass.getNome());
            index++;
            if (index < getAssociatedClassesSet().size()) {
                builder.append(", ");
            }
        }
        return builder.toString();
    }

    public String getShiftTypesPrettyPrint() {
        StringBuilder builder = new StringBuilder();
        int index = 0;
        SortedSet<ShiftType> sortedTypes = getSortedTypes();
        for (ShiftType shiftType : sortedTypes) {
            builder.append(BundleUtil.getString(Bundle.ENUMERATION, shiftType.getName()));
            index++;
            if (index < sortedTypes.size()) {
                builder.append(", ");
            }
        }
        return builder.toString();
    }

    public String getShiftTypesCapitalizedPrettyPrint() {
        StringBuilder builder = new StringBuilder();
        int index = 0;
        SortedSet<ShiftType> sortedTypes = getSortedTypes();
        for (ShiftType shiftType : sortedTypes) {
            builder.append(shiftType.getFullNameTipoAula());
            index++;
            if (index < sortedTypes.size()) {
                builder.append(", ");
            }
        }
        return builder.toString();
    }

    public String getShiftTypesCodePrettyPrint() {
        StringBuilder builder = new StringBuilder();
        int index = 0;
        SortedSet<ShiftType> sortedTypes = getSortedTypes();
        for (ShiftType shiftType : sortedTypes) {
            builder.append(shiftType.getSiglaTipoAula());
            index++;
            if (index < sortedTypes.size()) {
                builder.append(", ");
            }
        }
        return builder.toString();
    }

    public List<Summary> getExtraSummaries() {
        List<Summary> result = new ArrayList<Summary>();
        Set<Summary> summaries = getAssociatedSummariesSet();
        for (Summary summary : summaries) {
            if (summary.isExtraSummary()) {
                result.add(summary);
            }
        }
        return result;
    }

    private static class ShiftStudentListener extends RelationAdapter<Registration, Shift> {

        @Override
        public void afterAdd(Registration registration, Shift shift) {
            if (!shift.hasShiftEnrolment(registration)) {
                new ShiftEnrolment(shift, registration);
            }
        }

        @Override
        public void afterRemove(Registration registration, Shift shift) {
            shift.unEnrolStudent(registration);
        }
    }

    private boolean hasShiftEnrolment(final Registration registration) {
        for (final ShiftEnrolment shiftEnrolment : getShiftEnrolmentsSet()) {
            if (shiftEnrolment.hasRegistration(registration)) {
                return true;
            }
        }
        return false;
    }

    public void unEnrolStudent(final Registration registration) {
        final ShiftEnrolment shiftEnrolment = findShiftEnrolment(registration);
        if (shiftEnrolment != null) {
            shiftEnrolment.delete();
        }
    }

    private ShiftEnrolment findShiftEnrolment(final Registration registration) {
        for (final ShiftEnrolment shiftEnrolment : getShiftEnrolmentsSet()) {
            if (shiftEnrolment.getRegistration() == registration) {
                return shiftEnrolment;
            }
        }
        return null;
    }

    public int getCapacityBasedOnSmallestRoom() {
        int capacity =
                getAssociatedLessonsSet().stream().filter(Lesson::hasSala)
                        .mapToInt(lesson -> lesson.getSala().getAllocatableCapacity()).min().orElse(0);
        return capacity + (capacity / 10);
    }

    public boolean hasShiftType(final ShiftType shiftType) {
        for (CourseLoad courseLoad : getCourseLoadsSet()) {
            if (courseLoad.getType() == shiftType) {
                return true;
            }
        }
        return false;
    }

    public boolean hasSchoolClassForDegreeType(DegreeType degreeType) {
        for (SchoolClass schoolClass : getAssociatedClassesSet()) {
            if (schoolClass.getExecutionDegree().getDegreeType() == degreeType) {
                return true;
            }
        }
        return false;
    }

    @Atomic
    public void removeAttendFromShift(Registration registration, ExecutionCourse executionCourse) {

        GroupsAndShiftsManagementLog.createLog(getExecutionCourse(), Bundle.MESSAGING,
                "log.executionCourse.groupAndShifts.shifts.attends.removed", registration.getNumber().toString(), getNome(),
                getExecutionCourse().getNome(), getExecutionCourse().getDegreePresentationString());
        registration.removeShifts(this);

        ExecutionCourseSender sender = ExecutionCourseSender.newInstance(executionCourse);
        Collection<Recipient> recipients =
                Collections.singletonList(new Recipient(UserGroup.of(registration.getPerson().getUser())));
        final String subject = BundleUtil.getString(Bundle.APPLICATION, "label.shift.remove.subject");
        final String body = BundleUtil.getString(Bundle.APPLICATION, "label.shift.remove.body", getNome());

        new Message(sender, sender.getConcreteReplyTos(), recipients, subject, body, "");
    }

    public boolean hasAnyStudentsInAssociatedStudentGroups() {
        for (final StudentGroup studentGroup : getAssociatedStudentGroupsSet()) {
            if (studentGroup.getAttendsSet().size() > 0) {
                return true;
            }
        }
        return false;
    }

    public String getPresentationName() {
        StringBuilder stringBuilder = new StringBuilder(this.getNome());
        if (!this.getAssociatedLessonsSet().isEmpty()) {
            stringBuilder.append(" ( ");

            for (Iterator<Lesson> iterator = this.getAssociatedLessonsSet().iterator(); iterator.hasNext();) {
                Lesson lesson = iterator.next();
                stringBuilder.append(WeekDay.getWeekDay(lesson.getDiaSemana()).getLabelShort());
                stringBuilder.append(" ");
                stringBuilder.append(lesson.getBeginHourMinuteSecond().toString("HH:mm"));
                stringBuilder.append(" - ");
                stringBuilder.append(lesson.getEndHourMinuteSecond().toString("HH:mm"));
                if (lesson.hasSala()) {
                    stringBuilder.append(" - ");
                    stringBuilder.append(lesson.getSala().getName());
                }
                if (iterator.hasNext()) {
                    stringBuilder.append(" ; ");
                }
            }
            stringBuilder.append(" ) ");
        }
        return stringBuilder.toString();
    }

    public String getLessonPresentationString() {
        StringBuilder stringBuilder = new StringBuilder(this.getNome());
        if (!this.getAssociatedLessonsSet().isEmpty()) {
            for (Iterator<Lesson> iterator = this.getAssociatedLessonsSet().iterator(); iterator.hasNext();) {
                Lesson lesson = iterator.next();
                stringBuilder.append(" ");
                stringBuilder.append(WeekDay.getWeekDay(lesson.getDiaSemana()).getLabelShort());
                stringBuilder.append(" ");
                stringBuilder.append(lesson.getBeginHourMinuteSecond().toString("HH:mm"));
                stringBuilder.append(" - ");
                stringBuilder.append(lesson.getEndHourMinuteSecond().toString("HH:mm"));
                if (lesson.hasSala()) {
                    stringBuilder.append(" - ");
                    stringBuilder.append(lesson.getSala().getName());
                }
                if (iterator.hasNext()) {
                    stringBuilder.append(" ; ");
                }
            }
        }
        return stringBuilder.toString();
    }

    public List<StudentGroup> getAssociatedStudentGroups(Grouping grouping) {
        List<StudentGroup> result = new ArrayList<StudentGroup>();
        for (StudentGroup studentGroup : getAssociatedStudentGroupsSet()) {
            if (studentGroup.getGrouping() == grouping) {
                result.add(studentGroup);
            }
        }
        return result;
    }

    public boolean isTotalShiftLoadExceeded() {
        final BigDecimal totalHours = getTotalHours();
        for (final CourseLoad courseLoad : getCourseLoadsSet()) {
            if (totalHours.compareTo(courseLoad.getTotalQuantity()) == 1) {
                return true;
            }
        }
        return false;
    }

}
TOP

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

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.