<commit_before>﻿using Calcular.CoreApi.Models;
using Calcular.CoreApi.Models.Business;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Calcular.CoreApi.Shared;
using System;
using System.Globalization;
using Calcular.CoreApi.Models.ViewModels;

namespace Calcular.CoreApi.Controllers.Business
{
    [Route("api/[controller]")]
    public class ReportController : Controller
    {
        private readonly ApplicationDbContext db;

        public ReportController(ApplicationDbContext db)
        {
            this.db = db;
        }

        /// <summary>
        /// Relatório de Custo/Processo agrupado por clientes.
        /// </summary>
        /// <returns></returns>
        [HttpGet("custoprocesso")]
        [Authorize(Roles = "Gerencial")]
        public async Task<IActionResult> GetCustoProcesso()
        {
            var clientes = await db.Clientes
                                .Include(x => x.Processos)
                                    .ThenInclude(x => x.Honorarios)
                                .Include(x => x.Processos)
                                    .ThenInclude(x => x.Servicos).ThenInclude(x => x.Atividades).ThenInclude(x => x.ComissaoAtividade)
                                .Where(x => x.Processos.Any())
                                .ToListAsync();

            var result = clientes.GroupBy(x => new { Cliente = x.Nome, Empresa = x.Empresa })
                                .Select(x =>
                                {
                                    var quantidadeProcessos = x.Sum(c => c.Processos.Count());
                                    var totalHonorario = x.Sum(c => c.Processos.Sum(p => p.Honorario));
                                    var totalCusto = x.Sum(c => c.Processos.Sum(p => p.Servicos.Sum(s => s.Atividades.Sum(a => a.ComissaoAtividade != null ? a.ComissaoAtividade.ValorFinal : 0))));

                                    return new
                                    {
                                        Cliente = x.Key.Cliente,
                                        Empresa = x.Key.Empresa,
                                        QuantidadeProcessos = quantidadeProcessos,
                                        TotalHonorario = totalHonorario,
                                        TotalCusto = totalCusto,
                                        Diferenca = totalHonorario - totalCusto,
                                        MediaHonorario = totalHonorario / quantidadeProcessos,
                                        MediaCusto = totalCusto / quantidadeProcessos,
                                    };
                                })
                                .OrderBy(x => x.Empresa).ThenBy(x => x.Cliente);

            return Ok(result);
        }

        /// <summary>
        /// Relatório de Produtividade por Colaborador
        /// </summary>
        /// <returns></returns>
        [HttpGet("produtividadecolaborador")]
        [Authorize(Roles = "Gerencial")]
        public async Task<IActionResult> GetProdutividadePorColaborador(DateTime? dataFim = null, int quantidadeMeses = 4)
        {
            var dataInicio = dataFim.HasValue ? dataFim.Value.AddMonths(-quantidadeMeses) : DateTime.Now.AddMonths(-quantidadeMeses);

            var data = await db.Atividades
                            .Include(x => x.Responsavel)
                            .Where(x => !string.IsNullOrEmpty(x.ResponsavelId)
                                        && x.Entrega.HasValue
                                        && (x.EtapaAtividade == EtapaAtividadeEnum.Original)
                                        && x.TipoExecucao == TipoExecucaoEnum.Finalizado || x.TipoExecucao == TipoExecucaoEnum.Revisar)
                            .ToListAsync();

            var revisores = data.Select(x => x.Responsavel.Name).Distinct();

            var group = data.GroupBy(x => new { Mes = new DateTime(x.Entrega.Value.Year, x.Entrega.Value.Month, 1), Responsavel = x.Responsavel })
                            .Select(x => new
                            {
                                Responsavel = x.Key.Responsavel.Name,
                                Mes = x.Key.Mes,
                                Atividades = x.Count(),
                            }).ToList();

            var result = new
            {
                Meses = Enumerable.Range(0, quantidadeMeses).Select(i => dataInicio.AddMonths(i).ToString("MMMM/yy", new CultureInfo("pt-PT"))),
                Report = revisores.Select(z => new
                {
                    Name = z,
                    Data = Enumerable.Range(0, quantidadeMeses).Select(i =>
                    {
                        var mes = dataInicio.AddMonths(i);
                        return group.Where(g => g.Responsavel == z && g.Mes == new DateTime(mes.Year, mes.Month, 1)).Select(g => g.Atividades);
                    }),
                }),
            };

            return Ok(result);
        }

