feat: add approval/rejection information and change history display in AprovarAusencias and AprovarFerias components for enhanced user feedback
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { v } from 'convex/values';
|
||||
import { mutation, query } from './_generated/server';
|
||||
import type { QueryCtx, MutationCtx } from './_generated/server';
|
||||
import { internal, api } from './_generated/api';
|
||||
import { api } from './_generated/api';
|
||||
import { Id, Doc } from './_generated/dataModel';
|
||||
import { parseLocalDate, formatarDataBR } from './utils/datas';
|
||||
import { getCurrentUserFunction } from './auth';
|
||||
|
||||
// Query: Listar todas as solicitações (para RH)
|
||||
export const listarTodas = query({
|
||||
@@ -185,6 +186,20 @@ export const obterDetalhes = query({
|
||||
time = await ctx.db.get(membroTime.timeId);
|
||||
}
|
||||
|
||||
// Enriquecer histórico com nomes dos usuários
|
||||
let historicoComUsuarios = solicitacao.historicoAlteracoes;
|
||||
if (historicoComUsuarios && historicoComUsuarios.length > 0) {
|
||||
historicoComUsuarios = await Promise.all(
|
||||
historicoComUsuarios.map(async (hist) => {
|
||||
const usuario = await ctx.db.get(hist.usuarioId);
|
||||
return {
|
||||
...hist,
|
||||
usuarioNome: usuario?.nome || 'Usuário Desconhecido'
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...solicitacao,
|
||||
funcionario: funcionario
|
||||
@@ -194,7 +209,8 @@ export const obterDetalhes = query({
|
||||
}
|
||||
: null,
|
||||
gestor,
|
||||
time
|
||||
time,
|
||||
historicoAlteracoes: historicoComUsuarios
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -302,10 +318,12 @@ export const criarSolicitacao = mutation({
|
||||
|
||||
const dataInicio = parseLocalDate(args.dataInicio);
|
||||
const dataFim = parseLocalDate(args.dataFim);
|
||||
|
||||
|
||||
// Criar data de hoje em UTC para comparação
|
||||
const hoje = new Date();
|
||||
const hojeUTC = new Date(Date.UTC(hoje.getUTCFullYear(), hoje.getUTCMonth(), hoje.getUTCDate(), 0, 0, 0, 0));
|
||||
const hojeUTC = new Date(
|
||||
Date.UTC(hoje.getUTCFullYear(), hoje.getUTCMonth(), hoje.getUTCDate(), 0, 0, 0, 0)
|
||||
);
|
||||
|
||||
if (dataInicio < hojeUTC) {
|
||||
throw new Error('A data de início não pode ser no passado');
|
||||
@@ -320,6 +338,17 @@ export const criarSolicitacao = mutation({
|
||||
throw new Error('Funcionário não encontrado');
|
||||
}
|
||||
|
||||
// Buscar usuário que está criando (pode não ser o próprio funcionário)
|
||||
const usuarioCriador = await getCurrentUserFunction(ctx);
|
||||
const usuarioFuncionario = await ctx.db
|
||||
.query('usuarios')
|
||||
.withIndex('by_funcionarioId', (q) => q.eq('funcionarioId', args.funcionarioId))
|
||||
.first();
|
||||
|
||||
// Usar o usuário autenticado se disponível, senão usar o usuário do funcionário ou gestor
|
||||
const usuarioIdParaHistorico =
|
||||
usuarioCriador?._id || usuarioFuncionario?._id || funcionario.gestorId;
|
||||
|
||||
// Verificar sobreposição com outras solicitações aprovadas ou pendentes
|
||||
const solicitacoesExistentes = await ctx.db
|
||||
.query('solicitacoesAusencias')
|
||||
@@ -334,6 +363,17 @@ export const criarSolicitacao = mutation({
|
||||
}
|
||||
}
|
||||
|
||||
// Criar histórico inicial
|
||||
const historicoInicial = usuarioIdParaHistorico
|
||||
? [
|
||||
{
|
||||
data: Date.now(),
|
||||
usuarioId: usuarioIdParaHistorico,
|
||||
acao: 'Solicitação criada'
|
||||
}
|
||||
]
|
||||
: [];
|
||||
|
||||
// Criar solicitação
|
||||
const solicitacaoId = await ctx.db.insert('solicitacoesAusencias', {
|
||||
funcionarioId: args.funcionarioId,
|
||||
@@ -341,7 +381,8 @@ export const criarSolicitacao = mutation({
|
||||
dataFim: args.dataFim,
|
||||
motivo: args.motivo.trim(),
|
||||
status: 'aguardando_aprovacao',
|
||||
criadoEm: Date.now()
|
||||
criadoEm: Date.now(),
|
||||
historicoAlteracoes: historicoInicial
|
||||
});
|
||||
|
||||
// Encontrar gestor do funcionário
|
||||
@@ -482,11 +523,23 @@ export const aprovar = mutation({
|
||||
throw new Error('Funcionário não encontrado');
|
||||
}
|
||||
|
||||
// Buscar nome do gestor para o histórico
|
||||
const gestorUsuario = await ctx.db.get(args.gestorId);
|
||||
const nomeGestor = gestorUsuario?.nome || 'Gestor';
|
||||
|
||||
// Atualizar solicitação
|
||||
await ctx.db.patch(args.solicitacaoId, {
|
||||
status: 'aprovado',
|
||||
gestorId: args.gestorId,
|
||||
dataAprovacao: Date.now()
|
||||
dataAprovacao: Date.now(),
|
||||
historicoAlteracoes: [
|
||||
...(solicitacao.historicoAlteracoes || []),
|
||||
{
|
||||
data: Date.now(),
|
||||
usuarioId: args.gestorId,
|
||||
acao: `Aprovado por ${nomeGestor}`
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Buscar usuário do funcionário
|
||||
@@ -625,12 +678,24 @@ export const reprovar = mutation({
|
||||
throw new Error('Funcionário não encontrado');
|
||||
}
|
||||
|
||||
// Buscar nome do gestor para o histórico
|
||||
const gestorUsuario = await ctx.db.get(args.gestorId);
|
||||
const nomeGestor = gestorUsuario?.nome || 'Gestor';
|
||||
|
||||
// Atualizar solicitação
|
||||
await ctx.db.patch(args.solicitacaoId, {
|
||||
status: 'reprovado',
|
||||
gestorId: args.gestorId,
|
||||
dataReprovacao: Date.now(),
|
||||
motivoReprovacao: args.motivoReprovacao.trim()
|
||||
motivoReprovacao: args.motivoReprovacao.trim(),
|
||||
historicoAlteracoes: [
|
||||
...(solicitacao.historicoAlteracoes || []),
|
||||
{
|
||||
data: Date.now(),
|
||||
usuarioId: args.gestorId,
|
||||
acao: `Reprovado por ${nomeGestor}: ${args.motivoReprovacao.trim()}`
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Buscar usuário do funcionário
|
||||
|
||||
@@ -290,6 +290,20 @@ export const obterDetalhes = query({
|
||||
time = await ctx.db.get(membroTime.timeId);
|
||||
}
|
||||
|
||||
// Enriquecer histórico com nomes dos usuários
|
||||
let historicoComUsuarios = ferias.historicoAlteracoes;
|
||||
if (historicoComUsuarios && historicoComUsuarios.length > 0) {
|
||||
historicoComUsuarios = await Promise.all(
|
||||
historicoComUsuarios.map(async (hist) => {
|
||||
const usuario = await ctx.db.get(hist.usuarioId);
|
||||
return {
|
||||
...hist,
|
||||
usuarioNome: usuario?.nome || 'Usuário Desconhecido'
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...ferias,
|
||||
funcionario: funcionario
|
||||
@@ -299,7 +313,8 @@ export const obterDetalhes = query({
|
||||
}
|
||||
: null,
|
||||
gestor,
|
||||
time
|
||||
time,
|
||||
historicoAlteracoes: historicoComUsuarios
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -389,6 +404,10 @@ export const aprovar = mutation({
|
||||
|
||||
const funcionario = await ctx.db.get(registro.funcionarioId);
|
||||
|
||||
// Buscar nome do gestor para o histórico
|
||||
const gestorUsuario = await ctx.db.get(args.gestorId);
|
||||
const nomeGestor = gestorUsuario?.nome || 'Gestor';
|
||||
|
||||
// Atualizar o registro
|
||||
await ctx.db.patch(registro._id, {
|
||||
status: 'aprovado',
|
||||
@@ -399,7 +418,7 @@ export const aprovar = mutation({
|
||||
{
|
||||
data: Date.now(),
|
||||
usuarioId: args.gestorId,
|
||||
acao: 'Aprovado'
|
||||
acao: `Aprovado por ${nomeGestor}`
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -18,7 +18,16 @@ export const ausenciasTables = {
|
||||
dataReprovacao: v.optional(v.number()),
|
||||
motivoReprovacao: v.optional(v.string()),
|
||||
observacao: v.optional(v.string()),
|
||||
criadoEm: v.number()
|
||||
criadoEm: v.number(),
|
||||
historicoAlteracoes: v.optional(
|
||||
v.array(
|
||||
v.object({
|
||||
data: v.number(),
|
||||
usuarioId: v.id('usuarios'),
|
||||
acao: v.string()
|
||||
})
|
||||
)
|
||||
)
|
||||
})
|
||||
.index('by_funcionario', ['funcionarioId'])
|
||||
.index('by_status', ['status'])
|
||||
|
||||
Reference in New Issue
Block a user