Subversion Repositories bacoAlunos

Rev

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

package pt.estgp.estgweb.services.questionarios.pedagogico.reportprocessors;

import jomm.utils.PdfUtils;
import org.apache.fop.apps.FOPException;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.domain.Course;
import pt.estgp.estgweb.domain.QuestionarioReportCursoFile;
import pt.estgp.estgweb.domain.QuestionarioReportCursoFileImpl;
import pt.estgp.estgweb.domain.QuestionarioReportFileGroupCursosAnoImpl;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.filters.chains.ResourceAccessControlEnum;
import pt.estgp.estgweb.services.data.RepositoryService;
import pt.estgp.estgweb.services.jobs.ServiceJob;
import pt.estgp.estgweb.services.logresults.ILogMessages;
import pt.estgp.estgweb.services.logresults.LogMessageTypeEnum;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessage;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessages;
import pt.estgp.estgweb.services.questionarios.pedagogico.reportprocessors.queries.*;
import pt.estgp.estgweb.services.questionarios.pedagogico.reportprocessors.reportdomains.CursoPublicReport;
import pt.estgp.estgweb.services.questionarios.pedagogico.reportprocessors.reportdomains.EntityEvaluated;
import pt.estgp.estgweb.services.questionarios.pedagogico.reportprocessors.utils.*;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.utils.DatesUtils;
import pt.estgp.estgweb.utils.Dom4jUtil;

import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

/**
 * Created by jorgemachado on 16/12/16.
 */

public class CursoPublicReportGenerator extends ReportAlunosGenerator
{
    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(DocenteReportGenerator.class);