        /// <summary>
        /// Relatório de Honorários por mês
        /// </summary>
        /// <returns></returns>
        [HttpGet("honorarios")]
        [Authorize(Roles = "Gerencial")]
        public IActionResult GetHonorarios(DateTime? dataFim = null, int quantidadeMeses = 4)
        {
            var dataInicio = dataFim.HasValue ? dataFim.Value.AddMonths(-quantidadeMeses + 1) : DateTime.Now.AddMonths(-quantidadeMeses + 1);
            dataInicio = new DateTime(dataInicio.Year, dataInicio.Month, 1);

            var meses = Enumerable.Range(0, quantidadeMeses).Select(i => dataInicio.AddMonths(i));

            var data = db.Honorarios.Include(x => x.Processo);

            var groupedHonorarios = data
                            .Where(x => x.Data >= dataInicio)
                            .GroupBy(x => new
                            {
                                Mes = new DateTime(x.Data.Year, x.Data.Month, 1),
                                Registro = x.Registro,
                                Oficial = x.Processo.Parte == ParteEnum.Oficial,
                            })
                            .Select(x => new
                            {
                                Mes = x.Key.Mes,
                                Oficial = x.Key.Oficial,
                                Registro = x.Key.Registro,
                                Valor = x.Sum(y => y.Valor),
                                Quantidade = x.Count(),

                            })
                            .OrderBy(x => x.Mes);

            var groupedTotal = data
                            .Where(x => x.Data >= dataInicio)
                            .GroupBy(x => new
                            {
                                Mes = new DateTime(x.Data.Year, x.Data.Month, 1),
                                Registro = x.Registro,
                            });

            var pendentes = data.Where(x => x.Processo.Total.HasValue);
            var groupedPendentes = pendentes.GroupBy(x => x.Processo.Parte == ParteEnum.Oficial)
                                            .Select(x => new
                                            {
                                                Oficial = x.Key,
                                                Total = x.Sum(y => y.Processo.Total),
                                                Quantidade = x.Count()
                                            });

            var result = new
            {
                Meses = meses.Select(m => m.ToString("MMMM/yy", new CultureInfo("pt-PT"))),
                FaturadosAssistencia = meses.Select(x =>
                                                    {
                                                        var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Honorario && !g.Oficial && g.Mes == x);
                                                        return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                    }),

                RecebidosAssistencia = meses.Select(x =>
                                                    {
                                                        var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Pagamento && !g.Oficial && g.Mes == x);
                                                        return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                    }),

                RecebidosOficial = meses.Select(x =>
                                                {
                                                    var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Pagamento && g.Oficial && g.Mes == x);
                                                    return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                }),

                TotalHonorarios = meses.Select(x =>
                                                {
                                                    var h = groupedHonorarios.Where(g => g.Registro == RegistroEnum.Pagamento && g.Mes == x);
                                                    return new { Valor = h != null ? h.Sum(y => y.Valor) : 0, Quantidade = h != null ? h.Sum(y => y.Quantidade) : 0 };
                                                }),

                PendenteAssistenciaValor = groupedPendentes.Single(x => !x.Oficial).Total,
                PendenteAssistenciaQuantidade = groupedPendentes.Single(x => !x.Oficial).Quantidade,
                PendenteOficialValor = groupedPendentes.Single(x => x.Oficial).Total,
                PendenteOficialQuantidade = groupedPendentes.Single(x => x.Oficial).Quantidade,
                TotalPendenteValor = groupedPendentes.Sum(x => x.Total),
                TotalPendenteQuantidade = groupedPendentes.Sum(x => x.Quantidade),
            };

            return Ok(result);
        }
    }
}<commit_msg>Adicionado relatório de Tipo Processo<commit_after>﻿using Calcular.CoreApi.Models;
using Calcular.CoreApi.Models.Business;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Calcular.CoreApi.Shared;
using System;
using System.Globalization;
using Calcular.CoreApi.Models.ViewModels;

namespace Calcular.CoreApi.Controllers.Business
{
    [Route("api/[controller]")]
    public class ReportController : Controller
    {
        private readonly ApplicationDbContext db;

        public ReportController(ApplicationDbContext db)
        {
            this.db = db;
        }

