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

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:

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:

Se reparmos a linha 107, é possivel observar que existem validações de cargos com férias especiais, tais regras deveriam está no SID e não no Portal do Servidor. Outra regra que está sendo implementada pelo Portal do servidor começa pela linha 390, que é me verificação de formas de períodos e também de quando a solicitação é sem motivo ou com motivo.

3 - Possíveis problemas

Atualmente o time Titãs vem recebendo diversos chamados de inconsistências causadas pelas regras que falharam no Portal do Servidor, o caso mais recente envolve um colaborador, que conseguiu marcar as férias, cujo um dos períodos do tipo abono possuía 30 dias de férias. Uma falha bem grave já que ainda envolve uma informação para pagamento para servidores que vendem suas férias. Existem também outros tipos de problemas que foram relatados, como por exemplo: Solicitações com períodos incompletos ou informações importantes ausentes na solicitação.

 

 

4 - Valor agregado


A migração das regras do Portal do Servidor trará uma série de benefícios, dentre elas, facilidade de manunteção para a equipe, redução no número de chamados já que as regras no Portal do Servidor não serão mas soberanas e também trará uma melhor experiência para o usuário final.

 

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.