private async Task MontarEstruturaLinhas(ConselhoClasseAtaFinalDto relatorio, IEnumerable <AlunoSituacaoAtaFinalDto> alunos, IEnumerable <IGrouping <ComponenteCurricularGrupoMatriz, ComponenteCurricularPorTurma> > gruposMatrizes, IEnumerable <NotaConceitoBimestreComponente> notasFinais, IEnumerable <FrequenciaAluno> frequenciaAlunos, IEnumerable <FrequenciaAluno> frequenciaAlunosGeral, IEnumerable <ConselhoClasseParecerConclusivo> pareceresConclusivos, IEnumerable <PeriodoEscolar> periodosEscolares, string turmaCodigo)
        {
            // Primmeiro alunos com numero de chamada
            foreach (var aluno in alunos.Where(a => int.Parse(a.NumeroAlunoChamada ?? "0") > 0).Select(a => new AlunoSituacaoAtaFinalDto(a)).OrderBy(a => a.NumeroAlunoChamada))
            {
                relatorio.Linhas.Add(await MontarLinhaAluno(aluno, gruposMatrizes, notasFinais, frequenciaAlunos, frequenciaAlunosGeral, pareceresConclusivos, periodosEscolares, turmaCodigo));
            }

            // Depois alunos sem numero ordenados por nome
            foreach (var aluno in alunos.Where(a => int.Parse(a.NumeroAlunoChamada ?? "0") == 0).Select(a => new AlunoSituacaoAtaFinalDto(a)).OrderBy(a => a.NomeAluno))
            {
                relatorio.Linhas.Add(await MontarLinhaAluno(aluno, gruposMatrizes, notasFinais, frequenciaAlunos, frequenciaAlunosGeral, pareceresConclusivos, periodosEscolares, turmaCodigo));
            }
        }
        private async Task <ConselhoClasseAtaFinalDto> MontarEstruturaRelatorio(Modalidade modalidadeCodigo, ConselhoClasseAtaFinalCabecalhoDto cabecalho, IEnumerable <AlunoSituacaoAtaFinalDto> alunos, IEnumerable <ComponenteCurricularPorTurma> componentesCurriculares, IEnumerable <NotaConceitoBimestreComponente> notasFinais, IEnumerable <FrequenciaAluno> frequenciaAlunos, IEnumerable <FrequenciaAluno> frequenciaAlunosGeral, IEnumerable <ConselhoClasseParecerConclusivo> pareceresConclusivos, IEnumerable <PeriodoEscolar> periodosEscolares, string turmaCodigo)
        {
            var relatorio = new ConselhoClasseAtaFinalDto();

            relatorio.Modalidade = modalidadeCodigo;

            relatorio.Cabecalho = cabecalho;
            var gruposMatrizes = componentesCurriculares.Where(c => c.GrupoMatriz != null).GroupBy(c => c.GrupoMatriz);

            MontarEstruturaGruposMatriz(relatorio, gruposMatrizes, periodosEscolares);
            await MontarEstruturaLinhas(relatorio, alunos, gruposMatrizes, notasFinais, frequenciaAlunos, frequenciaAlunosGeral, pareceresConclusivos, periodosEscolares, turmaCodigo);

            return(relatorio);
        }
        private ConselhoClasseAtaFinalGrupoDto VerificarGrupoMatrizNaPagina(ConselhoClasseAtaFinalDto modelCompleto, ConselhoClasseAtaFinalPaginaDto modelPagina, ConselhoClasseAtaFinalComponenteDto disciplina)
        {
            if (!modelPagina.GruposMatriz.Any(x => x.Id == disciplina.IdGrupoMatriz))
            {
                var grupoMatriz = modelCompleto.GruposMatriz.FirstOrDefault(x => x.Id == disciplina.IdGrupoMatriz);

                var novoGrupoMatriz = new ConselhoClasseAtaFinalGrupoDto
                {
                    ComponentesCurriculares = new List <ConselhoClasseAtaFinalComponenteDto>(),
                    Id   = grupoMatriz.Id,
                    Nome = grupoMatriz.Nome
                };

                modelPagina.GruposMatriz.Add(novoGrupoMatriz);
            }

            return(modelPagina.GruposMatriz.FirstOrDefault(x => x.Id == disciplina.IdGrupoMatriz));
        }
        private void MontarEstruturaGruposMatriz(ConselhoClasseAtaFinalDto relatorio, IEnumerable <IGrouping <ComponenteCurricularGrupoMatriz, ComponenteCurricularPorTurma> > gruposMatrizes, IEnumerable <PeriodoEscolar> periodosEscolares)
        {
            if (gruposMatrizes != null)
            {
                foreach (var grupoMatriz in gruposMatrizes)
                {
                    var grupoMatrizDto = new ConselhoClasseAtaFinalGrupoDto()
                    {
                        Id   = grupoMatriz.Key.Id,
                        Nome = grupoMatriz.Key.Nome
                    };

                    foreach (var componenteCurricular in grupoMatriz)
                    {
                        grupoMatrizDto.AdicionarComponente(componenteCurricular.CodDisciplina, componenteCurricular.Disciplina, grupoMatrizDto.Id, periodosEscolares.OrderBy(p => p.Bimestre).Select(a => a.Bimestre));
                    }

                    relatorio.GruposMatriz.Add(grupoMatrizDto);
                }
            }
        }
        private List <ConselhoClasseAtaFinalPaginaDto> MontarEstruturaPaginada(ConselhoClasseAtaFinalDto dadosRelatorio)
        {
            var maximoComponentesPorPagina      = 7;
            var maximoComponentesPorPaginaFinal = 3;
            var quantidadeDeLinhasPorPagina     = 20;

            List <ConselhoClasseAtaFinalPaginaDto> modelsPaginas = new List <ConselhoClasseAtaFinalPaginaDto>();

            List <ConselhoClasseAtaFinalComponenteDto> todasAsDisciplinas = dadosRelatorio.GruposMatriz.SelectMany(x => x.ComponentesCurriculares).ToList();

            int quantidadePaginasHorizontal = CalcularPaginasHorizontal(maximoComponentesPorPagina, maximoComponentesPorPaginaFinal, todasAsDisciplinas.Count());

            int quantidadePaginasVertical = (int)Math.Ceiling(dadosRelatorio.Linhas.Count / (decimal)quantidadeDeLinhasPorPagina);

            int contPagina = 1;

            for (int v = 0; v < quantidadePaginasVertical; v++)
            {
                for (int h = 0; h < quantidadePaginasHorizontal; h++)
                {
                    bool ehPaginaFinal = (h + 1) == quantidadePaginasHorizontal;

                    int quantidadeDisciplinasDestaPagina = ehPaginaFinal ? maximoComponentesPorPaginaFinal : maximoComponentesPorPagina;

                    ConselhoClasseAtaFinalPaginaDto modelPagina = new ConselhoClasseAtaFinalPaginaDto
                    {
                        Modalidade      = dadosRelatorio.Modalidade,
                        Cabecalho       = dadosRelatorio.Cabecalho,
                        NumeroPagina    = contPagina++,
                        FinalHorizontal = ehPaginaFinal,
                        TotalPaginas    = quantidadePaginasHorizontal * quantidadePaginasVertical
                    };

                    if (todasAsDisciplinas.Any())
                    {
                        IEnumerable <ConselhoClasseAtaFinalComponenteDto> disciplinasDestaPagina = todasAsDisciplinas.Skip(h * maximoComponentesPorPagina).Take(quantidadeDisciplinasDestaPagina);

                        foreach (ConselhoClasseAtaFinalComponenteDto disciplina in disciplinasDestaPagina)
                        {
                            var grupoMatrizAtual = VerificarGrupoMatrizNaPagina(dadosRelatorio, modelPagina, disciplina);
                            if (grupoMatrizAtual != null)
                            {
                                grupoMatrizAtual.ComponentesCurriculares.Add(disciplina);
                            }
                        }
                    }

                    var gruposMatrizDestaPagina   = modelPagina.GruposMatriz.Select(x => x.Id);
                    var idsDisciplinasDestaPagina = modelPagina.GruposMatriz.SelectMany(x => x.ComponentesCurriculares).Select(x => x.Id);

                    int quantidadeHorizontal = idsDisciplinasDestaPagina.Count();

                    List <ConselhoClasseAtaFinalLinhaDto> linhas = dadosRelatorio.Linhas.Skip((v) * quantidadeDeLinhasPorPagina).Take(quantidadeDeLinhasPorPagina)
                                                                   .Select(x => new ConselhoClasseAtaFinalLinhaDto
                    {
                        Id       = x.Id,
                        Nome     = x.Nome,
                        Inativo  = x.Inativo,
                        Situacao = x.Situacao,
                        Celulas  = x.Celulas
                    }).ToList();

                    foreach (ConselhoClasseAtaFinalLinhaDto linha in linhas)
                    {
                        List <ConselhoClasseAtaFinalCelulaDto> todasAsCelulas = linha.Celulas;

                        linha.Celulas = todasAsCelulas.Where(x => gruposMatrizDestaPagina.Contains(x.GrupoMatriz) && idsDisciplinasDestaPagina.Contains(x.ComponenteCurricular)).Select(x => new ConselhoClasseAtaFinalCelulaDto {
                            GrupoMatriz = x.GrupoMatriz, ComponenteCurricular = x.ComponenteCurricular, Coluna = x.Coluna, Valor = x.Valor
                        }).ToList();

                        if (ehPaginaFinal)
                        {
                            IEnumerable <ConselhoClasseAtaFinalCelulaDto> celulasFinais = todasAsCelulas.Where(x => x.GrupoMatriz == 99);

                            linha.Celulas.AddRange(celulasFinais);
                        }
                    }

                    modelPagina.Linhas.AddRange(linhas);

                    foreach (var grupoMatriz in modelPagina.GruposMatriz)
                    {
                        grupoMatriz.QuantidadeColunas = modelPagina.Linhas.First().Celulas.Where(x => x.GrupoMatriz == grupoMatriz.Id).Count();
                    }

                    modelsPaginas.Add(modelPagina);
                }
            }

            return(modelsPaginas);
        }