        /// <summary>
        /// Relatório de Custo/Processo agrupado por clientes.
        /// </summary>
        /// <returns></returns>
        [HttpGet("custoprocesso")]
        [Authorize(Roles = "Gerencial")]
        public async Task<IActionResult> GetCustoProcesso()
        {
            var clientes = await db.Clientes
                                .Include(x => x.Processos)
                                    .ThenInclude(x => x.Honorarios)
                                .Include(x => x.Processos)
                                    .ThenInclude(x => x.Servicos).ThenInclude(x => x.Atividades).ThenInclude(x => x.ComissaoAtividade)
                                .Where(x => x.Processos.Any())
                                .ToListAsync();

            var result = clientes.GroupBy(x => new { Cliente = x.Nome, Empresa = x.Empresa })
                                .Select(x =>
                                {
                                    var quantidadeProcessos = x.Sum(c => c.Processos.Count());
                                    var totalHonorario = x.Sum(c => c.Processos.Sum(p => p.Honorario));
                                    var totalCusto = x.Sum(c => c.Processos.Sum(p => p.Servicos.Sum(s => s.Atividades.Sum(a => a.ComissaoAtividade != null ? a.ComissaoAtividade.ValorFinal : 0))));

                                    return new
                                    {
                                        Cliente = x.Key.Cliente,
                                        Empresa = x.Key.Empresa,
                                        QuantidadeProcessos = quantidadeProcessos,
                                        TotalHonorario = totalHonorario,
                                        TotalCusto = totalCusto,
                                        Diferenca = totalHonorario - totalCusto,
                                        MediaHonorario = totalHonorario / quantidadeProcessos,
                                        MediaCusto = totalCusto / quantidadeProcessos,
                                    };
                                })
                                .OrderBy(x => x.Empresa).ThenBy(x => x.Cliente);

            return Ok(result);
        }

        /// <summary>
        /// Relatório de Produtividade por Colaborador
        /// </summary>
        /// <returns></returns>
        [HttpGet("produtividadecolaborador")]
        [Authorize(Roles = "Gerencial")]
        public async Task<IActionResult> GetProdutividadePorColaborador(DateTime? dataFim = null, int quantidadeMeses = 4)
        {
            var dataInicio = dataFim.HasValue ? dataFim.Value.AddMonths(-quantidadeMeses) : DateTime.Now.AddMonths(-quantidadeMeses);

            var data = await db.Atividades
                            .Include(x => x.Responsavel)
                            .Where(x => !string.IsNullOrEmpty(x.ResponsavelId)
                                        && x.Entrega.HasValue
                                        && (x.EtapaAtividade == EtapaAtividadeEnum.Original)
                                        && x.TipoExecucao == TipoExecucaoEnum.Finalizado || x.TipoExecucao == TipoExecucaoEnum.Revisar)
                            .ToListAsync();

            var revisores = data.Select(x => x.Responsavel.Name).Distinct();

            var group = data.GroupBy(x => new { Mes = new DateTime(x.Entrega.Value.Year, x.Entrega.Value.Month, 1), Responsavel = x.Responsavel })
                            .Select(x => new
                            {
                                Responsavel = x.Key.Responsavel.Name,
                                Mes = x.Key.Mes,
                                Atividades = x.Count(),
                            }).ToList();

            var result = new
            {
                Meses = Enumerable.Range(0, quantidadeMeses).Select(i => dataInicio.AddMonths(i).ToString("MMMM/yy", new CultureInfo("pt-PT"))),
                Report = revisores.Select(z => new
                {
                    Name = z,
                    Data = Enumerable.Range(0, quantidadeMeses).Select(i =>
                    {
                        var mes = dataInicio.AddMonths(i);
                        return group.Where(g => g.Responsavel == z && g.Mes == new DateTime(mes.Year, mes.Month, 1)).Select(g => g.Atividades);
                    }),
                }),
            };

            return Ok(result);
        }

        /// <summary>
        /// Relatório de Honorários por mês
        /// </summary>
        /// <returns></returns>
        [HttpGet("honorarios")]
        [Authorize(Roles = "Gerencial")]
        public IActionResult GetHonorarios(DateTime? dataFim = null, int quantidadeMeses = 4)
        {
            var dataInicio = dataFim.HasValue ? dataFim.Value.AddMonths(-quantidadeMeses + 1) : DateTime.Now.AddMonths(-quantidadeMeses + 1);
            dataInicio = new DateTime(dataInicio.Year, dataInicio.Month, 1);

            var meses = Enumerable.Range(0, quantidadeMeses).Select(i => dataInicio.AddMonths(i));

            var data = db.Honorarios.Include(x => x.Processo);

            var groupedHonorarios = data
                            .Where(x => x.Data >= dataInicio)
                            .GroupBy(x => new
                            {
                                Mes = new DateTime(x.Data.Year, x.Data.Month, 1),
                                Registro = x.Registro,
                                Oficial = x.Processo.Parte == ParteEnum.Oficial,
                            })
                            .Select(x => new
                            {
                                Mes = x.Key.Mes,
                                Oficial = x.Key.Oficial,
                                Registro = x.Key.Registro,
                                Valor = x.Sum(y => y.Valor),
                                Quantidade = x.Count(),

                            })
                            .OrderBy(x => x.Mes);

            var groupedTotal = data
                            .Where(x => x.Data >= dataInicio)
                            .GroupBy(x => new
                            {
                                Mes = new DateTime(x.Data.Year, x.Data.Month, 1),
                                Registro = x.Registro,
                            });

            var pendentes = data.Where(x => x.Processo.Total.HasValue);
            var groupedPendentes = pendentes.GroupBy(x => x.Processo.Parte == ParteEnum.Oficial)
                                            .Select(x => new
                                            {
                                                Oficial = x.Key,
                                                Total = x.Sum(y => y.Processo.Total),
                                                Quantidade = x.Count()
                                            });

            var result = new
            {
                Meses = meses.Select(m => m.ToString("MMMM/yy", new CultureInfo("pt-PT"))),
                FaturadosAssistencia = meses.Select(x =>
                                                    {
                                                        var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Honorario && !g.Oficial && g.Mes == x);
                                                        return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                    }),

                RecebidosAssistencia = meses.Select(x =>
                                                    {
                                                        var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Pagamento && !g.Oficial && g.Mes == x);
                                                        return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                    }),

