Subversion Repositories bacoAlunos

Rev

Rev 1750 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.domain.dao.impl;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.sql.JoinFragment;
import pt.estgp.estgweb.domain.*;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.domain.dao.DaoUtils;
import pt.estgp.estgweb.services.common.SearchTypeEnum;
import pt.estgp.estgweb.utils.DatesUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static org.hibernate.criterion.Restrictions.*;

/**
 * @author Jorge Machado
 * @date 28/Fev/2008
 * @time 2:51:06
 * @see pt.estgp.estgweb.domain.dao.impl
 */

public class CourseUnitDaoImpl extends CourseUnitDao
{

    private static final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger = 1.5.0/docs/api/java/util/logging/Logger.html">Logger.getLogger(CourseUnitDaoImpl.class);


    public CourseUnitDaoImpl()
    {
    }

    public static CourseUnitDaoImpl getInstance()
    {
        if (myInstance == null)
            myInstance = new CourseUnitDaoImpl();
        return (CourseUnitDaoImpl) myInstance;
    }

    public List<CourseUnit> loadBySigesCode(1.5.0/docs/api/java/lang/String.html">String sigesCode)
    {
        return createCriteria().add(eq("code", sigesCode)).list();
    }

    public List<CourseUnit> loadByCourse(long course, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(eq("importYear", importYear)).add(eq("course.id", course)).list();
    }

    public List<CourseUnit> loadByCourseSiges(1.5.0/docs/api/java/lang/String.html">String course, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(eq("importYear", importYear)).add(eq("course.code", course)).list();
    }

    public List<CourseUnit> loadByCourseTurma(long courseId, 1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String turma) {
        5+0%2Fdocs%2Fapi+List">List o =  createCriteria()
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                .createAlias("turmas", "turma")
                .add(eq("importYear",importYear))
                .add(eq("course.id", courseId))
                .add(eq("turma.turma", turma))
                .list();
        return o;
    }

    public List<CourseUnit> load(1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        return createCriteria().add(eq("importYear", importYear)).add(eq("semestre", semestre)).list();
    }

    public List<Long> loadByYearInstitutionCode(1.5.0/docs/api/java/lang/String.html">String importYear, int institutionCode)
    {
        return createCriteria()
                .createAlias("course", "c")
                .createAlias("c.department", "d")
                .createAlias("d.courseSchool","sc")
                .setProjection(Projections.property("id"))
                .add(eq("importYear", importYear))
                .add(eq("sc.institutionalCode", institutionCode+""))
                .list();
    }

    public List<CourseUnit> loadYear(1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(eq("importYear", importYear)).list();
    }

   

    public List<Long> loadIds(1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        if(semestre == null || semestre.trim().length() == 0)
            return loadIds(importYear);
        1.5.0/docs/api/javax/management/Query.html">Query q = createQuery("select c.id from c in class " + CourseUnit.class.getName() + " where c.importYear = ? and c.semestre = ?");
        q.setString(0, importYear);
        q.setString(1, semestre);
        return q.list();
    }

    public List<Long> loadIds(1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        1.5.0/docs/api/javax/management/Query.html">Query q = createQuery("select c.id from c in class " + CourseUnit.class.getName() + " where c.importYear = ?");
        q.setString(0, importYear);
        //q.setString(1, semestre);
        return q.list();
    }

    public List<CourseUnit> loadSubscribedImportYearUnits(long studentId, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria()
                .createAlias("students", "st")
                .add(eq("st.id", studentId))
                                .add(eq("importYear", importYear))
                                .addOrder(Order.asc("name"))
                                .list();
    }
    public List<CourseUnit> loadSubscribedImportYearSemestreUnits(long studentId, 1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        Criteria c  =createCriteria()
                                .createAlias("students", "st")
                                .add(eq("st.id", studentId))
                .add(eq("importYear", importYear));
        if(semestre != null)
            c.add(eq("semestre", semestre));
        return c.addOrder(Order.asc("name")).list();
    }

    public List<CourseUnit> loadSubscribedOtherImportYearUnits(long studentId, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(not(eq("importYear", importYear)))
                .createAlias("students", "st")
                .add(eq("st.id", studentId)).addOrder(Order.asc("name")).list();
    }

    public List<CourseUnitImpl> loadTeachedImportYearUnits(long teacherId, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(eq("importYear", importYear))
                .createAlias("teachers", "st")
                .add(eq("st.id", teacherId)).addOrder(Order.asc("importYear")).addOrder(Order.asc("name")).list();
    }

    public List<CourseUnitImpl> loadResponsableImportYearUnits(long teacherId, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return createCriteria().add(eq("importYear", importYear))
                .add(eq("responsableTeacher.id", teacherId)).addOrder(Order.asc("importYear")).addOrder(Order.asc("name")).list();
    }

    public List<CourseUnit> loadTeachedImportYearSemestreUnits(long teacherId, 1.5.0/docs/api/java/lang/String.html">String importYear)
    {
        return loadTeachedImportYearSemestreUnits(teacherId, importYear,null);
    }
    public List<CourseUnit> loadTeachedImportYearSemestreUnits(long teacherId, 1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        Criteria c  =createCriteria()
                .add(eq("importYear", importYear))
                .createAlias("teachers", "st")
                .add(eq("st.id", teacherId))
                .add(eq("st.id", teacherId));
        if(semestre != null)
            c.add(eq("semestre", semestre));
        return c.addOrder(Order.asc("name")).list();
    }



    public CourseUnit loadBySigesCodeUnique(1.5.0/docs/api/java/lang/String.html">String sigesCode)
    {
        return (CourseUnit) createCriteria().add(eq("code", sigesCode)).uniqueResult();
    }

    public CourseUnit loadBySigesCodeUnique(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode)
    {
        return (CourseUnit) createCriteria().add(eq("code", sigesCode)).add(eq("courseCode", courseCode)).uniqueResult();
    }

    public CourseUnit loadBySigesCodeUniqueSubscribed(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String year, 1.5.0/docs/api/java/lang/String.html">String courseCode, long studentId, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        List<CourseUnit> cus = createCriteria()
                .add(eq("code", sigesCode))
                .add(eq("importYear", year))
                .add(eq("courseCode", courseCode))
                .add(eq("semestre", semestre))
                .createAlias("students", "st")
                .add(eq("st.id", studentId))
                .list();
        if (cus.size() > 1)
        {
            CourseUnit cu1 = cus.get(0);
            CourseUnit cu2 = cus.get(1);
            if (cus.size() > 2)
            {
                logger.error("CourseUnit in more than two places in a course:" + cu1.getCode());
            }
            else
            {
                if (cu1.getSemestre().equals("S1"))
                {
                    if (cu2.getSemestre().equals("S1"))
                        logger.error("CourseUnit in more than two places in a semestre:" + cu1.getCode());
                    else
                    {
                        return cu2;
                    }
                }
                else
                {
                    if (cu2.getSemestre().equals("S2"))
                        logger.error("CourseUnit in more than two places in a semestre:" + cu1.getCode());
                    else
                    {
                        return cu1;
                    }
                }
            }
        }
        else if (cus.size() == 1)
            return cus.get(0);

        return null;
    }


    public void consistCourseUnitCourseCodes(1.5.0/docs/api/java/lang/String.html">String importYear)
    {
           List<CourseUnit> courseUnit =  createCriteria()
                        .add(eq("importYear", importYear)).list();
        for(CourseUnit cu: courseUnit)
        {
            if(cu.getCourse() != null)
            {
                if(cu.getCourseCode() == null || (cu.getCourseCode() != null && !cu.getCourseCode().equals(cu.getCourse().getCode())))
                {
                    1.5.0/docs/api/java/lang/System.html">System.out.println("Course code wrong: " + cu.getId() + " - " + cu.getName() + " old CourseCode " + cu.getCourseCode() + " now:" + cu.getCourse().getCode() );
                }

                if(cu.getCourseName() == null || (cu.getCourseName() != null && !cu.getCourseName().equals(cu.getCourse().getName())))
                {
                    1.5.0/docs/api/java/lang/System.html">System.out.println("Course name wrong: " + cu.getId() + " - " + cu.getName() + " old CourseCode " + cu.getCourseName() + " now:" + cu.getCourse().getName() );
                }
                cu.setCourseCode(cu.getCourse().getCode());
                cu.setCourseName(cu.getCourse().getName());
            }
            else
            {
                cu.setCourseCode("");
                cu.setCourseName("");
            }
        }
    }


    //TODO Na actualizacao de uma cadeira para o curso de TESTE mudar o coursecode para o o coursecode desse curso para nao deixar os dados duplicados e mal
    //se nao a carregar unidades vai buscar a errada

    /**
     * Turma required to be unique in BACO Model
     * @param sigesCode
     * @param courseCode
     * @param semestre
     * @param year
     * @return
     */

    public List<CourseUnit> loadBySigesCode(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        return
                createCriteria()
                        .add(eq("code", sigesCode))
                        .add(eq("courseCode", courseCode))
                        .add(eq("semestre", semestre))
                        .add(eq("importYear", year))
                        .list();
    }

    /**
     * Metodo especial para a fase de transicao para terem código de turma
     * @param sigesCode
     * @param courseCode
     * @param semestre
     * @param year
     * @return
     */

    public List<CourseUnit> loadBySigesCodeTurmaNull(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        //todo cdTurma Rollback
        return (List<CourseUnit>)
                createCriteria()
                        .add(eq("code", sigesCode))
                        .add(eq("courseCode", courseCode))
                        .add(eq("semestre", semestre))
                        .add(eq("importYear", year))
                        .add(isNull("cdTurma"))
                        .list();
    }

    public List<CourseUnit> loadBySigesCodeUniqueIgnoreCourse(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        return loadBySigesCodeUnique(sigesCode,null,semestre,year);
    }
    //TODO Na actualizacao de uma cadeira para o curso de TESTE mudar o coursecode para o o coursecode desse curso para nao deixar os dados duplicados e mal
    //se nao a carregar unidades vai buscar a errada
    public List<CourseUnit> loadBySigesCodeUnique(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        Criteria c =  createCriteria();
        if(courseCode != null)
            c.add(eq("courseCode", courseCode));

        c.add(eq("code", sigesCode))
         .add(eq("semestre", semestre))
         .add(eq("importYear", year));
                //not any more .add(eq("cdTurma", turma))

        List<CourseUnit> cus = c.list();
        if(cus.size() > 1)
        {
            logger.warn("WARNING WARNING ####Two units found for: ");
            logger.warn("WARNING WARNING ####String sigesCode, String courseCode, String semestre, String year = " + sigesCode + ", " + courseCode + "," + semestre + "," + year);
            logger.warn("WARNING WARNING ####returning first one, this could be a case of units spared because of TURMAS split used in 201516: ");
        }

        return cus;
    }

    public List<CourseUnit> loadBySigesCodeUniqueWithTurmaIgnoreCourse(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year,1.5.0/docs/api/java/lang/String.html">String turma){
        return loadBySigesCodeUniqueWithTurma(sigesCode,null,semestre,year,turma);
    }
    public List<CourseUnit> loadBySigesCodeUniqueWithTurma(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year,1.5.0/docs/api/java/lang/String.html">String turma)
    {
        Criteria c =  createCriteria();
        if(courseCode != null)
            c.add(eq("courseCode", courseCode));

        c.add(eq("code", sigesCode))
            .add(eq("semestre", semestre))
            .add(eq("importYear", year))
            .add(eq("cdTurma", turma));
        List<CourseUnit> cus = c.list();
        if(cus.size() > 1)
        {
            logger.warn("WARNING WARNING ####Two units found for: ");
            logger.warn("WARNING WARNING ####String sigesCode, String courseCode, String semestre, String year = " + sigesCode + ", " + courseCode + "," + semestre + "," + year);
            logger.warn("WARNING WARNING ####returning first one, this could be a case of units spared because of TURMAS split used in 201516: ");
        }

        return cus;
    }

    public List<CourseUnit> loadBySigesCodeUniqueAllCourses(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        //todo cdTurma Rollback
        return
                createCriteria()
                        .add(eq("code", sigesCode))
                        // REMOVED TO LET BE ALL COURSES .add(eq("courseCode", courseCode))
                        .add(eq("semestre", semestre))
                        .add(eq("importYear", year))
                        //not anymore .add(eq("cdTurma", turma))
                        .list();
    }

    public CourseUnit loadBySigesCodeUniqueMostRecent(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        List<CourseUnit> cus;
        Criteria cr = createCriteria()
                        .add(eq("code", sigesCode))
                        .add(eq("courseCode", courseCode));
        if(semestre != null)
            cr.add(eq("semestre", semestre));
        cr.addOrder(Order.desc("importYear")).setMaxResults(1);
        cus = cr.list();
        if(cus.size() > 0)
            return cus.get(0);
        logger.warn("Accessing unit not existent with siges code " + sigesCode + " course code: " + courseCode + " semestre: " + semestre);
        return null;
    }

    public CourseUnit loadBySigesCodeUniqueMostRecentProgram(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        List<CourseUnit> cus;
        Criteria cr = createCriteria()
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode));
        if(semestre != null)
            cr.add(eq("semestre", semestre));
        cr.add(and(isNotNull("programStreamId"),not(eq("programStreamId",""))));
        cr.addOrder(Order.desc("importYear")).setMaxResults(1);
        cus = cr.list();
        if(cus.size() > 0)
            return cus.get(0);
        logger.warn("Accessing unit not existent with siges code " + sigesCode + " course code: " + courseCode + " semestre: " + semestre);
        return null;
    }


    public CourseUnit loadBySigesCodeUniqueLastYear(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        return loadBySigesCodeUniqueMostRecent(sigesCode,courseCode,semestre);
    }

    public CourseUnit loadBySigesCodeUniqueLastYearProgram(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String semestre)
    {
        return loadBySigesCodeUniqueMostRecentProgram(sigesCode,courseCode,semestre);
    }


    public List<CourseUnit> loadBySigesCodeUnique(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        return createCriteria()
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode))
                .add(eq("importYear", year))
                .addOrder(Order.desc("id"))
                .list();        
    }

    public List<CourseUnit> loadBySigesCodeUniqueWithProgram(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode)
    {
        return createCriteria()
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode))
                .add(not(isNull("courseUnitProgram")))
                .addOrder(Order.desc("id"))

                .list();
    }

