public MontarHistoricoEscolarQuery(Dre dre, Ue ue, IEnumerable <AreaDoConhecimento> areasConhecimento,
                                    IEnumerable <IGrouping <string, ComponenteCurricularPorTurma> > componentesCurricularesTurmas,
                                    IEnumerable <AlunoTurmasHistoricoEscolarDto> alunosTurmas,
                                    IEnumerable <MediaFrequencia> mediasFrequencia,
                                    IEnumerable <IGrouping <string, NotasAlunoBimestre> > notas,
                                    IEnumerable <IGrouping <string, FrequenciaAluno> > frequencias,
                                    IEnumerable <TipoNotaCicloAno> tiposNota,
                                    IEnumerable <TransferenciaDto> transferencias,
                                    string[] turmasCodigo, CabecalhoDto cabecalho, LegendaDto legenda,
                                    DadosDataDto dadosData, FuncionarioDto dadosDiretor, FuncionarioDto dadosSecretario,
                                    IEnumerable <IGrouping <long, UeConclusaoPorAlunoAno> > historicoUes,
                                    bool preencherDataImpressao, bool imprimirDadosResponsaveis)
 {
     Dre = dre;
     Ue  = ue;
     AreasConhecimento             = areasConhecimento;
     ComponentesCurricularesTurmas = componentesCurricularesTurmas;
     AlunosTurmas              = alunosTurmas;
     TurmasCodigo              = turmasCodigo;
     Cabecalho                 = cabecalho;
     HistoricoUes              = historicoUes;
     Notas                     = notas;
     Frequencias               = frequencias;
     MediasFrequencia          = mediasFrequencia;
     TiposNota                 = tiposNota;
     Transferencias            = transferencias;
     Legenda                   = legenda;
     DadosData                 = dadosData;
     DadosDiretor              = dadosDiretor;
     DadosSecretario           = dadosSecretario;
     PreencherDataImpressao    = preencherDataImpressao;
     ImprimirDadosResponsaveis = imprimirDadosResponsaveis;
 }
        public async Task Executar(FiltroRelatorioDto request)
        {
            var filtros = request.ObterObjetoFiltro <FiltroHistoricoEscolarDto>();

            var legenda = new LegendaDto(await ObterLegenda());

            var cabecalho = await MontarCabecalho(filtros);

            var alunosTurmas = await MontarAlunosTurmas(filtros);

            var alunosTurmasTransferencia = await MontarAlunosTurmasTransferencia(filtros);

            if ((alunosTurmas == null || !alunosTurmas.Any()) &&
                (alunosTurmasTransferencia == null || !alunosTurmasTransferencia.Any()))
            {
                throw new NegocioException("Não foi encontrado nenhum histórico de promoção e transferência para o(s) aluno(s) da turma.");
            }

            var alunosTransferenciaSemHistorico = alunosTurmasTransferencia.Where(tf => !alunosTurmas.Select(a => a.Aluno.Codigo).Contains(tf.Aluno.Codigo));

            var todosAlunosTurmas = new List <AlunoTurmasHistoricoEscolarDto>();

            if (alunosTransferenciaSemHistorico != null && alunosTransferenciaSemHistorico.Any())
            {
                filtros.AlunosCodigo = alunosTransferenciaSemHistorico.Select(a => a.Aluno.Codigo).ToArray();
                var alunosTransferenciaTurmas = await MontarAlunosTurmas(filtros);

                if (alunosTransferenciaTurmas != null && alunosTransferenciaTurmas.Any())
                {
                    todosAlunosTurmas.AddRange(alunosTransferenciaTurmas);
                }
            }

            if (alunosTurmas != null && alunosTurmas.Any())
            {
                todosAlunosTurmas.AddRange(alunosTurmas);
            }

            if (alunosTurmasTransferencia != null && alunosTurmasTransferencia.Any())
            {
                todosAlunosTurmas.AddRange(alunosTurmasTransferencia);
            }

            var todasTurmas = todosAlunosTurmas.SelectMany(a => a.Turmas).DistinctBy(t => t.Codigo);
            var todosAlunos = todosAlunosTurmas.Select(a => a.Aluno).DistinctBy(t => t.Codigo);

            var turmasCodigo = todasTurmas.Select(a => a.Codigo);
            var alunosCodigo = todosAlunos.Select(a => a.Codigo);

            IEnumerable <IGrouping <long, UeConclusaoPorAlunoAno> > historicoUes = null;

            if (todosAlunos != null && todosAlunos.Any())
            {
                historicoUes = await ObterUesConclusao(alunosCodigo.Select(long.Parse).ToArray(), filtros.Modalidade);
            }

            var componentesCurriculares = await ObterComponentesCurricularesTurmasRelatorio(turmasCodigo.ToArray(), filtros.UeCodigo, filtros.Modalidade, filtros.Usuario);

            var areasDoConhecimento = await ObterAreasConhecimento(componentesCurriculares);

            var dre = await ObterDrePorCodigo(filtros.DreCodigo);

            var ue = await ObterUePorCodigo(filtros.UeCodigo);

            var enderecoAtoUe = await ObterEnderecoAtoUe(filtros.UeCodigo);

            var tipoNotas = await ObterTiposNotaRelatorio();

            var notas = await ObterNotasAlunos(turmasCodigo.ToArray(), alunosCodigo.ToArray());

            var frequencias = await ObterFrequenciasAlunos(turmasCodigo.ToArray(), alunosCodigo.ToArray());

            var mediasFrequencia = await ObterMediasFrequencia();

            var dadosData = await ObterDadosData(filtros.PreencherDataImpressao);

            FuncionarioDto dadosDiretor = null, dadosSecretario = null;

            if (filtros.ImprimirDadosResponsaveis)
            {
                dadosDiretor = await ObterFuncionarioUePorCargo(filtros.UeCodigo, (int)Cargo.Diretor);

                dadosSecretario = await ObterFuncionarioUePorCargo(filtros.UeCodigo, (int)Cargo.Secretario);
            }

            var turmasHistorico     = alunosTurmas.SelectMany(t => t.Turmas).DistinctBy(t => t.Codigo);
            var turmasTransferencia = alunosTurmasTransferencia.SelectMany(t => t.Turmas).DistinctBy(t => t.Codigo);

            var turmasEja       = turmasHistorico.Where(t => t.ModalidadeCodigo == Modalidade.EJA);
            var turmasFundMedio = turmasHistorico.Where(t => t.ModalidadeCodigo != Modalidade.EJA);

            IEnumerable <HistoricoEscolarDTO>    resultadoFundMedio = null, resultadoFinalFundamental = null, resultadoFinalMedio = null;
            IEnumerable <HistoricoEscolarEJADto> resultadoEJA           = null;
            IEnumerable <TransferenciaDto>       resultadoTransferencia = null;

            if (turmasTransferencia != null && turmasTransferencia.Any())
            {
                resultadoTransferencia = await mediator.Send(new MontarHistoricoEscolarTransferenciaQuery(areasDoConhecimento, componentesCurriculares, alunosTurmasTransferencia, mediasFrequencia, notas,
                                                                                                          frequencias, tipoNotas, turmasTransferencia.Select(a => a.Codigo).Distinct().ToArray()));
            }

            if ((turmasFundMedio != null && turmasFundMedio.Any()) || (turmasTransferencia != null && turmasTransferencia.Any(t => t.ModalidadeCodigo != Modalidade.EJA)))
            {
                resultadoFundMedio = await mediator.Send(new MontarHistoricoEscolarQuery(dre, ue, areasDoConhecimento, componentesCurriculares, todosAlunosTurmas, mediasFrequencia, notas,
                                                                                         frequencias, tipoNotas, resultadoTransferencia, turmasFundMedio?.Select(a => a.Codigo).Distinct().ToArray(), cabecalho, legenda, dadosData, dadosDiretor, dadosSecretario,
                                                                                         historicoUes, filtros.PreencherDataImpressao, filtros.ImprimirDadosResponsaveis));
            }
            else if ((turmasEja != null && turmasEja.Any()) || (turmasTransferencia != null && turmasTransferencia.Any(t => t.ModalidadeCodigo == Modalidade.EJA)))
            {
                resultadoEJA = await mediator.Send(new MontarHistoricoEscolarEJAQuery(dre, ue, areasDoConhecimento, componentesCurriculares, todosAlunosTurmas, mediasFrequencia, notas,
                                                                                      frequencias, tipoNotas, resultadoTransferencia, turmasEja?.Select(a => a.Codigo).Distinct().ToArray(), cabecalho, legenda, dadosData, dadosDiretor, dadosSecretario,
                                                                                      historicoUes, filtros.PreencherDataImpressao, filtros.ImprimirDadosResponsaveis));
            }

            if (resultadoFundMedio != null && resultadoFundMedio.Any())
            {
                resultadoFinalFundamental = resultadoFundMedio.Where(a => a.Modalidade == Modalidade.Fundamental);
                resultadoFinalMedio       = resultadoFundMedio.Where(a => a.Modalidade == Modalidade.Medio);

                foreach (var item in resultadoFinalMedio)
                {
                    item.Legenda.Texto = string.Empty;
                }
            }

            if ((resultadoFinalFundamental != null && resultadoFinalFundamental.Any()) ||
                (resultadoFinalMedio != null && resultadoFinalMedio.Any()) ||
                (resultadoEJA != null && resultadoEJA.Any()))
            {
                if (resultadoEJA != null && resultadoEJA.Any())
                {
                    await EnviaRelatorioEJA(resultadoEJA, request.CodigoCorrelacao);
                }

                if (resultadoFinalFundamental != null && resultadoFinalFundamental.Any())
                {
                    await EnviaRelatorioFundamental(resultadoFinalFundamental, request.CodigoCorrelacao);
                }

                if (resultadoFinalMedio != null && resultadoFinalMedio.Any())
                {
                    await EnviaRelatorioMedio(resultadoFinalMedio, request.CodigoCorrelacao);
                }
            }
            else
            {
                throw new NegocioException("Não foi possível localizar informações com os filtros selecionados");
            }
        }