Ajustes final etapa1 #71

Merged
killer-cf merged 12 commits from ajustes_final_etapa1 into master 2025-12-29 17:28:52 +00:00
9 changed files with 477 additions and 153 deletions
Showing only changes of commit 414ae85264 - Show all commits

View File

@@ -821,8 +821,13 @@ export const atualizarStatus = mutation({
throw new Error('Período de férias não encontrado'); throw new Error('Período de férias não encontrado');
} }
// Atualizar status e histórico // Buscar usuário que está alterando o status para incluir na mensagem quando for Cancelado_RH
const acao = `Status alterado para ${args.novoStatus}`; let acao = `Status alterado para ${args.novoStatus}`;
if (args.novoStatus === 'Cancelado_RH') {
const usuarioRH = await ctx.db.get(args.usuarioId);
const nomeUsuario = usuarioRH?.nome || 'Usuário Desconhecido';
acao = `Status alterado para Cancelado_RH por ${nomeUsuario}`;
}
const updateData: { const updateData: {
status: typeof args.novoStatus; status: typeof args.novoStatus;

View File

@@ -1400,78 +1400,45 @@ function calcularHorasTrabalhadas(
return minutosA - minutosB; return minutosA - minutosB;
}); });
// Procurar registros principais let totalMinutos = 0;
const entrada = registrosOrdenados.find((r) => r.tipo === 'entrada'); let entradaPendente: { hora: number; minuto: number } | null = null;
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');
// Caso 1: Tem entrada e saída completas // Processar registros sequencialmente para capturar todos os períodos de trabalho
if (entrada && saida) { // Isso permite calcular múltiplas entradas/saídas no mesmo dia
const minutosEntrada = entrada.hora * 60 + entrada.minuto; for (const registro of registrosOrdenados) {
const minutosSaida = saida.hora * 60 + saida.minuto; const minutosRegistro = registro.hora * 60 + registro.minuto;
// Caso 1.1: Tem intervalo de almoço completo (saída almoço + retorno almoço) if (registro.tipo === 'entrada') {
if (saidaAlmoco && retornoAlmoco) { // Se já havia uma entrada pendente sem saída, ignorar a anterior (inconsistência)
const minutosSaidaAlmoco = saidaAlmoco.hora * 60 + saidaAlmoco.minuto; // e usar a nova entrada
const minutosRetornoAlmoco = retornoAlmoco.hora * 60 + retornoAlmoco.minuto; entradaPendente = { hora: registro.hora, minuto: registro.minuto };
} else if (registro.tipo === 'saida_almoco') {
// Validar ordem lógica // Se há entrada pendente, calcular período da manhã
if ( if (entradaPendente) {
minutosSaidaAlmoco > minutosEntrada && const minutosEntrada = entradaPendente.hora * 60 + entradaPendente.minuto;
minutosRetornoAlmoco > minutosSaidaAlmoco && if (minutosRegistro > minutosEntrada) {
minutosSaida > minutosRetornoAlmoco totalMinutos += minutosRegistro - minutosEntrada;
) {
const horasManha = minutosSaidaAlmoco - minutosEntrada;
const horasTarde = minutosSaida - minutosRetornoAlmoco;
return horasManha + horasTarde;
} }
// Limpar entrada pendente após saída almoço (aguardar retorno)
entradaPendente = null;
} }
} else if (registro.tipo === 'retorno_almoco') {
// Caso 1.2: Tem apenas saída almoço (sem retorno) - considerar apenas manhã // Marcar como nova entrada para período da tarde
if (saidaAlmoco && !retornoAlmoco) { entradaPendente = { hora: registro.hora, minuto: registro.minuto };
const minutosSaidaAlmoco = saidaAlmoco.hora * 60 + saidaAlmoco.minuto; } else if (registro.tipo === 'saida') {
if (minutosSaidaAlmoco > minutosEntrada) { // Se há entrada pendente (pode ser entrada inicial ou retorno almoço), calcular período
return minutosSaidaAlmoco - minutosEntrada; 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 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;
} }
} }
} }
// Caso 2: Tem apenas entrada (sem saída) - retornar 0 (dia incompleto) return totalMinutos;
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;
} }
/** /**