Ir para o conteúdo principal

[ETP] Avaliação técnica das regras de remarcação de férias no SID

ESTUDO TÉCNICO PRELIMINAR - ETP

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

1 - INTRODUÇÃO

O time Titãs realiza as manutenções de diversos sistemas, sendo que o que mais demanda manutenção é o SID. Devido as crescentes alterações do sistema, faz-se necessário realizar um estudo técnico acerca das novas regras de remarcação das férias recém implementadas. Portando, serão expostos neste estudo os aspectos positivos e negativos das atuais regras demandadas.

 

2 - O QUE É NECESSÁRIO PARA ATENDER A NECESSIDADE

O manual explicativo já existente https://documentos.sistemas.ro.gov.br/books/sid-sistema-integrado-de-descanso/page/solicitacao-de-remarcacao-das-ferias detalha de forma minuciosa as regras referente a remarcação, este estudo busca complementar o manual de forma mais técnica, para fins de elucidação de dúvidas mais específicas. Para solução da lide, será necessário realizar revisões nos códigos referente as regras de remarcação e apresentar todos os cenários abordados de diferentes formas, para fins de elucidação dos mesmos diagramas abordados no manual.

 

3 - COMPLEXIDADES DE IMPLEMENTAÇÃO

A elaboração deste estudo busca a revisão de código das regras de remarcação. As revisões de código permitem evitar bugs, garante a conformidade e confirma que o aplicativo está atendendo às especificações antes que o projeto seja concluído quando essas alterações seriam mais caras. Ainda assim, é difícil ver além do tempo que leva para realizá-los. 

Uma das análises iniciais a se fazer é a verificação do período em gozo, vejamos:

 private bool VerificarSePeriodoEstaEmGozoOuSeFoiGozado(Solicitacao solicitacaoASerRemarcada, PeriodoOrdem periodoOrdem)
{
	return solicitacaoASerRemarcada.PeriodosDeFerias[(int)periodoOrdem].PeriodoEstaEmGozoOuJaFoiGozado;
}

Basicamente este é um método basilar que através do parâmetros o compilador poderá identificar se determinado período já está em gozo, isso será de grande utilidade pois quando o servidor solicitar uma remarcação, períodos que já estão em gozo não poderão ser alterados.

Já a verificação da forma de período modificada é uma validação que possibilita a conversão da formas nas solicitações de remarcação, por exemplo o servidor poderá solicitar uma remarcação mediante saldo de férias disponível e válido para conversão quando for o caso. O código a seguir detalha tecnicamente melhor o método:

private bool VerificarSeFormaDePeriodoFoiAlterada(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	var formaDePeriodoDaSolicitacaoOriginal = solicitacaoASerRemarcada.FormaDoPeriodoDeFerias.ToString();
	var formaDePeriodoDaSolicitacaoDeRemarcacao = solicitacaoDeRemarcacao.FormaDoPeriodoDeFerias;
	var formasDePeriodosEstaoIguais = formaDePeriodoDaSolicitacaoOriginal == formaDePeriodoDaSolicitacaoDeRemarcacao;
	return !formasDePeriodosEstaoIguais;
}

Outra verificação importante nos fluxos de remarcação de férias é validar se os períodos de férias atuais já foram todos gozados, nesse caso o servidor não poderá solicitar uma remarcação, deste modo o código a seguir faz essa barreira de entrada:

private bool JaGozouTodosOsPeriodos(Solicitacao solicitacaoASerRemarcada)
{
	if (solicitacaoASerRemarcada.PeriodosDeFerias.All(x => x.PeriodoEstaEmGozoOuJaFoiGozado))
		return true;
	else
		return false;
}

A questão de antecedência de 60 dias para remarcação é uma regra que gerou certa confusão no time de desenvolvimento, a questão financeira envolvida é a seguinte, o servidor fará jus ao pagamento de 1/3 de suas férias um mês antes de sua marcação ou remarcação de férias e também fará jus ao pagamento de abono se for o caso um mês antes de sua marcação. Vejamos sua implementação:

private bool SolicitacaoPossuiAntecedenciaDeSessentaDias(Solicitacao solicitacaoASerRemarcada)
{
	if (!solicitacaoASerRemarcada.Remarcacao)
		return true;

	var dataMinima = solicitacaoASerRemarcada.DataRegistro.AddDays(60);

	var dataHoje = dateTimeProvider.Now();

	if (dataHoje.Date >= dataMinima.Date)
		return true;
	else
	return false;
}

Do ponto de vista mais específicos o primeiro cenário a ser revisado é as regras dos 30 dias, vejamos o código:

private bool RegraTrintaDias(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	bool ExecutarRegras()
	{
		if (JaGozouTodosOsPeriodos(solicitacaoASerRemarcada))
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());
		else
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);
	}
	return ExecutarRegras();
}

Agora, vejamos a regra dos 15+15 dias:

private bool RegraQuinzeMaisQuinzeDias(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	bool ExecutarRegras()
	{
		var gozouPrimeiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Primeiro);
		var gozouSegundoPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Segundo);
		var gozouTodosOsPeriodos = JaGozouTodosOsPeriodos(solicitacaoASerRemarcada);

		if (gozouTodosOsPeriodos)
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());

		if (!gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);

		if (gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Primeiro);
		else
			return false;
	}
	return ExecutarRegras();
}

A seguir também será abordada a regra de 20+10 dias:

private bool RegraVinteMaisDezDias(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	bool ExecutarRegras()
	{
		var gozouPrimeiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Primeiro);
		var gozouSegundoPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Segundo);

		if (!gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);

		if (gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Primeiro);

		if (!gozouPrimeiroPeriodo && gozouSegundoPeriodo)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Segundo);
		else
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());
	}
	return ExecutarRegras();
}