    public static void main(1.5.0/docs/api/java/lang/String.html">String[] args) throws 1.5.0/docs/api/java/io/IOException.html">IOException, DocumentException, 1.5.0/docs/api/javax/xml/transform/TransformerException.html">TransformerException, FOPException
    {

        //String teacherCode = "44451";
        //String teacherCode = "20122";
        1.5.0/docs/api/java/lang/String.html">String courseCode = "9119";
        //String courseCode = "9104";
        1.5.0/docs/api/java/lang/String.html">String anoLectivo = "201516";
        //String[] periodos = new String[]{"S2","T3","T4","A"};
        1.5.0/docs/api/java/lang/String.html">String[] periodos = new 1.5.0/docs/api/java/lang/String.html">String[]{"S1"};
        1.5.0/docs/api/java/lang/String.html">String[] degrees = new 1.5.0/docs/api/java/lang/String.html">String[]{"L","M","T","E"};
        new CursoPublicReportGenerator(anoLectivo,periodos,degrees,courseCode).processCourse(courseCode);

    }

    public CursoPublicReportGenerator() {
        super(null, null, null);
    }

    public CursoPublicReportGenerator(1.5.0/docs/api/java/lang/String.html">String anoLectivo, 1.5.0/docs/api/java/lang/String.html">String[] periodos, 1.5.0/docs/api/java/lang/String.html">String[] degrees, 1.5.0/docs/api/java/lang/String.html">String courseCode) {
        super(anoLectivo, periodos, degrees);
    }

    public CursoPublicReport processCourse(1.5.0/docs/api/java/lang/String.html">String courseCode) throws 1.5.0/docs/api/java/io/IOException.html">IOException, DocumentException, 1.5.0/docs/api/javax/xml/transform/TransformerException.html">TransformerException, FOPException
    {
        CursoPublicReport cursoReport = getCoursePublicReport(courseCode);
        if(cursoReport == null)
        {
            1.5.0/docs/api/java/lang/String.html">String msg = " Curso " + courseCode + " nao tem respostas nestas condições ";
            logger.warn(msg);
            serviceLogWarn(msg);
            1.5.0/docs/api/java/lang/System.html">System.out.println();
            return cursoReport;
        }

        ChartBuilderUtil.createChartTiposAlunos(cursoReport, "tiposAlunosTmp");
        ChartBuilderUtil.createChartTaxaRespostas(cursoReport, "taxaRespostasTmp");
        ChartBuilderUtil.createChartTaxaParticipacao(cursoReport, "taxaParticipacaoTmp");
        ChartBuilderUtil.createChartUnidadesContribuicao(cursoReport,"unidadesContribuicao");


        1.5.0/docs/api/java/lang/String.html">String path = generatePdfReport(cursoReport);
        cursoReport.setPathGeneratedPdfTemp(path);
        return cursoReport;

    }

    private 1.5.0/docs/api/java/lang/String.html">String generatePdfReport(CursoPublicReport cursoReport) throws DocumentException, 1.5.0/docs/api/javax/xml/transform/TransformerException.html">TransformerException, 1.5.0/docs/api/java/io/IOException.html">IOException, FOPException {
        1.5.0/docs/api/java/lang/String.html">String startPath = Globals.TMP_DIR + 1.5.0/docs/api/java/io/File.html">File.separator  + "reportCurso" +  cursoReport.getCursoStats().getCodigoCurso();
        1.5.0/docs/api/java/lang/String.html">String path = startPath + ".pdf";

        1.5.0/docs/api/java/io/FileOutputStream.html">FileOutputStream out = new 1.5.0/docs/api/java/io/FileOutputStream.html">FileOutputStream(path);
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("site", Globals.SITE_URL);
        params.put("updateDate", pt.estgp.estgweb.web.utils.DatesUtils.getStringFromDate(new 5+0%2Fdocs%2Fapi+Date">Date() ));


        org.w3c.dom.5+0%2Fdocs%2Fapi+Document">Document dom2 = cursoReport.serialize();
        Dom4jUtil.writeSout(dom2);
        Dom4jUtil.write(dom2,new java.io.1.5.0/docs/api/java/io/File.html">File(startPath + ".xml"));

        PdfUtils.setAuthority("Relatório de Avaliação Pedagógica - Relatório Público de Curso - " +
                cursoReport.getCursoStats().getNomeCurso() + " (" + cursoReport.getCursoStats().getCodigoCurso() + " ) " +
                "- Ano letivo " + cursoReport.getAnoLectivo() + " - Periodos " + cursoReport.getSemestres().toString() + "" +
                " Tipos de Curso - " + cursoReport.getDegrees().toString(),
                cursoReport.getCursoStats().getNomeCurso(), "Avaliação Pedagógica Docentes, Inqueritos aos Alunos");
        PdfUtils.createPdfFromXml(new 1.5.0/docs/api/javax/xml/transform/dom/DOMSource.html">DOMSource(dom2), "pt/estgp/estgweb/services/questionarios/pedagogico/reportprocessors/xsl/cursoPublicReport.fo.xsl", out, params);
        out.flush();
        out.close();
        return path;
    }

    private CursoPublicReport getCoursePublicReport(1.5.0/docs/api/java/lang/String.html">String courseCode) throws 1.5.0/docs/api/java/io/IOException.html">IOException {

        //AbstractDao.getCurrentSession().beginTransaction();

        Course c = DaoFactory.getCourseDaoImpl().findCourseByCode(courseCode);

        CursoPublicReport cursoReport = new CursoPublicReport();

        //dados relativos ao questionario
        cursoReport.setAnoLectivo(DatesUtils.getImportYearFormatted(anoLectivo));
        cursoReport.setSemestres(ReportUtils.getFormatedSemestres(periodos));
        cursoReport.setDegrees(ReportUtils.getFormatedDegrees(degrees));


        //dados relativos ao curso
        cursoReport.getCursoStats().setCodigoCurso(courseCode);
        cursoReport.getCursoStats().setNomeCurso(c.getName());
        cursoReport.getCursoStats().setCodigoCurso(c.getCode());
        cursoReport.getCursoStats().setNomeInstituicao(ConfigProperties.getProperty("institution.code." + c.getInstitutionalCode()));
        cursoReport.getCursoStats().setCodigoInstituicao(c.getInstitutionalCode());
        cursoReport.getCursoStats().setCodigoNacionalInstituicao(ConfigProperties.getProperty("institution.national.code." + c.getInstitutionalCode()));
        cursoReport.getCursoStats().setAbreviaturaInstituicao(ConfigProperties.getProperty("institution.code.prefix." + c.getInstitutionalCode()));
        cursoReport.setAnoLectivo(anoLectivo);





        //Caso nao haja respostas
        //este metodo preenche todas as questões relativas a respostas e generos m/f e idades, mas
        // devolve total de respostas para ser usada aqui como verificacao
        int respostas = AlunosQueryDao.countAlunosQueResponderamAoCurso(courseCode, anoLectivo, cursoReport, periodos, degrees);
        QuestionariosQueryDao.countQuestionariosRespostasAoCurso(courseCode, anoLectivo, cursoReport, periodos, degrees);
        //todo testar curso sem respostas
        if(respostas > 0)
        {
            AlunosQueryDao.countTiposAlunosComRespostasAoCurso(courseCode, anoLectivo, cursoReport, periodos, degrees);
            AlunosQueryDao.countIdadesAlunosComRespostasAoCurso(courseCode, anoLectivo, cursoReport, periodos, degrees);

            //TABELAS
            QuestionariosQueryDao.createDataTableIdades(cursoReport, "Alunos");
            QuestionariosQueryDao.createDataTableLocalidadesAoCurso(cursoReport, courseCode, anoLectivo, periodos, degrees, "Alunos");
        }

        UnidadesQueryDao.createTableTaxaRespostaUnidadeAoCurso(cursoReport, courseCode, anoLectivo, periodos, degrees);

        if(respostas > 0)
        {
        //EVOLUCAO DAS RESPOSTAS
        List<Object[]> semanaContagemCurso = QuestionariosQueryDao.obtainEvolucaoRespostas(new 1.5.0/docs/api/java/lang/String.html">String[]{courseCode}, EntityEvaluated.CURSO,anoLectivo,periodos,degrees);
        List<Object[]> semanaContagemEscola = QuestionariosQueryDao.obtainEvolucaoRespostas(new 1.5.0/docs/api/java/lang/String.html">String[]{cursoReport.getCursoStats().getCodigoInstituicao()},EntityEvaluated.ESCOLA,anoLectivo,periodos,degrees);
        1.5.0/docs/api/java/lang/String.html">String distRespostas = ChartBuilderUtil.createTimeSeriesCursoRepostas("distribuicaoRespostasSemanal",cursoReport.getCursoStats().getNomeCurso(),cursoReport.getCursoStats().getAbreviaturaInstituicao(),semanaContagemCurso,semanaContagemEscola);
        cursoReport.setPathDistribuicaoRespostasSemanalChart(distRespostas);

        DataTable tableEvolucaoRespostas = criarEvolucaoTaxasRespostas(semanaContagemCurso,cursoReport.getQuestionariosReqTotal());
        cursoReport.setTabelaEvolucaoRespostas(tableEvolucaoRespostas);


        //Os cursos na Escola são todos os cursos, na pratica nao serve para nada porque
        //A media de todos os cursos na escola é a media da escola considerando a restricao de graus e periodos
        //media nas Escolas por pergunta e media nos Cursos por pergunta é igual
        //A media da entidade neste caso é a do curso
        List<String> codigosTodosCursosDaEscola = QueryDaoUtils.getCodigosCursosEscola(cursoReport.getCursoStats().getCodigoInstituicao(),anoLectivo, periodos, degrees);

        //List<String> codigosEscola = QueryDaoUtils.getCodigosEscolaDocente(teacherCode, anoLectivo, periodos, degrees);
        List<String> codigosEscola = new ArrayList<String>();
        codigosEscola.add(cursoReport.getCursoStats().getCodigoInstituicao());


        cursoReport.getCursoStats().setDocentesDoCurso((int) QueryDaoUtils.countDocentesNosCursos(courseCode, anoLectivo, periodos, degrees));
        cursoReport.getCursoStats().setDocentesDaEscola((int) QueryDaoUtils.countDocentesNasEscolas(cursoReport.getCursoStats().getCodigoInstituicao(), anoLectivo, periodos, degrees));

        // @todoRefactor
        // O DocenteReport tem as unidades na escola e as unidades no curso
        // O CursoReport nao tem, estao antes no CursoStats
        // Uma vez que sao usados em todos os reports de Alunos poderiam ser colocados no QuestionarioAlunos não é problematico
        // vai buscar às cadeiras temos de fazer override do metodo e puxa-lo para o QuestionarioAlunos
        //ou nao porque o UnidadesDaEscola foi introduzido dentro do Curso não se puxou para o QuestionarioAlunos
        //o xsl vai ter de usar este caso o use
        cursoReport.getCursoStats().setUnidadesDoCurso((int) QueryDaoUtils.countUnidadesNosCursos(courseCode, anoLectivo, periodos, degrees));
        cursoReport.getCursoStats().setUnidadesDaEscola((int) QueryDaoUtils.countUnidadesNasEscolas(cursoReport.getCursoStats().getCodigoInstituicao(), anoLectivo, periodos, degrees));


        ReportAlunosGenerator.criarGraficosRespostasAgregadas(new 1.5.0/docs/api/java/lang/String.html">String[]{courseCode},
                EntityEvaluated.CURSO,
                anoLectivo,
                cursoReport,
                codigosTodosCursosDaEscola,
                codigosEscola,
                0,
                cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade().getRespostasAgregadasChartTable(),
                cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade(),
                PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS, null,
                periodos, degrees, true);

        ReportAlunosGenerator.criarGraficosRespostasAgregadas(new 1.5.0/docs/api/java/lang/String.html">String[]{courseCode},
                EntityEvaluated.CURSO,
                anoLectivo,
                cursoReport,
                codigosTodosCursosDaEscola,
                codigosEscola,
                4000,
                cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade().getRespostasAgregadasChartTable2Secs(),
                cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade(),
                PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS, null,
                periodos, degrees, false);


        ReportAlunosGenerator.criarGraficosRespostasAgregadas(new 1.5.0/docs/api/java/lang/String.html">String[]{courseCode},
                EntityEvaluated.CURSO,
                anoLectivo,
                cursoReport,
                codigosTodosCursosDaEscola,
                codigosEscola,
                0,
                cursoReport.getCursoStats().getRespostasAgregadasGrupoSalas().getRespostasAgregadasChartTable(),
                cursoReport.getCursoStats().getRespostasAgregadasGrupoSalas(),
                PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS, null,
                periodos, degrees, true);

        ReportAlunosGenerator.criarGraficosRespostasAgregadas(new 1.5.0/docs/api/java/lang/String.html">String[]{courseCode},
                EntityEvaluated.CURSO,
                anoLectivo,
                cursoReport,
                codigosTodosCursosDaEscola,
                codigosEscola,
                9000,
                cursoReport.getCursoStats().getRespostasAgregadasGrupoSalas().getRespostasAgregadasChartTable2Secs(),
                cursoReport.getCursoStats().getRespostasAgregadasGrupoSalas(),
                PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS, null,
                periodos, degrees, false);


            UnidadesQueryDao.criarTabelasCadeirasCurso(courseCode,
                    anoLectivo,
                    cursoReport,
                    0, periodos, degrees,cursoReport.getCursoStats().getUnidadesStats());


            ChartWithDataTable analiseConjuntaChartWithTable = criarAnaliseConjuntaDeUnidades(cursoReport.getCursoStats().getUnidadesStats());
            cursoReport.setAnaliseConjuntaChartWithTable(analiseConjuntaChartWithTable);

            1.5.0/docs/api/java/lang/String.html">String pathOrdenadaMediaUnidades = criarAnaliseConjuntaDeUnidadesOrdenadaMediaUnidades(cursoReport.getCursoStats().getUnidadesStats());
            cursoReport.setAnaliseConjuntaChartOrderMediaUnidades(pathOrdenadaMediaUnidades);

            1.5.0/docs/api/java/lang/String.html">String pathOrdenadaMediaSalas = criarAnaliseConjuntaDeUnidadesOrdenadaMediaSalas(cursoReport.getCursoStats().getUnidadesStats());
            cursoReport.setAnaliseConjuntaChartOrderMediaSalas(pathOrdenadaMediaSalas);

            ArrayList<TabelaPerguntaComparativosUnidades> listaTabelasComparativasUnidadesPergunta = criarAnaliseConjuntaDeUnidadesAPergunta(cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade().getPerguntasStats(), cursoReport.getCursoStats().getUnidadesStats(),PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS,null);
            cursoReport.setListaUnidadesComprativasPergunta(listaTabelasComparativasUnidadesPergunta);

            ArrayList<TabelaPerguntaComparativosUnidades> listaTabelasComparativasUnidadesPerguntaSalas = criarAnaliseConjuntaDeUnidadesAPergunta(cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade().getPerguntasStats(), cursoReport.getCursoStats().getUnidadesStats(),PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS,null);
            cursoReport.setListaUnidadesComprativasPerguntaSalas(listaTabelasComparativasUnidadesPerguntaSalas);

            DataTable dataTableTodasAsUndiadesTodasPerguntas = criarTabelaComRespostasATodasAsPerguntas(cursoReport);
            cursoReport.setTodasAsRespostasMediasGruposUnidadesESalas(dataTableTodasAsUndiadesTodasPerguntas);

        }
        //AbstractDao.getCurrentSession().getTransaction().commit();
        return cursoReport;
    }

    private DataTable criarTabelaComRespostasATodasAsPerguntas(CursoPublicReport cursoReport) {
        DataTable tabelaComRespostasATodasAsPerguntasUnidadesSalas = new DataTable();

        DataTable.Row headerHidden = tabelaComRespostasATodasAsPerguntasUnidadesSalas.addRowHeader();
        headerHidden.setInvisible(true);
        DataTable.Row headerGroups = tabelaComRespostasATodasAsPerguntasUnidadesSalas.addRowHeader();
        DataTable.Row header = tabelaComRespostasATodasAsPerguntasUnidadesSalas.addRowHeader();


        headerHidden.addColTextCenter("Inv " + "Unidade Curricular");
        headerGroups.addColInvisible();
        header.addColTextCenter("Unidade Curricular");




        headerHidden.addColTextCenter("Inv " + "Curso");
        headerGroups.addColInvisible();
        header.addColTextCenter("Curso");

        //CABECALHOS UNIDADES
        List<PerguntaStats> perguntaStatsesUnidadeHeader = cursoReport.getCursoStats().getRespostasAgregadasGrupoUnidade().getPerguntasStats();
        if(perguntaStatsesUnidadeHeader.size() > 0)
        {
            DataTable.Row.Col c = headerGroups.addColTextCenter("Unidade Curricular");
            c.setColspan(perguntaStatsesUnidadeHeader.size());
            c.setBackgroundColor(ChartBuilderUtil.getRgbXslColor(ChartBuilderUtil.COLOR_SECTION_GREEN));
            1.5.0/docs/api/java/util/Collections.html">Collections.sort(perguntaStatsesUnidadeHeader,new Comparator<PerguntaStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(PerguntaStats o1, PerguntaStats o2) {
                    return 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o1.getNumero()) - 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o2.getNumero());
                }
            });
            for(PerguntaStats perguntaStats : perguntaStatsesUnidadeHeader)
            {
                headerHidden.addColTextCenter("Inv " + perguntaStats.getNumero());
                header.addColTextCenter(perguntaStats.getNumero()).setBackgroundColor(ChartBuilderUtil.getRgbXslColor(ChartBuilderUtil.COLOR_SECTION_GREEN));
            }
        }

        //CABECALHOS SALAS
        List<PerguntaStats> perguntaStatsesSalasHeader = cursoReport.getCursoStats().getRespostasAgregadasGrupoSalas().getPerguntasStats();
        if(perguntaStatsesSalasHeader.size() > 0)
        {
            DataTable.Row.Col c = headerGroups.addColTextCenter("Instalações");
            c.setColspan(perguntaStatsesSalasHeader.size());
            c.setBackgroundColor(ChartBuilderUtil.getRgbXslColor(ChartBuilderUtil.COLOR_SECTION_ROSE));
            1.5.0/docs/api/java/util/Collections.html">Collections.sort(perguntaStatsesSalasHeader,new Comparator<PerguntaStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(PerguntaStats o1, PerguntaStats o2) {
                    return 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o1.getNumero()) - 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o2.getNumero());
                }
            });
            for(PerguntaStats perguntaStats : perguntaStatsesSalasHeader)
            {
                header.addColTextCenter(perguntaStats.getNumero());
                headerHidden.addColTextCenter("Inv " + perguntaStats.getNumero()).setBackgroundColor(ChartBuilderUtil.getRgbXslColor(ChartBuilderUtil.COLOR_SECTION_ROSE));
            }
        }




        header.addColTextCenter("Insc.");
        headerHidden.addColTextCenter("Inv Insc.");
        headerGroups.addColInvisible();

        headerHidden.addColTextCenter("Inv Resps.");
        header.addColTextCenter("Resps.");
        headerGroups.addColInvisible();

        for(UnidadeStats unidadeStats: cursoReport.getCursoStats().getUnidadesStats())
        {
            DataTable.Row unidadeRow = tabelaComRespostasATodasAsPerguntasUnidadesSalas.addRowNormal();
            unidadeRow.addColTextCenter(unidadeStats.getNomeUnidade());
            unidadeRow.addColTextCenter(unidadeStats.getNomeCurso());


            //COLUNA POR CADA MEDIA DE CADA PERGUNTA NAS UNIDADES
            List<PerguntaStats> perguntaStatsesUnidades = unidadeStats.getUnidadeStatsGrupoUnidade().getPerguntasStats();
            1.5.0/docs/api/java/util/Collections.html">Collections.sort(perguntaStatsesUnidades,new Comparator<PerguntaStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(PerguntaStats o1, PerguntaStats o2) {
                    return 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o1.getNumero()) - 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o2.getNumero());
                }
            });

            for(PerguntaStats guiaHeader: perguntaStatsesUnidadeHeader)
            {
                boolean found = false;
                for(PerguntaStats perguntaStats : perguntaStatsesUnidades)
                {
                    if(perguntaStats.getNumero().equals(guiaHeader.getNumero()))
                    {
                        unidadeRow.addColPercentageDefinedCenter(perguntaStats.getMediaEntidadeEmAvaliacaoPrint(), perguntaStats.getPercentMediaEntidadeEmAvaliacao(), true);
                        found = true;
                        break;
                    }
                }
                if(!found)
                    unidadeRow.addColTextCenter("--");
            }


            //COLUNA POR CADA MEDIA DE CADA PERGUNTA NAS SALAS
            List<PerguntaStats> perguntaStatsSalas = unidadeStats.getUnidadeStatsGrupoSalas().getPerguntasStats();
            1.5.0/docs/api/java/util/Collections.html">Collections.sort(perguntaStatsSalas,new Comparator<PerguntaStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(PerguntaStats o1, PerguntaStats o2) {
                    return 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o1.getNumero()) - 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(o2.getNumero());
                }
            });
            for(PerguntaStats guiaHeader: perguntaStatsesSalasHeader)
            {
                boolean found = false;
                for(PerguntaStats perguntaStats : perguntaStatsSalas)
                {
                    if(perguntaStats.getNumero().equals(guiaHeader.getNumero()))
                    {
                        unidadeRow.addColPercentageDefinedCenter(perguntaStats.getMediaEntidadeEmAvaliacaoPrint(), perguntaStats.getPercentMediaEntidadeEmAvaliacao(), true);
                        found = true;
                        break;
                    }
                }
                if(!found)
                    unidadeRow.addColTextCenter("--");
            }


            unidadeRow.addColTextCenter("" + unidadeStats.getInscritos());
            unidadeRow.addColTextCenter("" + unidadeStats.getRespostas());
        }
        return tabelaComRespostasATodasAsPerguntasUnidadesSalas;
    }

    private ArrayList<TabelaPerguntaComparativosUnidades> criarAnaliseConjuntaDeUnidadesAPergunta(List<PerguntaStats> perguntasAgregadasGrupo, ArrayList<UnidadeStats> unidadesStats, 1.5.0/docs/api/java/lang/String.html">String grupo, 1.5.0/docs/api/java/lang/String.html">String subgrupo)
    {
        Map<String, List<UnidadePergunta>> unidadesPerguntas = new HashMap<String, List<UnidadePergunta>>();
        for(UnidadeStats unidadeStats: unidadesStats)
        {
            for(PerguntaStats prgStatUnidade :unidadeStats.findUnidadeStatsGrupo(grupo,subgrupo).getPerguntasStats())
            {
                List<UnidadePergunta> unidadesPerguntasList = unidadesPerguntas.get(prgStatUnidade.getPergunta());
                if(unidadesPerguntasList == null)
                {
                    unidadesPerguntasList = new ArrayList<UnidadePergunta>();
                    unidadesPerguntas.put(prgStatUnidade.getPergunta(),unidadesPerguntasList);
                }
                unidadesPerguntasList.add(new UnidadePergunta(unidadeStats,prgStatUnidade));
            }
        }
        ArrayList<TabelaPerguntaComparativosUnidades> tabelas = new ArrayList<TabelaPerguntaComparativosUnidades>();


        for(1.5.0/docs/api/java/lang/String.html">String pergunta: unidadesPerguntas.keySet())
        {
            TabelaPerguntaComparativosUnidades tabelaPerguntaComparativosUnidades = new TabelaPerguntaComparativosUnidades();
            tabelas.add(tabelaPerguntaComparativosUnidades);
            tabelaPerguntaComparativosUnidades.setPergunta(pergunta);

            DataTable perguntaUnidadesTable = new DataTable();
            tabelaPerguntaComparativosUnidades.setTabelaComparativaUnidades(perguntaUnidadesTable);
            DataTable.Row header = perguntaUnidadesTable.addRowHeader();
            header.addColTextCenter("Unidade Curricular");
            header.addColTextCenter("Curso");
            header.addColTextCenter("Insc.");
            header.addColTextCenter("Resp.");
            header.addColTextCenter("% Resposta");
            header.addColTextCenter("Média");
            header.addColTextCenter("Desvio");

            List<UnidadePergunta> unidadesPergunta = unidadesPerguntas.get(pergunta);

            //SUPOSTAMENTE VEM SEMPRE PREENCHIDO
            if(unidadesPergunta != null && unidadesPergunta.size() > 0)
                tabelaPerguntaComparativosUnidades.setPerguntaNumero(unidadesPergunta.get(0).getPerguntaStats().getNumero());

            1.5.0/docs/api/java/util/Collections.html">Collections.sort(unidadesPergunta,new Comparator<UnidadePergunta>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(UnidadePergunta o1, UnidadePergunta o2) {
                    double sub = o2.getPerguntaStats().getMediaEntidadeEmAvaliacao() - o1.getPerguntaStats().getMediaEntidadeEmAvaliacao();
                    if(sub < 0.0)
                        return -1;
                    else if (sub > 0.0)
                        return 1;
                    else return 0;
                }
            });
            for(UnidadePergunta unidadePergunta: unidadesPergunta)
            {
                DataTable.Row rowUnidade = perguntaUnidadesTable.addRowNormal();

                rowUnidade.addColLabelCenter(unidadePergunta.getUnidadeStats().getNomeUnidade());
                rowUnidade.addColLabelCenter(unidadePergunta.getUnidadeStats().getNomeCurso());
                rowUnidade.addColTextRight("" + unidadePergunta.getUnidadeStats().getInscritos());
                rowUnidade.addColTextRight("" + unidadePergunta.getUnidadeStats().getRespostas());
                rowUnidade.addColTextRight("" + unidadePergunta.getUnidadeStats().getTaxaRespostaPrint0Slots());
                rowUnidade.addColPercentageDefinedCenter("" + unidadePergunta.getPerguntaStats().getMediaEntidadeEmAvaliacaoPrint(), unidadePergunta.getPerguntaStats().getPercentMediaEntidadeEmAvaliacao(), true);
                rowUnidade.addColTextRight(unidadePergunta.getPerguntaStats().getDesvio());
            }

        }

        return tabelas;
    }

    private ChartWithDataTable criarAnaliseConjuntaDeUnidades(List<UnidadeStats> unidadesStats)
    {
        DataTable tabelaDocenteUnidade = new DataTable();
        try {

            1.5.0/docs/api/java/util/Collections.html">Collections.sort(unidadesStats, new Comparator<UnidadeStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(UnidadeStats o1, UnidadeStats o2) {
                    return o1.getNomeUnidade().compareTo(o2.getNomeUnidade());
                }
            });
            1.5.0/docs/api/java/lang/String.html">String unidadeSalasPath = criarChartETabelaMediaGruposPorUnidade(500,30, unidadesStats,
                    PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS,
                    null,
                    PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS,
                    null,
                    tabelaDocenteUnidade,
                    "unidadeSalas",
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{ChartBuilderUtil.COLOR_SECTION_GREEN_DARK,ChartBuilderUtil.COLOR_SECTION_ROSE_DARK},
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{1.5.0/docs/api/java/awt/Color.html">Color.black,1.5.0/docs/api/java/awt/Color.html">Color.black}
            );

            return
                    new ChartWithDataTable(
                            "Analise Conjunta de Unidades",
                            "Unidade VS Instalações/Equipamentos/Outros Recursos",
                            unidadeSalasPath,
                            tabelaDocenteUnidade);

        } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
            logger.error(e,e);
        }
        return null;

    }

    private 1.5.0/docs/api/java/lang/String.html">String criarAnaliseConjuntaDeUnidadesOrdenadaMediaUnidades(List<UnidadeStats> unidadesStats)
    {
        try {

            1.5.0/docs/api/java/util/Collections.html">Collections.sort(unidadesStats,new Comparator<UnidadeStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(UnidadeStats o1, UnidadeStats o2) {

                    double sub = (o2.getUnidadeStatsGrupoUnidade().getMediasGrupo().getAvaliacaoMedia()
                            -
                            o1.getUnidadeStatsGrupoUnidade().getMediasGrupo().getAvaliacaoMedia());
                    if(sub > 0.0)
                        return 1;
                    else if (sub < 0.0)
                        return -1;
                    return 0;
                }
            });
            1.5.0/docs/api/java/lang/String.html">String unidadeSalasPath = criarChartETabelaMediaGruposPorUnidade(500,30, unidadesStats,
                    PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS,
                    null,
                    PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS,
                    null,
                    null,
                    "unidadeSalasOrderMediaUnidades",
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{ChartBuilderUtil.COLOR_SECTION_GREEN_DARK,ChartBuilderUtil.COLOR_SECTION_ROSE_DARK},
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{1.5.0/docs/api/java/awt/Color.html">Color.black,1.5.0/docs/api/java/awt/Color.html">Color.black}
            );

            return unidadeSalasPath;

        } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
            logger.error(e,e);
        }
        return null;

    }

    private 1.5.0/docs/api/java/lang/String.html">String criarAnaliseConjuntaDeUnidadesOrdenadaMediaSalas(List<UnidadeStats> unidadesStats)
    {
        try {

            1.5.0/docs/api/java/util/Collections.html">Collections.sort(unidadesStats,new Comparator<UnidadeStats>() {
                @1.5.0/docs/api/java/lang/Override.html">Override
                public int compare(UnidadeStats o1, UnidadeStats o2) {

                    double sub = (o2.getUnidadeStatsGrupoSalas().getMediasGrupo().getAvaliacaoMedia()
                            -
                            o1.getUnidadeStatsGrupoSalas().getMediasGrupo().getAvaliacaoMedia());
                    if(sub > 0.0)
                        return 1;
                    else if (sub < 0.0)
                        return -1;
                    return 0;
                }
            });
            1.5.0/docs/api/java/lang/String.html">String unidadeSalasPath = criarChartETabelaMediaGruposPorUnidade(500,30, unidadesStats,
                    PerguntasGrupoQueryDao.GRUPO_UNIDADE_CODE_PERGUNTAS,
                    null,
                    PerguntasGrupoQueryDao.GRUPO_SALAS_CODE_PERGUNTAS,
                    null,
                    null,
                    "unidadeSalasOrderMediaSalas",
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{ChartBuilderUtil.COLOR_SECTION_GREEN_DARK,ChartBuilderUtil.COLOR_SECTION_ROSE_DARK},
                    new 1.5.0/docs/api/java/awt/Color.html">Color[]{1.5.0/docs/api/java/awt/Color.html">Color.black,1.5.0/docs/api/java/awt/Color.html">Color.black}
            );

            return unidadeSalasPath;

        } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
            logger.error(e,e);
        }
        return null;

    }


    /**
     *
     * @param semanaContagemCurso List<[count,Week,Year]>
     */

    private DataTable criarEvolucaoTaxasRespostas(List<Object[]> semanaContagemCurso, int respostasRequisitadas)
    {
        DataTable tableEvolucaoRespostas = new DataTable();

        DataTable.Row header = tableEvolucaoRespostas.addRowHeader();

        header.addColTextCenter("Semana");
        header.addColTextCenter("Respostas obtidas na semana");
        header.addColTextCenter("Respostas Acumuladas");
        header.addColTextCenter("Por Responder");
        header.addColTextCenter("Esperadas");
        header.addColTextCenter("%");

        int acumuladas = 0;

        1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat dateFormat = new 1.5.0/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat( "dd-MMM-yyyy" );

        if(semanaContagemCurso.size() > 0)
        {
            for(5+0%2Fdocs%2Fapi+Object">Object[] semanaObj :  semanaContagemCurso)
            {
                1.5.0/docs/api/java/lang/Long.html">Long count = (1.5.0/docs/api/java/lang/Long.html">Long) semanaObj[0];
                acumuladas += count;
                int faltam = respostasRequisitadas - acumuladas;
                1.5.0/docs/api/java/lang/Integer.html">Integer semana = (1.5.0/docs/api/java/lang/Integer.html">Integer) semanaObj[1];
                1.5.0/docs/api/java/lang/Integer.html">Integer ano = (1.5.0/docs/api/java/lang/Integer.html">Integer) semanaObj[2];
                1.5.0/docs/api/java/lang/String.html">String percentagemPrt = ChartBuilderUtil.getPercentagemPrint0Slots(acumuladas,respostasRequisitadas);
                double percentagem = ChartBuilderUtil.getPercentagem(acumuladas,respostasRequisitadas);

                1.5.0/docs/api/java/util/Calendar.html">Calendar calendar = 1.5.0/docs/api/java/util/Calendar.html">Calendar.getInstance();
                calendar.clear();

                calendar.set(1.5.0/docs/api/java/util/Calendar.html">Calendar.YEAR, ano);
                calendar.set(1.5.0/docs/api/java/util/Calendar.html">Calendar.WEEK_OF_YEAR, semana);
                calendar.set(1.5.0/docs/api/java/util/Calendar.html">Calendar.DAY_OF_WEEK, 7);
                1.5.0/docs/api/java/lang/String.html">String dataFinalDaSemana = dateFormat.format(calendar.getTime());

                DataTable.Row rowSemana = tableEvolucaoRespostas.addRowNormal();
                rowSemana.addColTextCenter(dataFinalDaSemana);
                rowSemana.addColNumberRight(count + "");
                rowSemana.addColNumberRight(acumuladas + "").setBackgroundColor(DataTable.getColorGradientForPercentage(percentagem/100.0));
                rowSemana.addColNumberRight(faltam + "");
                rowSemana.addColNumberRight(""+ respostasRequisitadas);
                rowSemana.addColPercentageProgressCenter(percentagemPrt);
            }
        }
        return tableEvolucaoRespostas;
    }


    protected ILogMessages runJobServiceTask() throws 1.5.0/docs/api/java/lang/Throwable.html">Throwable
    {
        long questionarioReportId = 1.5.0/docs/api/java/lang/Long.html">Long.parseLong(getParametersMap().get(ServiceJob.JOB_questionario_report_id_KEY).getObject());
        DefaultLogMessages logMessages = new DefaultLogMessages();

        int cursosEncontrados = 0;
        int cursosProcessados = 0;
        int cursosFalhados = 0;
        int cursosSemRespostas = 0;
        int cursosSemUnidadesAfetas = 0;
        int cursosComRespostas = 0;

        QuestionarioReportFileGroupCursosAnoImpl reportGroup = (QuestionarioReportFileGroupCursosAnoImpl) DaoFactory.getQuestionarioReportFileGroupCursosAnoDaoImpl().load(questionarioReportId);

        anoLectivo = reportGroup.getImportYear();
        periodos = reportGroup.getPeriodosArray();
        degrees = reportGroup.getDegreesArray();

        1.5.0/docs/api/java/lang/String.html">String msg = "Starting process for Report Cursos (" + questionarioReportId + "): " + reportGroup.getTitle();
        serviceLogInfo(msg);
        logger.info(msg);


        List<String> courseCodes = QuestionariosQueryDao.findCoursesSigesCodes(reportGroup.getImportYear(), periodos, degrees);

        msg = "Vai processar " + courseCodes.size() + " Cursos ";
        serviceLogInfo(msg);
        logger.info(msg);  
        for(1.5.0/docs/api/java/lang/String.html">String sigesCode: courseCodes)
        {
            if(sigesCode == null)
            {
                msg = "Found Course with siges code null, not known but has units in " + reportGroup.getImportYear();
                serviceLogInfo(msg);
                logger.info(msg);
                continue;
            }
            cursosEncontrados++;

            /** COMMIT OPERATION **/
            setProgress((int)((((float)cursosEncontrados)/((float)courseCodes.size()))*100.0f));
            commitPartially();
            /** COMMIT OPERATION **/

            try{
                Course c = DaoFactory.getCourseDaoImpl().findCourseByCode(""+sigesCode);
                msg = "(" + cursosEncontrados + "/" + courseCodes.size() + ") Found Course sigesCode: " + sigesCode + " " + c.getName() + " will start process";
                serviceLogInfo(msg);
                logger.info(msg);
                CursoPublicReport cursoReport = processCourse("" + sigesCode);


                if(cursoReport == null)
                    cursosSemRespostas++;
                else{
                    1.5.0/docs/api/java/lang/String.html">String tmpPath = cursoReport.getPathGeneratedPdfTemp();

                    QuestionarioReportCursoFile q = DaoFactory.getQuestionarioReportCursoFileDaoImpl().findBySigesCode(1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(sigesCode),reportGroup.getId());
                    if(q == null)
                    {
                        q = new QuestionarioReportCursoFileImpl();
                        q.setReportGroup(reportGroup);
                        q.setEntityCode("" + sigesCode);
                        q.setEntityName(c.getName());
                        //q.setCourse(c);
                        DaoFactory.getQuestionarioReportCursoFileDaoImpl().save(q);
                    }

                    q.setInquiridos(cursoReport.getInquiridosTotal());
                    q.setInquiridosComResposta(cursoReport.getInquiridosComResposta());
                    q.setRespostasRequisitadas(cursoReport.getQuestionariosReqTotal());
                    q.setRespostas(cursoReport.getQuestionariosReqRespondidos());
                    q.setUnidades(cursoReport.getUnidadesRequisitadas());


                    //STATS
                    if(q.getInquiridos() == 0)
                        cursosSemUnidadesAfetas++;
                    else if(q.getRespostas() == 0)
                        cursosSemRespostas++;
                    else
                        cursosComRespostas++;


                    1.5.0/docs/api/java/io/File.html">File tmpFile = new 1.5.0/docs/api/java/io/File.html">File(tmpPath);
                    if(q.getRepositoryStream() == null || q.getRepositoryStream().trim().length() == 0)
                    {
                        1.5.0/docs/api/java/lang/String.html">String repositoryStreamCode = new RepositoryService().storeRepositoryFile(
                                new 1.5.0/docs/api/java/io/FileInputStream.html">FileInputStream(tmpPath),
                                "application/pdf",
                                "pdf",
                                (int)tmpFile.length(),
                                tmpFile.getName(),
                                "reports.QuestionarioReportCursoFile course: " + c.getName() + " (" + sigesCode + ") " + " ano:" + anoLectivo + " periodos:" + periodos.toString() + " degrees:" + degrees.toString(),
                                ResourceAccessControlEnum.authenticatedDomain,//Este relatório de curso é publico
                                DaoFactory.getUserDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(1)));
                        q.setRepositoryStream(repositoryStreamCode);
                    }
                    else
                    {
                        new RepositoryService().updateRepositoryFile(
                                q.getRepositoryStream(),
                                new 1.5.0/docs/api/java/io/FileInputStream.html">FileInputStream(tmpPath),
                                "application/pdf",
                                "pdf",
                                (int)tmpFile.length(),
                                tmpFile.getName(),
                                "reports.QuestionarioReportCursoFile curso: " + c.getName() + " (" + sigesCode + ") " + " ano:" + anoLectivo + " periodos:" + periodos.toString() + " degrees:" + degrees.toString(),
                                ResourceAccessControlEnum.authenticatedDomain);
                    }
                }
                //Final
                cursosProcessados++;
            }catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
            {
                msg = "FAIL - Teacher with siges: " + sigesCode;
                serviceLogError(msg,e);
                logger.error(msg,e);
                cursosFalhados++;
            }
        }

        serviceLogInfo("######################################");
        serviceLogInfo("######################################");
        serviceLogInfo("#Cursos Encontrados:" + cursosEncontrados);
        serviceLogInfo("#Cursos Processados:" + cursosProcessados);
        serviceLogInfo("#Cursos Com Resposta:" + cursosComRespostas);
        serviceLogInfo("#Cursos Sem Respostas:" + cursosSemRespostas);
        serviceLogInfo("#Cursos Sem Unidades Afetas:" + cursosSemUnidadesAfetas);
        serviceLogInfo("#Cursos Falhados:" + cursosFalhados);

        logger.info("######################################");
        logger.info("######################################");
        logger.info("#Cursos Encontrados:" + cursosEncontrados);
        logger.info("#Cursos Processados:" + cursosProcessados);
        logger.info("#Cursos Falhados:" + cursosFalhados);
        logger.info("#Cursos Com Resposta:" + cursosComRespostas);
        logger.info("#Cursos Sem Respostas:" + cursosSemRespostas);
        logger.info("#Cursos Sem Unidades Afetas:" + cursosSemUnidadesAfetas);

        reportGroup = (QuestionarioReportFileGroupCursosAnoImpl) DaoFactory.getQuestionarioReportFileGroupCursosAnoDaoImpl().load(questionarioReportId);
        reportGroup.setEntidadesEncontradas(cursosEncontrados);
        reportGroup.setEntidadesProcessadas(cursosProcessados);
        reportGroup.setEntidadesFalhadas(cursosFalhados);
        reportGroup.setEntidadesComRespostas(cursosComRespostas);
        reportGroup.setEntidadesSemRespostas(cursosSemRespostas);
        reportGroup.setEntidadesSemUnidadesAfetas(cursosSemUnidadesAfetas);

        logger.info("terminating docente reports generation");
        serviceLogInfo("terminating docente reports generation");
        logMessages.addMessage(new DefaultLogMessage("report.docente.gen.terminating", LogMessageTypeEnum.INFO));
        setProgress(100);
        commitPartially();
        return logMessages;
    }
}