feat: improve vacation status update logic to include user information when status is set to 'Cancelado_RH' and refactor work hour calculation to handle multiple entries and exits more effectively
This commit is contained in:
@@ -1400,78 +1400,45 @@ function calcularHorasTrabalhadas(
|
||||
return minutosA - minutosB;
|
||||
});
|
||||
|
||||
// Procurar registros principais
|
||||
const entrada = registrosOrdenados.find((r) => r.tipo === 'entrada');
|
||||
const saidaAlmoco = registrosOrdenados.find((r) => r.tipo === 'saida_almoco');
|
||||
const retornoAlmoco = registrosOrdenados.find((r) => r.tipo === 'retorno_almoco');
|
||||
const saida = registrosOrdenados.find((r) => r.tipo === 'saida');
|
||||
let totalMinutos = 0;
|
||||
let entradaPendente: { hora: number; minuto: number } | null = null;
|
||||
|
||||
// Caso 1: Tem entrada e saída completas
|
||||
if (entrada && saida) {
|
||||
const minutosEntrada = entrada.hora * 60 + entrada.minuto;
|
||||
const minutosSaida = saida.hora * 60 + saida.minuto;
|
||||
// Processar registros sequencialmente para capturar todos os períodos de trabalho
|
||||
// Isso permite calcular múltiplas entradas/saídas no mesmo dia
|
||||
for (const registro of registrosOrdenados) {
|
||||
const minutosRegistro = registro.hora * 60 + registro.minuto;
|
||||
|
||||
// Caso 1.1: Tem intervalo de almoço completo (saída almoço + retorno almoço)
|
||||
if (saidaAlmoco && retornoAlmoco) {
|
||||
const minutosSaidaAlmoco = saidaAlmoco.hora * 60 + saidaAlmoco.minuto;
|
||||
const minutosRetornoAlmoco = retornoAlmoco.hora * 60 + retornoAlmoco.minuto;
|
||||
|
||||
// Validar ordem lógica
|
||||
if (
|
||||
minutosSaidaAlmoco > minutosEntrada &&
|
||||
minutosRetornoAlmoco > minutosSaidaAlmoco &&
|
||||
minutosSaida > minutosRetornoAlmoco
|
||||
) {
|
||||
const horasManha = minutosSaidaAlmoco - minutosEntrada;
|
||||
const horasTarde = minutosSaida - minutosRetornoAlmoco;
|
||||
return horasManha + horasTarde;
|
||||
if (registro.tipo === 'entrada') {
|
||||
// Se já havia uma entrada pendente sem saída, ignorar a anterior (inconsistência)
|
||||
// e usar a nova entrada
|
||||
entradaPendente = { hora: registro.hora, minuto: registro.minuto };
|
||||
} else if (registro.tipo === 'saida_almoco') {
|
||||
// Se há entrada pendente, calcular período da manhã
|
||||
if (entradaPendente) {
|
||||
const minutosEntrada = entradaPendente.hora * 60 + entradaPendente.minuto;
|
||||
if (minutosRegistro > minutosEntrada) {
|
||||
totalMinutos += minutosRegistro - minutosEntrada;
|
||||
}
|
||||
// Limpar entrada pendente após saída almoço (aguardar retorno)
|
||||
entradaPendente = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Caso 1.2: Tem apenas saída almoço (sem retorno) - considerar apenas manhã
|
||||
if (saidaAlmoco && !retornoAlmoco) {
|
||||
const minutosSaidaAlmoco = saidaAlmoco.hora * 60 + saidaAlmoco.minuto;
|
||||
if (minutosSaidaAlmoco > minutosEntrada) {
|
||||
return minutosSaidaAlmoco - minutosEntrada;
|
||||
}
|
||||
}
|
||||
|
||||
// Caso 1.3: Tem apenas retorno almoço (sem saída) - considerar apenas tarde
|
||||
if (!saidaAlmoco && retornoAlmoco) {
|
||||
const minutosRetornoAlmoco = retornoAlmoco.hora * 60 + retornoAlmoco.minuto;
|
||||
if (minutosSaida > minutosRetornoAlmoco) {
|
||||
return minutosSaida - minutosRetornoAlmoco;
|
||||
}
|
||||
}
|
||||
|
||||
// Caso 1.4: Sem intervalo de almoço registrado - calcular direto
|
||||
if (!saidaAlmoco && !retornoAlmoco) {
|
||||
if (minutosSaida > minutosEntrada) {
|
||||
return minutosSaida - minutosEntrada;
|
||||
} else if (registro.tipo === 'retorno_almoco') {
|
||||
// Marcar como nova entrada para período da tarde
|
||||
entradaPendente = { hora: registro.hora, minuto: registro.minuto };
|
||||
} else if (registro.tipo === 'saida') {
|
||||
// Se há entrada pendente (pode ser entrada inicial ou retorno almoço), calcular período
|
||||
if (entradaPendente) {
|
||||
const minutosEntrada = entradaPendente.hora * 60 + entradaPendente.minuto;
|
||||
if (minutosRegistro > minutosEntrada) {
|
||||
totalMinutos += minutosRegistro - minutosEntrada;
|
||||
}
|
||||
// Limpar entrada pendente após saída
|
||||
entradaPendente = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Caso 2: Tem apenas entrada (sem saída) - retornar 0 (dia incompleto)
|
||||
if (entrada && !saida) {
|
||||
// Se tiver saída almoço, considerar até a saída almoço
|
||||
if (saidaAlmoco) {
|
||||
const minutosEntrada = entrada.hora * 60 + entrada.minuto;
|
||||
const minutosSaidaAlmoco = saidaAlmoco.hora * 60 + saidaAlmoco.minuto;
|
||||
if (minutosSaidaAlmoco > minutosEntrada) {
|
||||
return minutosSaidaAlmoco - minutosEntrada;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Caso 3: Tem apenas saída (sem entrada) - inconsistência, retornar 0
|
||||
if (saida && !entrada) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Caso 4: Não tem entrada nem saída - retornar 0
|
||||
return 0;
|
||||
return totalMinutos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user