                RecebidosOficial = meses.Select(x =>
                                                {
                                                    var h = groupedHonorarios.SingleOrDefault(g => g.Registro == RegistroEnum.Pagamento && g.Oficial && g.Mes == x);
                                                    return new { Valor = h != null ? h.Valor : 0, Quantidade = h != null ? h.Quantidade : 0 };
                                                }),

                TotalHonorarios = meses.Select(x =>
                                                {
                                                    var h = groupedHonorarios.Where(g => g.Registro == RegistroEnum.Pagamento && g.Mes == x);
                                                    return new { Valor = h != null ? h.Sum(y => y.Valor) : 0, Quantidade = h != null ? h.Sum(y => y.Quantidade) : 0 };
                                                }),

                PendenteAssistenciaValor = groupedPendentes.Single(x => !x.Oficial).Total,
                PendenteAssistenciaQuantidade = groupedPendentes.Single(x => !x.Oficial).Quantidade,
                PendenteOficialValor = groupedPendentes.Single(x => x.Oficial).Total,
                PendenteOficialQuantidade = groupedPendentes.Single(x => x.Oficial).Quantidade,
                TotalPendenteValor = groupedPendentes.Sum(x => x.Total),
                TotalPendenteQuantidade = groupedPendentes.Sum(x => x.Quantidade),
            };

            return Ok(result);
        }

        /// <summary>
        /// Relatório de Honorários por mês
        /// </summary>
        /// <returns></returns>
        [HttpGet("tipoprocesso")]
        [Authorize(Roles = "Gerencial")]
        public async Task<IActionResult> GetTipoProcessos(DateTime? dataFim = null, int quantidadeMeses = 12)
        {
            var dataInicio = dataFim.HasValue ? dataFim.Value.AddMonths(-quantidadeMeses + 1) : DateTime.Now.AddMonths(-quantidadeMeses + 1);
            dataInicio = new DateTime(dataInicio.Year, dataInicio.Month, 1);

            var meses = Enumerable.Range(0, quantidadeMeses).Select(i => dataInicio.AddMonths(i));

            var data = await db.Servicos
                               .Include(x => x.Processo).ThenInclude(x => x.Servicos)
                               .Where(x => x.Entrada >= dataInicio).ToListAsync();

            var grouped = data.GroupBy(x => new
            {
                Mes = new DateTime(x.Entrada.Year, x.Entrada.Month, 1),
                Oficial = x.Processo.Parte == ParteEnum.Oficial,
            })
                                .Select(x => new
                                {
                                    Mes = x.Key.Mes,
                                    Oficial = x.Key.Oficial,
                                    Quantidade = x.Count(),
                                })
                                .OrderBy(x => x.Mes);

            var novos = data.Where(x => x.Processo.Servicos.Count == 1)
                            .GroupBy(x => new DateTime(x.Entrada.Year, x.Entrada.Month, 1))
                            .Select(x => new
                            {
                                Mes = x.Key,
                                Quantidade = x.Count(),
                            })
                            .OrderBy(x => x.Mes);

            var result = new
            {
                Meses = meses.Select(m => m.ToString("MMM/yy", new CultureInfo("pt-PT"))),
                QuantidadeOficial = meses.Select(x => grouped.SingleOrDefault(g => g.Oficial && g.Mes == x)?.Quantidade ?? 0 ),
                QuantidadeAssistencia = meses.Select(x => grouped.SingleOrDefault(g => !g.Oficial && g.Mes == x)?.Quantidade ?? 0),
                QuantidadeNovos = meses.Select(x => novos.SingleOrDefault(g => g.Mes == x)?.Quantidade ?? 0),
            };

            return Ok(result);
        }
    }
}
{'fraction_non_alphanumeric': 0.10363556723609287, 'fraction_numerical': 0.0023653088042049934, 'mean_word_length': 1.0706511881008525, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 175, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 144, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2125499', 'n_tokens_mistral': 5869, 'n_tokens_neox': 5647, 'n_words': 1015}