O método da regra de 20+10 dias de abono já um pouco mais específico devido a regra do abono, observamos:

private bool RegraVinteMaisDezDiasDeAbono(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	bool ExecutarRegras()
	{
		var gozouPrimeiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Primeiro);
		var gozouSegundoPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Segundo);

		if (!gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);

		if (gozouPrimeiroPeriodo && !gozouSegundoPeriodo)
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());

		if (!gozouPrimeiroPeriodo && gozouSegundoPeriodo)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Segundo);
		else
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());
	}

	return ExecutarRegras();
}

Já a regra de 10+10+10 dias aborda uma cenário de validação mais complexo:

private bool RegraDezMaisDezMaisDez(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	bool ExecutarRegras()
	{
		var gozouPrimeiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Primeiro);
		var gozouSegundoPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Segundo);
		var gozouTerceiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Terceiro);

		if (!gozouPrimeiroPeriodo && !gozouSegundoPeriodo && !gozouTerceiroPeriodo)
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);

		if (gozouPrimeiroPeriodo && gozouSegundoPeriodo && gozouTerceiroPeriodo)
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());

		if (gozouPrimeiroPeriodo && !gozouSegundoPeriodo && !gozouTerceiroPeriodo)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Primeiro);
		else
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Segundo);
	}

	return ExecutarRegras();
}

Por fim, temos a regra 10+10+10 dias de abono que aborda várias verificações no períodos e cenários de extensão para falhas:

private bool RegraDezMaisDezMaisAbono(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{          
	bool ExecutarRegras()
	{
		var gozouPrimeiroPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Primeiro);
		var gozouSegundoPeriodo = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Segundo);
		var gozouTerceiroPeriodoComAbono = VerificarSePeriodoEstaEmGozoOuSeFoiGozado(solicitacaoASerRemarcada, PeriodoOrdem.Terceiro);

		if (!gozouPrimeiroPeriodo && !gozouSegundoPeriodo && !gozouTerceiroPeriodoComAbono)
			return NaoIniciouGozoDasFerias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao);

		if (gozouPrimeiroPeriodo && gozouSegundoPeriodo && gozouTerceiroPeriodoComAbono)
			return GerarFalha((new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber());

		if (gozouPrimeiroPeriodo && !gozouSegundoPeriodo && !gozouTerceiroPeriodoComAbono)
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Primeiro);
		else
			return IniciouGozoDoPeriodo(solicitacaoASerRemarcada, solicitacaoDeRemarcacao, PeriodoOrdem.Segundo);
	}
	return ExecutarRegras();
}

 

4 - POSSÍVEIS PROBLEMAS

Para validação das regras já citadas, é necessário uma fluxo de demanda que encaminhe as regras para o cenário correto, vejamos:

public (bool validado, string retorno) ExecutarRegrasDeRemarcaoDaSolicitacao(Solicitacao solicitacaoASerRemarcada, SolicitacaoDeRemarcacaoDeFeriasDto solicitacaoDeRemarcacao)
{
	switch (solicitacaoASerRemarcada.FormaDoPeriodoDeFerias)
	{
		case FormaDoPeriodoDeFerias.UmaDeTrintaDias:
			return (RegraTrintaDias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.UmaDeTrintaDias}");

		case FormaDoPeriodoDeFerias.DoisDeQuinzeDias:
			return (RegraQuinzeMaisQuinzeDias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.DoisDeQuinzeDias}");

		case FormaDoPeriodoDeFerias.TresDeDezDias:
			return (RegraDezMaisDezMaisDez(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.TresDeDezDias}");

		case FormaDoPeriodoDeFerias.UmaDeVinteDiasEOutraDezDias:
			return (RegraVinteMaisDezDias(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.UmaDeVinteDiasEOutraDezDias}");

		case FormaDoPeriodoDeFerias.UmaDeVinteDiasEDezDiasDeAbono:
			return (RegraVinteMaisDezDiasDeAbono(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.UmaDeVinteDiasEDezDiasDeAbono}");

		case FormaDoPeriodoDeFerias.DoisDeDezDiasEUmAbonoDeDezDias:
			return (RegraDezMaisDezMaisAbono(solicitacaoASerRemarcada, solicitacaoDeRemarcacao), $"{FormaDoPeriodoDeFerias.DoisDeDezDiasEUmAbonoDeDezDias}");

		default:
			return (true, string.Empty);
	}
}

Os problemas que podem acontecer é a falta de revisão dessas regras, pois em uma cenário de várias mudanças, infelizmente pode ocorrer alterações

 

5 - VALOR AGREGADO

Os desenvolvedores colocam todo o seu poder na criação do melhor produto de software, mantendo os problemas e as preferências dos usuários em mente. Mas uma coisa importante que muitas vezes é esquecida é a documentação das funcionalidades mais importantes, a exemplo no caso, as regras de remarcação do SID. Não importa a quantidade de trabalho duro na codificação, se o software não vier com um documento, é altamente provável que os usuários eventualmente não tenham uma boa experiência. A documentação de software é uma parte crítica do desenvolvimento de software que não deve ser perdida a qualquer custo. 

 

6 - 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 VALIDAÇÃO DAS REGRAS DE REMARCAÇÃO ATUAIS, uma vez que foram considerados a análise técnica do código envolvido, principalmente potenciais problemas que afetem a disponibilidade do serviço. Em complemento, os contratempos identificados são administráveis, pelo que RECOMENDAMOS A REVISÃO CONSTANTE DAS REGRAS, uma vez que, o projeto está suscetível a mudanças solicitadas pelos responsáveis do SID.