Files
sgse-app/apps/web/src/lib/utils/ponto.ts

160 lines
4.0 KiB
TypeScript

/**
* 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<string, string> = {
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<string, string> = {
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';
}
}
/**
* Formata data no formato DD/MM/AAAA
* Suporta strings ISO (YYYY-MM-DD), objetos Date, e timestamps
*/
export function formatarDataDDMMAAAA(data: string | Date | number): string {
if (!data) return '';
let dataObj: Date;
if (typeof data === 'string') {
// Se for string no formato ISO (YYYY-MM-DD), adicionar hora para evitar problemas de timezone
if (data.match(/^\d{4}-\d{2}-\d{2}$/)) {
dataObj = new Date(data + 'T12:00:00');
} else {
dataObj = new Date(data);
}
} else if (typeof data === 'number') {
dataObj = new Date(data);
} else {
dataObj = data;
}
// Verificar se a data é válida
if (isNaN(dataObj.getTime())) {
return '';
}
const dia = dataObj.getDate().toString().padStart(2, '0');
const mes = (dataObj.getMonth() + 1).toString().padStart(2, '0');
const ano = dataObj.getFullYear();
return `${dia}/${mes}/${ano}`;
}