/** * Formata hora no formato HH:mm */ export function formatarHoraPonto(hora: number, minuto: number): string { return `${hora.toString().padStart(2, '0')}:${minuto.toString().padStart(2, '0')}`; } /** * Formata data e hora completa */ export function formatarDataHoraCompleta( data: string, hora: number, minuto: number, segundo: number ): string { const dataObj = new Date(`${data}T${formatarHoraPonto(hora, minuto)}:${segundo.toString().padStart(2, '0')}`); return dataObj.toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', }); } /** * Calcula tempo trabalhado entre dois registros */ export function calcularTempoTrabalhado( horaInicio: number, minutoInicio: number, horaFim: number, minutoFim: number ): { horas: number; minutos: number } { const minutosInicio = horaInicio * 60 + minutoInicio; const minutosFim = horaFim * 60 + minutoFim; const diferencaMinutos = minutosFim - minutosInicio; if (diferencaMinutos < 0) { return { horas: 0, minutos: 0 }; } const horas = Math.floor(diferencaMinutos / 60); const minutos = diferencaMinutos % 60; return { horas, minutos }; } /** * Verifica se está dentro do prazo baseado na configuração */ export function verificarDentroDoPrazo( hora: number, minuto: number, horarioConfigurado: string, toleranciaMinutos: number ): boolean { const [horaConfig, minutoConfig] = horarioConfigurado.split(':').map(Number); const totalMinutosRegistro = hora * 60 + minuto; const totalMinutosConfigurado = horaConfig * 60 + minutoConfig; const diferenca = totalMinutosRegistro - totalMinutosConfigurado; return diferenca <= toleranciaMinutos && diferenca >= -toleranciaMinutos; } /** * Obtém label do tipo de registro * Se config fornecida, usa os nomes personalizados, senão usa os padrões */ export function getTipoRegistroLabel( tipo: 'entrada' | 'saida_almoco' | 'retorno_almoco' | 'saida', config?: { nomeEntrada?: string; nomeSaidaAlmoco?: string; nomeRetornoAlmoco?: string; nomeSaida?: string; } ): string { // Se config fornecida, usar nomes personalizados if (config) { const labels: Record = { entrada: config.nomeEntrada || 'Entrada 1', saida_almoco: config.nomeSaidaAlmoco || 'Saída 1', retorno_almoco: config.nomeRetornoAlmoco || 'Entrada 2', saida: config.nomeSaida || 'Saída 2', }; return labels[tipo] || tipo; } // Valores padrão const labels: Record = { entrada: 'Entrada 1', saida_almoco: 'Saída 1', retorno_almoco: 'Entrada 2', saida: 'Saída 2', }; return labels[tipo] || tipo; } /** * Obtém próximo tipo de registro esperado */ export function getProximoTipoRegistro( ultimoTipo: 'entrada' | 'saida_almoco' | 'retorno_almoco' | 'saida' | null ): 'entrada' | 'saida_almoco' | 'retorno_almoco' | 'saida' { if (!ultimoTipo) { return 'entrada'; } switch (ultimoTipo) { case 'entrada': return 'saida_almoco'; case 'saida_almoco': return 'retorno_almoco'; case 'retorno_almoco': return 'saida'; case 'saida': return 'entrada'; // Novo dia default: return 'entrada'; } }