Ir para o conteúdo principal

[ETP] Migração das regras de negócio de férias do Portal do Servidor para o SID

ESTUDO TÉCNICO PRELIMINAR - ETP

Autores:
José Lucas da Silva Costa,
João Pedro Rocha Brito,
Jônatas Neves Legal


1 - Introdução

Inicialmente o SID (Sistema Integrado de Descanso) é o sistema responsável pelo controle de férias do Poder Executivo Estadual, atualmente o Portal do Servidor no ato de uma solicitação de férias ou remarcação se comunica com o SID para lançamento de uma solicitação. A problemática envolve informar tratar a respeito das regras de negócio que estão no Portal do Servidor e deveriam está na API do SID.

2 - Complexidade de cada funcionalidade

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using PortalDoServidor.AppService.Interface;
using PortalDoServidor.AppService.ViewModel.Ferias;
using PortalDoServidor.CrossCutting.Services.Dto;
using PortalDoServidor.CrossCutting.Services.Enumerables;
using PortalDoServidor.CrossCutting.Services.Interface;
using PortalDoServidor.CrossCutting.Services.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PortalDoServidor.Apresentacao.Controllers
{
    [Authorize]
    public class FeriasController : Controller
    {
        private readonly IUserService userService;
        private readonly IFeriasAppService feriasAppService;
        private readonly IApiServicos apiServicos;
        private readonly IServicoAppService servicoAppService;
        private readonly IColaboradorAppService colaboradorAppService;

        public FeriasController(IUserService userService, IFeriasAppService feriasAppService, IApiServicos apiServicos, IServicoAppService servicoAppService, IColaboradorAppService colaboradorAppService)
        {
            this.userService = userService;
            this.feriasAppService = feriasAppService;
            this.apiServicos = apiServicos;
            this.servicoAppService = servicoAppService;
            this.colaboradorAppService = colaboradorAppService;
        }

        public async Task<IActionResult> Index()
        {
            var cpfDoColaborador = userService.ObterCpf();
            var matriculaDoColaborador = userService.ObterMatricula();
            var nomeDoColaborador = userService.ObterNome();
            var cargo = userService.ObterCargo();

            var feriasViewModel = await feriasAppService.BuscarSolicitacoesDeFeriasViewModel(cpfDoColaborador);

            if (cargo.Contains("TÉCNICO EM RADIOLOGIA"))
                feriasViewModel.EhTecnicoEmRadiologia = true;

            ViewData["Colaborador"] = nomeDoColaborador;
            ViewData["PossuiFeriasPendentes"] = await feriasAppService.VerificarSePossuiFeriasPendentes(cpfDoColaborador);

            return View(feriasViewModel);
        }

        public async Task<IActionResult> SolicitacoesDoColaborador()
        {
            var cpfDoColaborador = userService.ObterCpf();
            var solicitacoes = await feriasAppService.BuscarSolicitacoesDeFeriasDoColaborador(cpfDoColaborador);
            return View(solicitacoes);
        }

        public async Task<IActionResult> SolicitacoesDosServidoresDoDepartamento(int? solicitacaoAnoDeExercicio)
        {
            var cpfDoServidor = userService.ObterCpf();
            int anoDeExercicio = solicitacaoAnoDeExercicio ?? DateTime.Now.AddYears(1).Year;
            var solicitacoes = await feriasAppService.BuscarSolicitacoesDeFeriasDoDepartamentoDoUsuario(cpfDoServidor, anoDeExercicio);

            ViewData["AnoDeExercicio"] = anoDeExercicio;
            ViewData["PeriodoDePlanejamentoDeFerias"] = await feriasAppService.BuscarPeriodoDePlanejamentoDeFerias();
            return View(solicitacoes);
        }

        public async Task<IActionResult> Cadastrar(Guid solicitacaoId, string codigoUnidadeOrcamentaria)
        {

            var periodoDePlanejamento = await feriasAppService.BuscarPeriodoDePlanejamentoDeFerias();

            var cpfDoColaborador = userService.ObterCpf();

            CarregarViewBagDasMatriculasDoServidor();
            var podeSolicitarFerias = await feriasAppService.VerificarSePodeSolicitarFerias(cpfDoColaborador);

            if (!podeSolicitarFerias)
            {
                TempData["Erro"] = "Servidor já possui férias marcadas!";
                return RedirectToAction("Detalhes", "Servico", new { Id = solicitacaoId, codigoUnidadeOrcamentaria });
            }

            if (!periodoDePlanejamento.PodePlanejar)
            {
                TempData["Erro"] = "O planejamento de férias expirou!";
                return RedirectToAction("Detalhes", "Servico", new { Id = solicitacaoId, codigoUnidadeOrcamentaria });
            }

            return View();
        }


        public async Task<IActionResult> CadastrarDaMatricula(string matriculaDoColaborador)
        {
            CarregarViewBagDasMatriculasDoServidor(matriculaDoColaborador);

            var periodoDisponivelParaOServidorMarcarAsFerias = await feriasAppService.ObterPeriodoDisponivelParaOServidorMarcarAsFerias(matriculaDoColaborador, 0);

            ViewData["AtividadePrivativaDoCargoDeRaioXValido"] = false;

            var cargo = await apiServicos.ObterCargo(matriculaDoColaborador);

            if (ValidarCargo.DeProcurador(cargo))
            {
                var quantidadeDeSolicitacoes = await feriasAppService.ObterQuantidadeDeSolicitacaoesRealizadasParaOAnoEmExercicio(matriculaDoColaborador);
                ViewData["EhProcurador"] = true;
                ViewData["QuantidadeDeSolicitacoes"] = quantidadeDeSolicitacoes + 1;
            }
            else if (cargo.Contains("TÉCNICO EM RADIOLOGIA") || cargo.Contains("TÉCNICO EM RADIOTERAPIA"))
            {
                ViewData["AtividadePrivativaDoCargoDeRaioXValido"] = await feriasAppService.VerificarCargoDeTecnicoEmRadiologiaOuRadioterapia(matriculaDoColaborador);
            }
            else if (cargo.Contains("PROFESSOR CLASSE A") || cargo.Contains("PROFESSOR CLASSE B") || cargo.Contains("PROFESSOR CLASSE C"))
            {
                ViewData["AtividadePrivativaDoCargoDeProfessorComFeriasAutomaticas"] = await feriasAppService.VerificarCargoDoProfessorSePossuiFeriasAutomaticas(matriculaDoColaborador);
            }

            var anoAquisitivo = periodoDisponivelParaOServidorMarcarAsFerias.DataInicial.AddYears(-1).Year;

            ViewData["CargoDoServidor"] = cargo;
            ViewData["Matricula"] = matriculaDoColaborador;
            ViewData["AnoAquisitivo"] = anoAquisitivo;
            ViewData["DataInicial"] = periodoDisponivelParaOServidorMarcarAsFerias.DataInicial;
            ViewData["DataFinal"] = periodoDisponivelParaOServidorMarcarAsFerias.DataFinal;

            return View("CamposDoCadastroDeFerias");
        }

        public async Task<IActionResult> ServicoDeRemarcacaoDeFerias()
        {
            var cpfDoColaborador = userService.ObterCpf();
            var feriasViewModel = await feriasAppService.BuscarSolicitacoesDeFeriasViewModel(cpfDoColaborador);
            feriasViewModel.UnidadeOrcamentariaId = colaboradorAppService.ObterTodasAsUnidadesOrcamentariasDoColaborador(cpfDoColaborador).Result.FirstOrDefault();
            return View(feriasViewModel);
        }

        [HttpPost]
        public async Task<IActionResult> Cadastrar(string formaDoPeriodoDeFerias, List<PeriodoDeFeriasDto> dataInicialDeFerias, int anoAquisitivo, string matricula)
        {
            CarregarViewBagDasMatriculasDoServidor();

            var response = await feriasAppService.EnviarSolicitacaoDeFerias(formaDoPeriodoDeFerias, matricula, dataInicialDeFerias, anoAquisitivo);

            if (response.Success)
            {
                TempData["Sucesso"] = response.Message;
                return RedirectToAction("Solicitacoes", "Servico");
            }
            else
            {
                TempData["Erro"] = response.Message;
            }

            return RedirectToAction();
        }

        public async Task<IActionResult> Editar(int id, string codigoUnidadeOrcamentaria, string matriculaDoServidor)
        {

            var solicitacao = await feriasAppService.ObterSolicitacaoDeFerias(id, matriculaDoServidor);

            PeriodoDisponivelDTO periodoDisponivelParaOServidorMarcarAsFerias = null;

            if (solicitacao.Remarcacao)
            {
                periodoDisponivelParaOServidorMarcarAsFerias = await feriasAppService.ObterPeriodoDisponivelParaOServidorRemarcarAsFeriasPendentes();
            }
            else
            {
                periodoDisponivelParaOServidorMarcarAsFerias = await feriasAppService.ObterPeriodoDisponivelParaOServidorMarcarAsFerias(matriculaDoServidor, id);
            }

            ViewData["DataInicial"] = periodoDisponivelParaOServidorMarcarAsFerias.DataInicial;
            ViewData["DataFinal"] = periodoDisponivelParaOServidorMarcarAsFerias.DataFinal;
            ViewData["CodigoUnidadeOrcamentaria"] = codigoUnidadeOrcamentaria;

            return View(solicitacao);
        }

        [HttpPost]
        public async Task<IActionResult> Editar(int id, string formaDoPeriodoDeFerias, List<PeriodoDeFeriasDto> dataInicialDeFerias, int anoAquisitivo, bool remarcacao, int quantidadeDeDiasPendentes, string codigoUnidadeOrcamentaria, string matricula)
        {

            var response = await feriasAppService.EnviarSolicitacaoDeFerias(id, formaDoPeriodoDeFerias, matricula, dataInicialDeFerias, anoAquisitivo, remarcacao, quantidadeDeDiasPendentes);

            if (response.Success)
            {
                TempData["Sucesso"] = response.Message;
                return RedirectToAction("SolicitacaoDeServico", "Servico",
                    new { response.Id, codigoUnidadeOrcamentaria, origem = OrigemDaSolicitacao.SidSolicitacao });
            }
            else
            {
                TempData["Erro"] = response.Message;
            }

            return RedirectToAction("Solicitacoes", "Servico");
        }

        [HttpPost]
        public async Task<IActionResult> DarCienciaDeNotificacaoDeFerias(int id)
        {
            var response = await feriasAppService.DarCienciaDeNotificacaoDeFerias(id);

            if (response.Success)
            {
                return RedirectToAction(nameof(Index));
            }

            return RedirectToAction(nameof(Index));
        }

        public async Task<IActionResult> DetalhesDaSuspensao(int suspensaoId)
        {
            var suspensao = await feriasAppService.BuscarSolicitacaoDeSuspensaoDoColaboradorPorId(suspensaoId);

            return PartialView("_DetalhesDaSuspensao", suspensao);
        }

        public async Task<IActionResult> DetalhesDaInterrupcao(int interrupcaoId)
        {
            var interrupcao = await feriasAppService.BuscarSolicitacaoDeInterrupcaoDoColaboradorPorId(interrupcaoId);

            return PartialView("_DetalhesDaInterrupcao", interrupcao);
        }

        public async Task<IActionResult> DarCienciaNaSuspensao(int id, string codigoUnidadeOrcamentaria, int solicitacaoDeferiasId)
        {
            var response = await feriasAppService.DarCienciaNaSuspensao(id);

            if (response.Success)
            {
                TempData["Sucesso"] = response.Message;
            }
            else
            {
                TempData["Erro"] = response.Message;
            }

            return RedirectToAction("SolicitacaoDeServico", "Servico",
                     new { id = solicitacaoDeferiasId, codigoUnidadeOrcamentaria, origem = OrigemDaSolicitacao.SidSolicitacao });
        }

        public async Task<IActionResult> DarCienciaNaInterrupcao(int id, string codigoUnidadeOrcamentaria, int solicitacaoDeferiasId)
        {
            var response = await feriasAppService.DarCienciaNaInterrupcao(id);

            if (response.Success)
            {
                TempData["Sucesso"] = response.Message;
            }
            else
            {
                TempData["Erro"] = response.Message;
            }
            return RedirectToAction("SolicitacaoDeServico", "Servico",
                    new { id = solicitacaoDeferiasId, codigoUnidadeOrcamentaria, origem = OrigemDaSolicitacao.SidSolicitacao });
        }

        public async Task<IActionResult> SolicitarRemarcacaoDeFerias(int solicitacaoId, string codigoUnidadeOrcamentaria)
        {
            var motivosDaRemarcacaoDeFerias = await feriasAppService.BuscarOsMotivosDaRemarcacaoDeFerias();
            ViewBag.Motivos = new SelectList(motivosDaRemarcacaoDeFerias, "Descricao", "Descricao");
            ViewData["SolicitacaoId"] = solicitacaoId;
            ViewData["CodigoUnidadeOrcamentaria"] = codigoUnidadeOrcamentaria;
            return View();
        }

        public async Task<IActionResult> SolicitarRemarcacaoDeFeriasInrrompidas(int solicitacaoId, string codigoUnidadeOrcamentaria)
        {
            var periodosDisponiveis = await feriasAppService.ObterPeriodosDeFeriasDisponiveisParaRemarcar(solicitacaoId);


            ViewData["SolicitacaoId"] = solicitacaoId;

            ViewData["CodigoUnidadeOrcamentaria"] = codigoUnidadeOrcamentaria;


            ViewData["DataInicial"] = DateTime.Now.AddDays(1);
            ViewData["DataFinal"] = new DateTime(DateTime.Now.Year, 12, 31);

            ViewData["CodigoUnidadeOrcamentaria"] = codigoUnidadeOrcamentaria;

            return View(periodosDisponiveis);
        }
        [HttpPost]
        public async Task<IActionResult> RemarcarFeriasInterrompidas(ReceberDadosDaRemarcacao receberDadosDaRemarcacao)
        {
            receberDadosDaRemarcacao.EhRemarcacaoDeInterrupcao = true;
            var response = await feriasAppService.EnviarSolicitacaoDeRemarcacaoDeFerias(receberDadosDaRemarcacao);
            if (response.Success)
            {
                TempData["Sucesso"] = response.Message;
                return RedirectToAction("SolicitacaoDeServico", "Servico",
                    new { Id = receberDadosDaRemarcacao.SolicitacaoDeFeriasId, codigoUnidadeOrcamentaria = receberDadosDaRemarcacao.CodigoUnidadeOrcamentaria, origem = OrigemDaSolicitacao.SidSolicitacao });
            }
            else
            {
                TempData["Erro"] = response.Message;
                return RedirectToAction(nameof(RemarcarFerias), new { solicitacaoId = receberDadosDaRemarcacao.SolicitacaoDeFeriasId, codigoUnidadeOrcamentaria = receberDadosDaRemarcacao.CodigoUnidadeOrcamentaria, motivo = receberDadosDaRemarcacao.Motivo });
            }
        }

        public async Task<IActionResult> RemarcarFerias(int solicitacaoId, string codigoUnidadeOrcamentaria, string motivo)
        {
            var periodosDisponiveis = await feriasAppService.ObterPeriodosDeFeriasDisponiveisParaRemarcar(solicitacaoId);

            var motivosDaRemarcacaoDeFerias = await feriasAppService.BuscarOsMotivosDaRemarcacaoDeFerias();

            ViewBag.Motivos = new SelectList(motivosDaRemarcacaoDeFerias, "Descricao", "Descricao", motivo);

            var periodoDisponivelParaOServidorMarcarAsFerias = await feriasAppService.ObterPeriodoDisponivelParaOServidorRemarcarAsFerias(solicitacaoId, motivo);
            var ehRemacarcacaoDeVinteMaisDezDias = VerficarSeEhRemarcacaoDeVinteMaisDezDias(periodosDisponiveis.FormaDoPeriodoDeFerias, periodosDisponiveis, motivo);

            if (ehRemacarcacaoDeVinteMaisDezDias && (periodosDisponiveis.PeriodosDeFerias[0].TipoDoPeriodoDeFerias.Equals("DezDias") && !periodosDisponiveis.PeriodosDeFerias[0].PodeRemarcar))
            {
                ViewData["GozouDezDias"] = true;
            }
            ViewData["SolicitacaoId"] = solicitacaoId;
            ViewData["EhRemarcacaoDeVinteMaisDezDias"] = ehRemacarcacaoDeVinteMaisDezDias;
            ViewData["CodigoUnidadeOrcamentaria"] = codigoUnidadeOrcamentaria;
            ViewData["AbonoGozado"] = periodosDisponiveis.VerificarSeJaGozouDoAbono();
            ViewData["Motivo"] = motivo;
            ViewData["DataInicial"] = periodoDisponivelParaOServidorMarcarAsFerias.DataInicial;
            ViewData["DataFinal"] = periodoDisponivelParaOServidorMarcarAsFerias.DataFinal;
            var jaVeioComAbonoQueNaoPodeRemarcar = periodosDisponiveis.PeriodosDeFerias.Any(x => x.TipoDoPeriodoDeFerias.Equals("Abono") && !x.PodeRemarcar);
            ViewData["JaTemAbonoENaoPodeRemarcar"] = jaVeioComAbonoQueNaoPodeRemarcar;
            return View(periodosDisponiveis);
        }

        [HttpPost]
        public async Task<IActionResult> RemarcarFerias(ReceberDadosDaRemarcacao receberDadosDaRemarcacao, string jatemAbono)
        {
            if (receberDadosDaRemarcacao.Motivo.ToUpper() != "SEM MOTIVO" && string.IsNullOrEmpty(receberDadosDaRemarcacao.NumeroDoProcessoSei))
                return MensagemErro("Por favor, informe o numero do processo do SEI.");

            if (ValidarDados())
            {
                var response = await feriasAppService.EnviarSolicitacaoDeRemarcacaoDeFerias(receberDadosDaRemarcacao);

                if (response.Success)
                    return MensagemSucesso(response.Message);
                else
                    return MensagemErro(response.Message);
            }

            return MensagemErro("A Data do abono não pode ser menor que 60 dias, contando a partir de hoje");

            bool ValidarDados()
            {
                var podeProceguir = true;
                var temAbonoNoPlanejamentoAnual = !string.IsNullOrEmpty(jatemAbono) && jatemAbono.Equals("jaTemAbono");
                if (receberDadosDaRemarcacao.DataInicialDeFerias.Any(x => x.TipoDoPeriodoDeFerias.Equals("Abono")) && !temAbonoNoPlanejamentoAnual)
                {
                    var dataModelo = DateTime.Now.AddDays(60).Date;
                    var periodoDeAbono = receberDadosDaRemarcacao.DataInicialDeFerias.FirstOrDefault(x => x.TipoDoPeriodoDeFerias.Equals("Abono"));
                    podeProceguir = periodoDeAbono.DataInicial.Date >= dataModelo;
                }

                return podeProceguir;
            }

            IActionResult MensagemSucesso(string mensagem) 
            {
                TempData["Sucesso"] = mensagem;
                return RedirectToAction("SolicitacaoDeServico", "Servico", new
                {
                    Id = receberDadosDaRemarcacao.SolicitacaoDeFeriasId,
                    codigoUnidadeOrcamentaria = receberDadosDaRemarcacao.CodigoUnidadeOrcamentaria,
                    origem = OrigemDaSolicitacao.SidSolicitacao
                });
            }

            IActionResult MensagemErro(string mensagem)
            {
                TempData["Erro"] = mensagem;
                return RedirectToAction(nameof(RemarcarFerias), new
                {
                    solicitacaoId = receberDadosDaRemarcacao.SolicitacaoDeFeriasId,
                    codigoUnidadeOrcamentaria = receberDadosDaRemarcacao.CodigoUnidadeOrcamentaria,
                    motivo = receberDadosDaRemarcacao.Motivo
                });
            }
        }

        public IActionResult ObterPartialDaformaDoPeriodoDeFerias(string idSolicitacao, string formaDoPeriodoDeFerias, string motivo)
        {
            var periodosDisponiveis = feriasAppService.ObterPeriodosDeFeriasDisponiveisParaRemarcar(int.Parse(idSolicitacao)).Result;

            if (VerficarSeEhRemarcacaoDeVinteMaisDezDias(formaDoPeriodoDeFerias, periodosDisponiveis, motivo))
            {
                if (formaDoPeriodoDeFerias.Equals("TresDeDezDias"))
                {
                    if (!string.IsNullOrEmpty(motivo) && !motivo.Equals("SEM MOTIVO"))
                    {
                        formaDoPeriodoDeFerias = "TresDeDezDiasComMotivo";
                    }
                    else
                    {
                        formaDoPeriodoDeFerias = "TresDeDezDias";
                    }
                    periodosDisponiveis.FormaDoPeriodoDeFerias = "TresDeDezDias";
                }
                if (formaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEDezDiasDeAbono"))
                {
                    formaDoPeriodoDeFerias = "UmaDeVinteDiasEDezDiasDeAbono";
                    periodosDisponiveis.FormaDoPeriodoDeFerias = "UmaDeVinteDiasEDezDiasDeAbono";
                }
                if (formaDoPeriodoDeFerias.Equals("DoisDeDezDiasEUmAbonoDeDezDias"))
                {
                    formaDoPeriodoDeFerias = "DoisDeDezDiasEUmAbonoDeDezDias";
                    periodosDisponiveis.FormaDoPeriodoDeFerias = "DoisDeDezDiasEUmAbonoDeDezDias";
                }
                if (formaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias"))
                {
                    formaDoPeriodoDeFerias = "UmaDeVinteDiasEOutraDezDias";
                    periodosDisponiveis.FormaDoPeriodoDeFerias = "UmaDeVinteDiasEOutraDezDias";
                }
                ViewData["RemacarcaoVinteDias"] = true;
                ViewData["AbonoGozado"] = periodosDisponiveis.VerificarSeJaGozouDoAbono();
                return PartialView($"_{formaDoPeriodoDeFerias}", periodosDisponiveis);
            }
            if (VerificarSeEhRemarcacaoTresDeDezDias(periodosDisponiveis))
            {
                ViewData["RemacarcaoTresDeDezDias"] = true;
                ViewData["RemacarcaoVinteDias"] = false;
                ViewData["AbonoGozado"] = periodosDisponiveis.VerificarSeJaGozouDoAbono();
                return PartialView($"_{formaDoPeriodoDeFerias}", periodosDisponiveis);
            }
            if ((!string.IsNullOrEmpty(motivo) && !motivo.Equals("SEM MOTIVO")) && (periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias") && periodosDisponiveis.PeriodosDeFerias.Count(x => !x.PodeRemarcar) == 1))
            {
                if (!periodosDisponiveis.PodeConverterEmAbonoEhRemarcarDezDias())
                {
                    formaDoPeriodoDeFerias = "DoisDeDezDiasEDezDiasDeAbonoComMotivo";
                    return PartialView($"_{formaDoPeriodoDeFerias}", periodosDisponiveis);
                }
            }
            if ((!string.IsNullOrEmpty(motivo) && !motivo.Equals("SEM MOTIVO")) && (periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEDezDiasDeAbono") && periodosDisponiveis.PeriodosDeFerias.Any(x => !x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("Abono"))))
            {
                ViewData["JaGozouOuNaoPodeRemarcarOAbono"] = true;
                formaDoPeriodoDeFerias = "DoisDeDezDiasEDezDiasDeAbonoComMotivo";
                return PartialView($"_{formaDoPeriodoDeFerias}", periodosDisponiveis);
            }

            ViewData["RemacarcaoTresDeDezDias"] = false;
            ViewData["AbonoGozado"] = periodosDisponiveis.VerificarSeJaGozouDoAbono();
            ViewBag.SelecioneiOpcaoComAbono = true;
            ViewData["DataInicialParaAbonoComMotivo"] = DateTime.Now.AddDays(59);

            return PartialView($"_{formaDoPeriodoDeFerias}");
        }

        private bool VerificarSeEhRemarcacaoTresDeDezDias(RemarcarFeriasViewModel periodosDisponiveis)
        {
            if (periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("TresDeDezDias") || periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("DoisDeDezDiasEUmAbonoDeDezDias"))
            {
                if ((periodosDisponiveis.PeriodosDeFerias[0].TipoDoPeriodoDeFerias == "DezDias" && periodosDisponiveis.PeriodosDeFerias[1].TipoDoPeriodoDeFerias == "DezDias" && periodosDisponiveis.PeriodosDeFerias[2].TipoDoPeriodoDeFerias == "DezDias") && periodosDisponiveis.PeriodosDeFerias.Count(x => x.PodeRemarcar) <= 2)
                {
                    return true;
                }
                if (periodosDisponiveis.VerificarSeJaGozouDoAbono())
                {
                    return true;
                }
                return false;
            }
            return false;
        }

        private bool VerficarSeEhRemarcacaoDeVinteMaisDezDias(string formaDoPeriodoDeFerias, RemarcarFeriasViewModel periodosDisponiveis, string motivo)
        {
            if (formaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias") && periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias"))
            {
                if (periodosDisponiveis.PeriodosDeFerias[0].PodeRemarcar && periodosDisponiveis.PeriodosDeFerias[1].PodeRemarcar)
                {
                    return false;
                }
                return true;
            }
            else if (formaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEDezDiasDeAbono"))
            {
                return periodosDisponiveis.PeriodosDeFerias.Any(x => (!x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("Abono")) || (x.TipoDoPeriodoDeFerias.Equals("VinteDias") && !x.PodeRemarcar));
            }
            else if (formaDoPeriodoDeFerias.Equals("DoisDeDezDiasEUmAbonoDeDezDias"))
            {
                if ((periodosDisponiveis.PeriodosDeFerias.Count(x => !x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("Abono")) == 1) &&
                    (periodosDisponiveis.PeriodosDeFerias.Count(x => x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("DezDias")) == 2))
                {
                    return true;
                }
                if (periodosDisponiveis.PeriodosDeFerias.Count(x => !x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("Abono")) == 1 && periodosDisponiveis.PeriodosDeFerias.Count(x => x.PodeRemarcar && x.TipoDoPeriodoDeFerias.Equals("VinteDias")) == 1)
                {
                    return true;
                }
                else if (periodosDisponiveis.PeriodosDeFerias.Any(x => (x.TipoDoPeriodoDeFerias.Equals("DezDias") && !x.PodeRemarcar)))
                {
                    if (periodosDisponiveis.PeriodosDeFerias.Any(x => x.TipoDoPeriodoDeFerias.Equals("VinteDias") && x.PodeRemarcar))
                    {
                        return true;
                    }

                }
                return false;
            }
            if (formaDoPeriodoDeFerias.Equals("TresDeDezDias") && periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("TresDeDezDias"))
            {
                if (periodosDisponiveis.PeriodosDeFerias[0].PodeRemarcar && periodosDisponiveis.PeriodosDeFerias[1].PodeRemarcar && periodosDisponiveis.PeriodosDeFerias[2].PodeRemarcar)
                {
                    return false;
                }
                return true;
            }
            if (formaDoPeriodoDeFerias.Equals("TresDeDezDias") && periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias"))
            {
                if (periodosDisponiveis.PeriodosDeFerias.Any(x => x.TipoDoPeriodoDeFerias.Equals("VinteDias") && x.PodeRemarcar))
                {
                    return true;
                }
                return false;
            }
            if (formaDoPeriodoDeFerias.Equals("DoisDeQuinzeDias") && periodosDisponiveis.FormaDoPeriodoDeFerias.Equals("DoisDeQuinzeDias"))
            {
                if (periodosDisponiveis.PeriodosDeFerias.Count(x => x.PodeRemarcar) == 2)
                {
                    return false;
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public async Task<IActionResult> FeriasPendentes()
        {
            
            var cpfDoColaborador = userService.ObterCpf();
            var nomeDoColaborador = userService.ObterNome();

            ViewData["Colaborador"] = nomeDoColaborador;

            var feriasPendentes = await feriasAppService.BuscarFeriasPendentesDoServidor(cpfDoColaborador);

            return View(feriasPendentes);
        }

        public async Task<IActionResult> ObterSolicitacaoComPeriodosDeFeriasDoServidorParaSuspensao(int solicitacaoId)
        {
            var solicitacao = await feriasAppService.BuscarSolicitacaoPorIdParaSuspensao(solicitacaoId);
            return Json(solicitacao);
        }

        [HttpPost]
        public async Task<IActionResult> SolicitarSuspensaoDePeriodosDeFeriasDoServidor(SolicitacaoDeParalisacaoDeFeriasDto solicitacao)
        {
            var resposta = await feriasAppService.SolicitarSuspensaoDePeriodoDeFerias(solicitacao);

            if (resposta.Success)
                TempData["Sucesso"] = resposta.Message;
            else
                TempData["Erro"] = resposta.Message;

            return RedirectToAction("Solicitacoes", "Servico");
        }

        public void CarregarViewBagDasMatriculasDoServidor(string matricula = null)
        {
            var pisPasep = userService.ObterPis();
            var matriculasDoColaborador = apiServicos.ObterMovimentacaoDoServidorDtoPisPasep(pisPasep).Result;
            bool matriculaPodeSolicitarFerias = false;

            var listaDeMatriculas = matriculasDoColaborador.Select(x => new { matricula = x.matricula, descricao = string.Format("{0} | {1}", x.matricula, x.nomeDoDepartamento) });
            if (matricula == null)
                ViewBag.Matriculas = new SelectList(listaDeMatriculas, "matricula", "descricao");
            else
            {
                ViewBag.Matriculas = new SelectList(listaDeMatriculas, "matricula", "descricao", matricula);
                matriculaPodeSolicitarFerias = apiServicos.VerificarSeOServidorPodeSolicitarFerias(matricula).Result;
                ViewBag.MatriculaPodeSolicitarFerias = matriculaPodeSolicitarFerias;
            }
        }
        public IActionResult ObterPartialDoPeriodoDeTempoParaMarcacaoDeFerias(string formaDoPeriodoDeFerias)
        {
            if (formaDoPeriodoDeFerias.Equals("UmaDeVinteDiasEOutraDezDias"))
            {
                ViewData["RemacarcaoVinteDias"] = false;
                ViewData["RemacarcaoTresDeDezDias"] = false;
            }

            return PartialView($"_{formaDoPeriodoDeFerias}");
        }
    }

}

Atualmente existem várias regras que estão no Portal do Servidor e que algumas até falham fazendo com que os dados do banco de dados não possua consistência, vejamos um trecho de código a seguir do Portal do Servidor:

 

3 - Possíveis problemas


 

4 - Valor agregado


5 - Conclusão do estudo

 

O presente ESTUDO TÉCNICO PRELIMINAR, elaborado pelos integrantes TÉCNICOS do time TITÃS, considerando a análise dos desafios técnicos envolvidos e citados, conclui pela VIABILIDADE DA IMPLEMENTAÇÃO DA NOTIFICAÇÃO DE MODO CRITERIOSO, uma vez que foram considerados os potenciais benefícios em termos de eficiência e também os problemas envolvidos, principalmente potenciais problemas de desempenho da aplicação. Em complemento, os contratempos identificados são administráveis, pelo que RECOMENDAMOS o prosseguimento da demanda. Ressalva-se que o ideal é que a periodicidade de envio dos e-mails seja no máximo diária, para esta atividade recomenda-se a construção de um Job que faça o envio no período desejado.