Ir para o conteúdo principal

Funcionalidades descontinuadas do SID no Portal do Servidor

Data de elaboração

 11/05/2022

Responsável pelo estudo

João Pedro Rocha Brito (Assessor)

José Henrique dos Santos Nogueira (Assessor)


Equipe do estudo

João Pedro Rocha Brito (Assessor)

José Henrique dos Santos Nogueira (Assessor)

José Lucas da Silva Costa (Analista de Desenvolvimento Full-Stack)

Jônatas Neves Legal (Técnico emTecnologia da Informação e Comunicação) 

Alvo Sistema Integrado de Descanso.
Origem

Melhoria: Funcionalidades descontinuadas do SID no Portal do Servidor.

Objetivo

Revisar as funcionalidades do SID dentro do Portal do Servidor para verificar se existem funções descontinuadas.
Documentação Correlata Sem documentação correlata.

Observações

Sem observações.

1. Glossário de Termos


  1. API Application Programming Interface (interface de Programação de Aplicações).
  2. SETIC - Superintendência Estadual de Tecnologia da Informação e Comunicação.
  3. SID - Sistema Integrado de Descanso.

2. Introdução


 

O SID (Sistema Integrado de Descanso) é responsável pelo controle de férias dos servidores do poder executivo do Estado De Rondônia.  O fluxo principal deste sistema funciona basicamente todos os anos no mês de setembro, onde todos os servidores devem indicar suas preferências de período de férias para o ano subsequente. Acontece que o Portal do Servidor que é um sistema que integra ao SID, provavelmente possui funcionalidades que já foram descontinuadas dentro da API do SID. O time Titãs assumiu a responsabilidade das manutenções referente ao SID e vem fazendo correções de extrema importância para que não aconteçam imprevistos durante seu uso. O objetivo deste estudo é realizar uma revisão nas funcionalidades do SID dentro do Portal do Servidor para verificar se existem funções descontinuadas.

3. Desenvolvimento


 

Para que este estudo seja possível, inicialmente é necessário avaliar o fluxo básico das solicitações no Portal do Servidor que são gerenciadas pela API do SID, vejamos o fluxo para remarcação de férias por exemplo, ao acessar o Portal do Servidor podemos observar a função de acompanhamento das solicitações de férias.

image-1652245283951.png

Fonte: Documentação de Remarcação de Férias


Ao abrir uma solicitação, temos acesso a tela a seguir que é possível realizar a remarcação de férias do servidor solicitante:

image-1652245462987.png

Fonte: Documentação de Remarcação de Férias


Quando na tela após a consulta de períodos disponíveis a visão do colaborador será a seguinte:

image-1652245553050.png

Fonte: Documentação de Remarcação de Férias


Nesta tela ele irá conseguir finalizar a sua solicitação e confirmar todas as alterações na ilustração a seguir:

image-1652245612271.png

Fonte: Documentação de Remarcação de Férias


Se formos analisar toda a codificação por trás dessas requisições fica um pouco mais complexo de se analisar trechos de códigos que não mais utilizados, mas veremos a seguir a codificação da camada controladora principal do Portal do Servidor referente as férias:

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.AddYears(1).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}");
        }
    }

}

Fonte: Código Fonte do Portal do Servidor (Área de Férias)

A principal complexidade atualmente deste código é que as regras que deveriam ser de responsabilidade da API do SID são do Portal do Servidor. O que está totalmente incorreto e trouxe dificuldades como trechos de códigos descontinuados devido a regra está codificada no local errado. O ideal seria a separação correta das responsabilidades.

Podemos afirmar que a API do SID é o local onde as regras de negócio são centralizadas, conceitua-se por regras de negócios a definição que descrevem as operações, definições e restrições que se aplicam a uma organização para atingir seus objetivos. 

Realizando essa separação fica possível usar um nível mais alto de abstração, que está bem alinhado com o domínio do problema e define o que implementar, em vez de como fazê-lo. Isso normalmente leva um tempo de desenvolvimento mais curto e manutenção menos custosas. 

A flexibilidade e a modificabilidade das implementações de regras de negócio são alcançadas através do suporte de manutenção de regras e da sua separação correta, permitindo mudanças dinâmicas. Essa capacidade fornece uma maneira conveniente de modificar dinamicamente as regras de negócios sem reconstruir e reimplantar o mesmo código na camada errada.

Por conclusão, o que se observa na verdade é que o problema do Portal do Servidor é a contenção de regras do SID que não deveria está lá, o Portal do Servidor em sua essência é apenas um meio de fornecer serviços, não deveria laborar nenhum tipo de serviço e sim apenas entregar de sua fonte.

3.1. Possíveis problemas

O problema de tentar achar trechos de códigos não utilizados é o risco de removê-los por equívoco, por exemplo, após uma análise de algum desenvolvedor, considera-se prudente remover um código que possivelmente não é utilizado, mas se for feita de maneira equivocada o SID irá parar de funcionar em alguma ocasião específica. 

3.2. Valor agregado

A remoção de trechos de código de funcionalidades descontinuadas poderá gerar uma facilidade na manutenção do sistema como um todo, do ponto de vista técnico muito provavelmente reduza até mesmo a quantidade bugs, pois o desenvolvedor irá ter uma visão mais limpa da camada de negócio

4. Conclusão


 

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 RETIRADA DAS REGRAS DO FÉRIAS DO PORTAL DO SERVIDOR PARA QUE SEJAM TRANSFERIDAS PARA A API DO SID, o que vai permitir que naturalmente os códigos não utilizados sejam descartados pelo programadores. Uma vez que foram considerados potenciais problemas que afetem a disponibilidade do serviço. Em complemento, os contratempos identificados são administráveis, pelo que RECOMENDAMOS o prosseguimento da demanda.