    public List<CourseUnit> loadBySigesCodes(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode)
    {
        return (List<CourseUnit>) createCriteria()
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode))
                .addOrder(Order.desc("importYear"))
                .list();
    }

    /**
     * Metodo usado para carregar unidades de anos anteriores que possam estar em edição
     * para mostrar na página da unidade
     *
     * Este metodo nao serve para mais nada, nao é usado nas Tarefas da Home
     * @param sigesCode
     * @param courseCode
     * @return
     */

    public CourseUnit loadUnitInEvaluationBySigesCodes(1.5.0/docs/api/java/lang/String.html">String sigesCode, 1.5.0/docs/api/java/lang/String.html">String courseCode)
    {
        1.5.0/docs/api/java/lang/String.html">String activeImportYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion crtDegrees = getCourseUnitActiveDegreeCourseIdsCriterion(activeImportYear);
        if(crtDegrees == null)
        {
            //Nao ha graus nem cursos portanto o ano não interessa
            //o ano deve ser usado para abrir graus ou cursos senao nao
            //abre nada
            crtDegrees = eq("evaluationOpenByAdmin",true);
        }
        else
        {
            crtDegrees = and(eq("importYear", activeImportYear),crtDegrees);
            crtDegrees = or(eq("evaluationOpenByAdmin",true),crtDegrees);
        }

        List<CourseUnit> cus = (List<CourseUnit>) createCriteria()
                .createAlias("course","c")
                .createAlias("courseUnitEvaluation","ce")
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode))
                .add(crtDegrees)
                .add(eq("ce.closed",false))
                .list();
        List<CourseUnit> cusNull = (List<CourseUnit>) createCriteria()
                .createAlias("course","c")
                .add(eq("code", sigesCode))
                .add(eq("courseCode", courseCode))
                .add(crtDegrees)
                .add(isNull("courseUnitEvaluation"))
                .list();
        cus.addAll(cusNull);
        if(cus != null && cus.size() > 1)
        {
            logger.warn("Mais do que uma unidade do mesmo codigo em avaliacao curricular, e suposto haver apenas uma, verificar logica aplicacional");
        }
        else if(cus != null && cus.size() > 0)
        {
            return cus.get(0);
        }

        return null;
    }

    public List<CourseUnit> loadCourseUnits(long courseId, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year, boolean withTeacher, boolean withNoTeacher)
    {
        return loadCourseUnits( courseId,  semestre,  year,  withTeacher,  withNoTeacher,null);
    }
    public List<CourseUnit> loadCourseUnits(long courseId, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year, boolean withTeacher, boolean withNoTeacher,1.5.0/docs/api/java/lang/String.html">String institutionCode)
    {
        Criteria c = createCriteria()
                .createAlias("course","c")
                .createAlias("c.department","d")
                .createAlias("d.courseSchool","sc");
        if(courseId > 0)
            c.add(eq("c.id", courseId));
        if(semestre != null && semestre.trim().length() > 0)
            c.add(eq("semestre", semestre));
        if(year != null  && year.trim().length() > 0)
            c.add(eq("importYear", year));
        if(institutionCode != null && institutionCode.trim().length() > 0)
            c.add(eq("sc.institutionalCode", institutionCode));

        if(withTeacher && !withNoTeacher)
        {
            c.createAlias("teachers", "th");
            c.add(isNotNull("th.id"));
        }
        else if(!withTeacher && withNoTeacher)
        {
            c.createAlias("teachers", "th", JoinFragment.LEFT_OUTER_JOIN);
            c.add(isNull("th.id"));
        }
        return c.list();
    }

    public CourseUnit findUnitByCourseNameYear(long courseId, 1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/String.html">String importYear) {
        List<CourseUnit> courseUnit = createCriteria().
                createAlias("course","c").
                add(eq("c.id",courseId)).
                add(eq("importYear",importYear)).
                add(eq("name",name)).list();
        if(courseUnit.size() > 0)
            return courseUnit.get(0);
        return null;

    }


    public static class CourseUnitResult
    {
        public long id = 0;
        public int students = 0;
        public int teachers = 0;
        public int turmas = 0;
    }
    /**
     *
     * @param courseId
     * @param semestre
     * @param year
     * @return List<CourseUnitResult>
     *
     *     todo ver esta para fazer um load courseunits de um curso dado o ano e o semestre
     */

    public List<CourseUnitResult> loadCourseUnits(long courseId, 1.5.0/docs/api/java/lang/String.html">String semestre, 1.5.0/docs/api/java/lang/String.html">String year)
    {
        Criteria c = createCriteria();

       c.setProjection(Projections.projectionList()
                .add(Projections.groupProperty("id"))
                .add(Projections.countDistinct("student.id"))
                .add(Projections.countDistinct("teacher.id"))
                .add(Projections.countDistinct("turma.id")));
        c.createAlias("students","student");
        c.createAlias("teachers","teacher");
        c.createAlias("turmas","turma");
        c.createAlias("turma.students","ts");//obrigar a entrar apenas turmas com alunos
        if(courseId > 0)
            c.add(eq("course.id", courseId));
        if(semestre != null && semestre.trim().length() > 0)
            c.add(eq("semestre", semestre));
        if(year != null  && year.trim().length() > 0)
            c.add(eq("importYear", year));
        List<CourseUnitResult> results = new ArrayList<CourseUnitResult>();
        List<Object[]> result = c.list();
        for(5+0%2Fdocs%2Fapi+Object">Object[] r:result)
        {
            CourseUnitResult cur = new CourseUnitResult();
            cur.id = (1.5.0/docs/api/java/lang/Long.html">Long) r[0];
            cur.students = (1.5.0/docs/api/java/lang/Integer.html">Integer) r[1];
            cur.teachers = (1.5.0/docs/api/java/lang/Integer.html">Integer) r[2];
            cur.turmas = (1.5.0/docs/api/java/lang/Integer.html">Integer) r[3];
            results.add(cur);
        }
        return results;
    }


    public int countCourseUnits(1.5.0/docs/api/java/lang/String.html">String query, SearchTypeEnum searchType)
    {
        Criterion c = DaoUtils.createSearchQuery(query, searchType, "objectives", "name","code");
        return createCriteria().add(c).list().size();
    }

    public List<CourseUnit> search(1.5.0/docs/api/java/lang/String.html">String query, SearchTypeEnum searchTypeEnum, int maxUnits, int page)
    {
        Criterion c = DaoUtils.createSearchQuery(query, searchTypeEnum, "objectives", "name","code");
        Criteria criteria = createCriteria();
        criteria.add(c)
                .addOrder(Order.asc("name"))
                .setMaxResults(maxUnits)
                .setFirstResult(page * maxUnits);
        return criteria.list();
    }

    public int countCourseUnitsActualYear(1.5.0/docs/api/java/lang/String.html">String query, SearchTypeEnum searchType)
    {
        Criterion c = DaoUtils.createSearchQuery(query, searchType, "objectives", "name");
        return createCriteria()
                .add(c)
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .list().size();
    }

    public List<CourseUnit> searchActualYear(1.5.0/docs/api/java/lang/String.html">String query, SearchTypeEnum searchTypeEnum, int maxUnits, int page)
    {
        Criterion c = DaoUtils.createSearchQuery(query, searchTypeEnum, "objectives", "name");
        Criteria criteria = createCriteria();
        criteria.add(c)
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .addOrder(Order.asc("name"))
                .setMaxResults(maxUnits)
                .setFirstResult(page * maxUnits);
        return criteria.list();
    }

    public List<CourseUnit> loadMissingObjectives(long teacherId)
    {
        //todo falta a projeccao do teacher id
        return createCriteria()
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add((or(isNull("objectives"), eq("objectives", ""))))
                .createAlias("teachers", "th")
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add(eq("th.id", teacherId))
                .list();
    }

    public List<CourseUnit> loadMissingPrograms(long teacherId)
    {
        //todo falta a projeccao do teacher id
        return createCriteria()
                .createAlias("course","c")
                .add(eq("c.status", true))
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add((or(isNull("programStreamId"), eq("programStreamId", ""))))
                .createAlias("teachers", "th")
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add(eq("th.id", teacherId))
                .list();
    }

    public List<CourseUnit> loadMissingObjectivesOrPrograms(long teacherId)
    {
        //todo falta a projeccao do teacher id
        Criteria c = createCriteria()
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add(or(or(isNull("objectives"), eq("objectives", "")), or(isNull("programStreamId"), eq("programStreamId", ""))));

        DatesUtils.SemestreModerate semestreModerate = DatesUtils.getSemestreModerate();
        if (semestreModerate == DatesUtils.SemestreModerate.S1)
            c.add(eq("semestre", "S1"));
        else if (semestreModerate == DatesUtils.SemestreModerate.S2)
            c.add(eq("semestre", "S2"));
        else
            c.add(or(eq("semestre", "S1"), eq("semestre", "S2")));

        return c.createAlias("teachers", "th")
                .add(eq("th.id", teacherId))
                .list();
    }


    public List<CourseUnit> loadMissingObjectivesGivenCourse(long courseId)
    {
        return createCriteria()
                .createAlias("course", "c")
                .add(eq("c.id", courseId))
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add((or(isNull("objectives"), eq("objectives", ""))))
                .list();
    }

    public List<CourseUnit> loadMissingProgramOptimizedComissionsAndSecreariat(User u)
    {
        Criteria crit = createCriteria()
                .createAlias("course", "c")
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add((or(isNull("programStreamId"), eq("programStreamId", ""))));

        crit = DaoFactory.getCourseDaoImpl().getCriteriaForComissionsAndCoordinationsOr(u,"c",crit);
        if(crit == null)
            return new ArrayList<CourseUnit>();
        else
            return crit.list();
    }

    public List<CourseUnit> loadMissingProgramGivenCourse(long courseId)
    {
        return createCriteria()
                .createAlias("course", "c")
                .add(eq("c.id", courseId))
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add((or(isNull("programStreamId"), eq("programStreamId", ""))))
                .list();
    }

    public List<CourseUnit> loadMissingProgramValidateGivenCourse(long courseId)
    {
        return createCriteria()
                .createAlias("course", "c")
                .add(eq("c.id", courseId))
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                //.add(eq("semestre", DatesUtils.getSemestre()))
                .add((and(isNotNull("programStreamId"), not(eq("programStreamId", "")))))
                .add((eq("validProgram", false)))
                .list();
    }

    public List<CourseUnit> loadMissingProgramValidateOptimizedComissionsAndSecreariat(User u)
    {
        Criteria crit = createCriteria()
                .createAlias("course", "c")
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                //.add(eq("semestre", DatesUtils.getSemestre()))
                .add((and(isNotNull("programStreamId"), not(eq("programStreamId", "")))))
                .add((eq("validProgram", false)));
        crit = DaoFactory.getCourseDaoImpl().getCriteriaForComissionsAndCoordinationsOr(u,"c",crit);
        if(crit == null)
            return new ArrayList<CourseUnit>();
        else
            return crit.list();
    }



    public List<CourseUnit> loadMissingObjectivesOrProgramGivenCourse(long courseId)
    {
        return createCriteria()
                .createAlias("course", "c")
                .add(eq("c.id", courseId))
                .add(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear()))
                .add(eq("semestre", DatesUtils.getSemestre()))
                .add((or(or(isNull("objectives"), eq("objectives", "")), or(isNull("programStreamId"), eq("programStreamId", "")))))
                .list();
    }

    public int countMissingProgramGivenCourse(long courseId)
    {
        return loadMissingProgramGivenCourse(courseId).size();
    }

    public int countMissingProgramValidateCourse(long courseId)
    {
        return loadMissingProgramValidateGivenCourse(courseId).size();
    }


    public List<String> getTeachersEmails(long unit) {
        1.5.0/docs/api/javax/management/Query.html">Query q = createQuery("select e.email from "
                + Teacher.class.getName() + " e join e.teachedUnits as unit "
                + " where "
                + " unit.id = ? "

        );
        q.setLong(0,unit);
        return q.list();
    }

    public static class CourseMissingValidationProgram
    {
        public Course course;
        public List<CourseUnit> courseUnits;
    }




    public List<CourseMissingValidationProgram> loadMissingProgramValidateOptimized(UserSession userSession)
    {
        List<CourseMissingValidationProgram> result = new ArrayList<CourseMissingValidationProgram>();

        //Em vez de FindAll faco a listagem total de cadeiras e é la dentro que restringe ou a todas
        //os cursos caso seja da secretaria ou aos cursos de que faz parte da comissao
        //Obtenho todas as cadeiras de todos os cursos
        //Organizo-as por curso
        //devolvo a lista final
        HashMap<Course,CourseMissingValidationProgram> mapaUnidadesCurso = new HashMap<Course, CourseMissingValidationProgram>();

        List<CourseUnit> courseUnits = loadMissingProgramValidateOptimizedComissionsAndSecreariat(userSession.getUser());
        for(CourseUnit cu : courseUnits)
        {
            if(mapaUnidadesCurso.get(cu.getCourse()) == null)
            {
                CourseMissingValidationProgram c = new CourseMissingValidationProgram();
                c.course = DaoFactory.getCourseDaoImpl().narrow(cu.getCourse());
                c.courseUnits = new ArrayList<CourseUnit>();
                c.courseUnits.add(cu);
                result.add(c);
                mapaUnidadesCurso.put(c.course,c);
            }
            else
            {
                CourseMissingValidationProgram c = mapaUnidadesCurso.get(cu.getCourse());
                c.courseUnits.add(cu);
            }
        }
        return result;
    }


    public List<CourseMissingValidationProgram> loadMissingProgramsOptimized(UserSession userSession)
    {
        List<CourseMissingValidationProgram> result = new ArrayList<CourseMissingValidationProgram>();

        //Em vez de FindAll faco a listagem total de cadeiras e é la dentro que restringe ou a todas
        //os cursos caso seja da secretaria ou aos cursos de que faz parte da comissao
        //Obtenho todas as cadeiras de todos os cursos
        //Organizo-as por curso
        //devolvo a lista final
        HashMap<Course,CourseMissingValidationProgram> mapaUnidadesCurso = new HashMap<Course, CourseMissingValidationProgram>();

        List<CourseUnit> courseUnits = loadMissingProgramOptimizedComissionsAndSecreariat(userSession.getUser());
        for(CourseUnit cu : courseUnits)
        {
            if(mapaUnidadesCurso.get(cu.getCourse()) == null)
            {
                CourseMissingValidationProgram c = new CourseMissingValidationProgram();
                c.course = DaoFactory.getCourseDaoImpl().narrow(cu.getCourse());
                c.courseUnits = new ArrayList<CourseUnit>();
                c.courseUnits.add(cu);
                result.add(c);
                mapaUnidadesCurso.put(c.course,c);
            }
            else
            {
                CourseMissingValidationProgram c = mapaUnidadesCurso.get(cu.getCourse());
                c.courseUnits.add(cu);
            }
        }
        return result;
    }

    public static class CourseMissingValidationEvaluation
    {
        public Course course;
        public List<CourseUnit> courseUnits;
    }


    public List<CourseMissingValidationEvaluation> loadMissingEvaluationOptimized(UserSession userSession)
    {
        List<CourseMissingValidationEvaluation> result = new ArrayList<CourseMissingValidationEvaluation>();

        //Em vez de FindAll faco a listagem total de cadeiras e é la dentro que restringe ou a todas
        //os cursos caso seja da secretaria ou aos cursos de que faz parte da comissao
        //Obtenho todas as cadeiras de todos os cursos
        //Organizo-as por curso
        //devolvo a lista final
        HashMap<Course,CourseMissingValidationEvaluation> mapaUnidadesCurso = new HashMap<Course, CourseMissingValidationEvaluation>();

        List<CourseUnit> courseUnits = loadMissingEvaluationOptimizedComissionsAndSecreariat(userSession.getUser());
        for(CourseUnit cu : courseUnits)
        {
            if(mapaUnidadesCurso.get(cu.getCourse()) == null)
            {
                CourseMissingValidationEvaluation c = new CourseMissingValidationEvaluation();
                c.course = DaoFactory.getCourseDaoImpl().narrow(cu.getCourse());
                c.courseUnits = new ArrayList<CourseUnit>();
                c.courseUnits.add(cu);
                result.add(c);
                mapaUnidadesCurso.put(c.course,c);
            }
            else
            {
                CourseMissingValidationEvaluation c = mapaUnidadesCurso.get(cu.getCourse());
                c.courseUnits.add(cu);
            }
        }
        return result;
    }

    public List<CourseMissingValidationEvaluation> loadMissingEvaluationValidateOptimized(UserSession userSession)
    {
        List<CourseMissingValidationEvaluation> result = new ArrayList<CourseMissingValidationEvaluation>();

        //Em vez de FindAll faco a listagem total de cadeiras e é la dentro que restringe ou a todas
        //os cursos caso seja da secretaria ou aos cursos de que faz parte da comissao
        //Obtenho todas as cadeiras de todos os cursos
        //Organizo-as por curso
        //devolvo a lista final
        HashMap<Course,CourseMissingValidationEvaluation> mapaUnidadesCurso = new HashMap<Course, CourseMissingValidationEvaluation>();

        List<CourseUnit> courseUnits = loadMissingEvaluationValidateOptimizedComissionsAndSecreariat(userSession.getUser());
        for(CourseUnit cu : courseUnits)
        {
            if(mapaUnidadesCurso.get(cu.getCourse()) == null)
            {
                CourseMissingValidationEvaluation c = new CourseMissingValidationEvaluation();
                c.course = DaoFactory.getCourseDaoImpl().narrow(cu.getCourse());
                c.courseUnits = new ArrayList<CourseUnit>();
                c.courseUnits.add(cu);
                result.add(c);
                mapaUnidadesCurso.put(c.course,c);
            }
            else
            {
                CourseMissingValidationEvaluation c = mapaUnidadesCurso.get(cu.getCourse());
                c.courseUnits.add(cu);
            }
        }
        return result;
    }




    /**
     * @param u utilizador com vista para cursos
     *          Se for secretaria considera todos os cursos
     *          Se nao for considera apenas comissoes de curso do professor se for TeacherImpl
     * @return
     */


    public List<CourseUnit> loadMissingEvaluationValidateOptimizedComissionsAndSecreariat(User u)
    {

        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);
        if(degreesCrit == null)
            return new ArrayList<CourseUnit>();

        Criteria c = createCriteria()
                .createAlias("course", "c")
                .createAlias("courseUnitEvaluation", "ce")
                .add(eq("importYear", activeYear))
                .add(degreesCrit)
                .add((eq("ce.closed", false)))
                .add((eq("ce.teacherComplete", true)));

        //NOVO para restringir os cursos de que é coordenador ou todos se for da secretaria de cursos
        c = DaoFactory.getCourseDaoImpl().getCriteriaForComissionsAndCoordinationsOr(u,"c",c);
        if(c == null)
            return new ArrayList<CourseUnit>();
        else
            return c.list();
    }

    /*
    * Neste caso apenas se validam as do ano anterior*/


    public List<CourseUnit> loadMissingEvaluationValidateGivenCourse(long courseId)
    {
        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);
        if(degreesCrit == null)
            return new ArrayList<CourseUnit>();

        return createCriteria()
                .createAlias("course", "c")
                .createAlias("courseUnitEvaluation", "ce")
                .add(eq("c.id", courseId))
                .add(eq("importYear", activeYear))
                .add(degreesCrit)
                .add((eq("ce.closed", false)))
                .add((eq("ce.teacherComplete", true)))
                .list();
    }

    /**
     *
     * @return devolve todos os ids de unidades que verifiquem a condição de avaliação
     * do periodo actual e tenham o programa fechado pela comissão
     */


    public List<Long> loadClosedCourseUnitsEvaluations()
    {
        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);
        if(degreesCrit == null)
            return new ArrayList<Long>();

        return createCriteria()
                .setProjection(Projections.property("id"))
                .createAlias("course", "c")
                .createAlias("courseUnitEvaluation", "ce")
                .add(eq("importYear", activeYear))
                .add(degreesCrit)
                .add((eq("ce.closed", true)))
                .list();
    }

    /**
     * Devolve um criteio OR para todos os cursos de grau pertencente à lista de graus
     * ou pertencete à lista de cursoIds

     * @return
     */

    private Criterion getCourseUnitActiveDegreeCourseIdsCriterion(1.5.0/docs/api/java/lang/String.html">String activeYear)
    {
        List<String> activeDegrees = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveDegrees();
        List<Long> activeCourseIds = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveCourseIds();
        boolean activeDegreesOff = activeDegrees == null || activeDegrees.size() == 0;
        boolean activeCourseIdsOff = activeCourseIds == null || activeCourseIds.size() == 0;
        if(activeYear == null || (activeDegreesOff && activeCourseIdsOff))
            return null;

        Criterion crit = null;

        if(activeDegrees != null)
            for(1.5.0/docs/api/java/lang/String.html">String degree: activeDegrees)
            {
                if(crit == null)
                    crit = eq("c.degree",degree);
                else
                    crit = or(crit,eq("c.degree",degree));
            }
        if(activeCourseIds != null)
            for(1.5.0/docs/api/java/lang/Long.html">Long courseId: activeCourseIds)
            {
                if(crit == null)
                    crit = eq("c.id",courseId);
                else
                    crit = or(crit,eq("c.id",courseId));
            }

        return crit;
    }


    public List<CourseUnit> loadTeacherUnitsMissingEvaluation(UserSession userSession)
    {
        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);
        if(degreesCrit == null)
            return new ArrayList<CourseUnit>();


        List<CourseUnit> nulls =
                createCriteria()
                        .createAlias("course", "c")
                        .createAlias("teachers", "t")
                        .add(eq("importYear", activeYear))
                                //.add(not(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear())))
                                //.add(ge("importYear", "201415" ))
                                //.add(isNull("courseUnitEvaluation"))
                                //todo novo testar
                        .add(eq("t.id", userSession.getUser().getId()))
                        .add(degreesCrit)
                        .add(isNull("courseUnitEvaluation"))
                        .list();

        List<CourseUnit> teacherCompleteFalse =
                createCriteria()
                        .createAlias("course", "c")
                        .createAlias("courseUnitEvaluation", "ce")
                        .createAlias("teachers", "t")
                        .add(eq("t.id", userSession.getUser().getId()))
                        .add(eq("importYear", activeYear))
                                //.add(not(eq("importYear", DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear())))
                                //.add(ge("importYear", "201415" ))
                                //.add(isNull("courseUnitEvaluation"))
                                //todo novo testar
                        .add(degreesCrit)
                        .add(eq("ce.teacherComplete", false))
                        .list();
        teacherCompleteFalse.addAll(nulls);
        return teacherCompleteFalse;
    }



    public List<CourseUnit> loadMissingEvaluationOptimizedComissionsAndSecreariat(User u)
    {

        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();

        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);
        if(degreesCrit == null)
            return new ArrayList<CourseUnit>();


        Criteria nullsCrit = createCriteria()
                .createAlias("course", "c")
                .add(eq("importYear", activeYear))
                .add(degreesCrit)
                .add(isNull("courseUnitEvaluation"));

        Criteria teachrCompleteCrit = createCriteria()
                .createAlias("course", "c")
                .createAlias("courseUnitEvaluation", "ce")
                .add(degreesCrit)
                .add(eq("importYear", activeYear))
                .add(eq("ce.teacherComplete", false));


        //NOVO para restringir os cursos de que é coordenador ou todos se for da secretaria de cursos
        nullsCrit = DaoFactory.getCourseDaoImpl().getCriteriaForComissionsAndCoordinationsOr(u,"c",nullsCrit);
        if(nullsCrit == null)
            return new ArrayList<CourseUnit>();
        teachrCompleteCrit = DaoFactory.getCourseDaoImpl().getCriteriaForComissionsAndCoordinationsOr(u,"c",teachrCompleteCrit);
        if(teachrCompleteCrit == null)
            return new ArrayList<CourseUnit>();
        List<CourseUnit> nulls = nullsCrit.list();
        List<CourseUnit> teacherCompleteFalse = teachrCompleteCrit.list();
        teacherCompleteFalse.addAll(nulls);
        return teacherCompleteFalse;
    }

    public List<CourseUnit> loadMissingEvaluation(long courseId)
    {

        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();
        Criterion degreesCrit = getCourseUnitActiveDegreeCourseIdsCriterion(activeYear);

        if(degreesCrit == null)
            return new ArrayList<CourseUnit>();

        List<CourseUnit> nulls =
           createCriteria()
                .createAlias("course", "c")
                .add(eq("c.id", courseId))
                .add(eq("importYear", activeYear))
                .add(degreesCrit)
                .add(isNull("courseUnitEvaluation"))
                .list();

        List<CourseUnit> teacherCompleteFalse =
                createCriteria()
                        .createAlias("course", "c")
                        .createAlias("courseUnitEvaluation", "ce")
                        .add(eq("c.id", courseId))
                        .add(degreesCrit)
                        .add(eq("importYear", activeYear))
                        .add(eq("ce.teacherComplete", false))
                        .list();
        teacherCompleteFalse.addAll(nulls);
        return teacherCompleteFalse;
    }

    public CourseUnit loadByEvaluationStreamId(1.5.0/docs/api/java/lang/String.html">String identifier)
    {
        return
                (CourseUnit)
                        createCriteria()
                                .add(eq("evaluationStreamId",identifier))
                                .uniqueResult();
    }
}