feat: implement automatic adjustment removal for deleted records in absence and atestado mutations, enhancing data integrity and recalculating work hours for specific periods

This commit is contained in:
2025-12-23 07:44:54 -03:00
parent 414ae85264
commit a731015c89
4 changed files with 191 additions and 16 deletions

View File

@@ -1535,6 +1535,54 @@ async function verificarAusenciaAprovada(
return { temAusencia: false };
}
/**
* Remove ajustes automáticos relacionados a um registro excluído
* Busca e remove ajustes que referenciam o motivoId fornecido
*/
async function removerAjustesAutomaticos(
ctx: MutationCtx,
funcionarioId: Id<'funcionarios'>,
motivoTipo: 'atestado' | 'licenca' | 'ausencia',
motivoId: string,
dataInicio: string,
dataFim: string
): Promise<void> {
// Gerar todas as datas do período
const dataInicioObj = new Date(dataInicio);
const dataFimObj = new Date(dataFim);
const datas: string[] = [];
const dataAtual = new Date(dataInicioObj);
while (dataAtual <= dataFimObj) {
const ano = dataAtual.getFullYear();
const mes = String(dataAtual.getMonth() + 1).padStart(2, '0');
const dia = String(dataAtual.getDate()).padStart(2, '0');
datas.push(`${ano}-${mes}-${dia}`);
dataAtual.setDate(dataAtual.getDate() + 1);
}
// Buscar todos os ajustes automáticos relacionados ao motivoId no período
for (const data of datas) {
const ajustes = await ctx.db
.query('ajustesBancoHoras')
.filter((q) =>
q.and(
q.eq(q.field('funcionarioId'), funcionarioId),
q.eq(q.field('dataAplicacao'), data),
q.eq(q.field('motivoTipo'), motivoTipo),
q.eq(q.field('motivoId'), motivoId),
q.eq(q.field('aplicado'), true)
)
)
.collect();
// Remover cada ajuste encontrado
for (const ajuste of ajustes) {
await ctx.db.delete(ajuste._id);
}
}
}
/**
* Verifica ajustes manuais aplicados no dia
*/
@@ -1693,10 +1741,13 @@ async function atualizarBancoHoras(
const ajustesIds: Array<Id<'ajustesBancoHoras'>> = [];
// Aplicar ajustes automáticos se houver atestado, licença ou ausência
if (atestadoInfo.temAtestado) {
tipoDia = 'atestado';
motivoAbono = atestadoInfo.motivo;
if (atestadoInfo.atestadoId) {
// IMPORTANTE: Verificar se o registro ainda existe antes de criar ajuste
if (atestadoInfo.temAtestado && atestadoInfo.atestadoId) {
// Verificar se o atestado ainda existe no banco
const atestado = await ctx.db.get(atestadoInfo.atestadoId as Id<'atestados'>);
if (atestado) {
tipoDia = 'atestado';
motivoAbono = atestadoInfo.motivo;
const ajusteId = await aplicarAjusteAutomatico(
ctx,
funcionarioId,
@@ -1708,10 +1759,12 @@ async function atualizarBancoHoras(
);
ajustesIds.push(ajusteId);
}
} else if (licencaInfo.temLicenca) {
tipoDia = 'licenca';
motivoAbono = licencaInfo.motivo;
if (licencaInfo.licencaId) {
} else if (licencaInfo.temLicenca && licencaInfo.licencaId) {
// Verificar se a licença ainda existe no banco
const licenca = await ctx.db.get(licencaInfo.licencaId as Id<'licencas'>);
if (licenca) {
tipoDia = 'licenca';
motivoAbono = licencaInfo.motivo;
const ajusteId = await aplicarAjusteAutomatico(
ctx,
funcionarioId,
@@ -1723,10 +1776,12 @@ async function atualizarBancoHoras(
);
ajustesIds.push(ajusteId);
}
} else if (ausenciaInfo.temAusencia) {
tipoDia = 'ausencia';
motivoAbono = ausenciaInfo.motivo;
if (ausenciaInfo.ausenciaId) {
} else if (ausenciaInfo.temAusencia && ausenciaInfo.ausenciaId) {
// Verificar se a ausência ainda existe no banco e está aprovada
const ausencia = await ctx.db.get(ausenciaInfo.ausenciaId as Id<'solicitacoesAusencias'>);
if (ausencia && ausencia.status === 'aprovado') {
tipoDia = 'ausencia';
motivoAbono = ausenciaInfo.motivo;
const ajusteId = await aplicarAjusteAutomatico(
ctx,
funcionarioId,
@@ -4238,6 +4293,31 @@ export const recalcularBancoHoras = mutation({
/**
* Mutation interna para recalcular banco de horas de uma data específica
*/
/**
* Internal mutation para remover ajustes automáticos relacionados a um registro excluído
*/
export const removerAjustesAutomaticosInternal = internalMutation({
args: {
funcionarioId: v.id('funcionarios'),
motivoTipo: v.union(v.literal('atestado'), v.literal('licenca'), v.literal('ausencia')),
motivoId: v.string(),
dataInicio: v.string(),
dataFim: v.string()
},
returns: v.null(),
handler: async (ctx, args) => {
await removerAjustesAutomaticos(
ctx,
args.funcionarioId,
args.motivoTipo,
args.motivoId,
args.dataInicio,
args.dataFim
);
return null;
}
});
export const recalcularBancoHorasData = internalMutation({
args: {
funcionarioId: v.id('funcionarios'),