feat: add new features for point management and registration

- Introduced "Homologação de Registro" and "Dispensa de Registro" sections in the dashboard for enhanced point management.
- Updated the WidgetGestaoPontos component to include new links and icons for the added features.
- Enhanced backend functionality to support the new features, including querying and managing dispensas and homologações.
- Improved the PDF generation process to include daily balance calculations for employee time records.
- Implemented checks for active dispensas to prevent unauthorized point registrations.
This commit is contained in:
2025-11-19 16:37:31 -03:00
parent ed5695cf28
commit db61df1fb4
9 changed files with 2602 additions and 164 deletions

View File

@@ -1390,6 +1390,10 @@ export default defineSchema({
// Justificativa opcional para o registro
justificativa: v.optional(v.string()),
// Campos para homologação
editadoPorGestor: v.optional(v.boolean()),
homologacaoId: v.optional(v.id("homologacoesPonto")),
criadoEm: v.number(),
})
.index("by_funcionario_data", ["funcionarioId", "data"])
@@ -1443,4 +1447,60 @@ export default defineSchema({
.index("by_funcionario_data", ["funcionarioId", "data"])
.index("by_funcionario", ["funcionarioId"])
.index("by_data", ["data"]),
// Homologações de Ponto - Edições e ajustes realizados pelo gestor
homologacoesPonto: defineTable({
registroId: v.optional(v.id("registrosPonto")), // ID do registro editado (se for edição)
funcionarioId: v.id("funcionarios"),
gestorId: v.id("usuarios"),
// Dados do registro original (se for edição)
horaAnterior: v.optional(v.number()),
minutoAnterior: v.optional(v.number()),
// Dados do registro novo (se for edição)
horaNova: v.optional(v.number()),
minutoNova: v.optional(v.number()),
// Motivo e observações
motivoId: v.optional(v.string()), // ID do motivo (referência a atestados/declarações)
motivoTipo: v.optional(v.string()), // Tipo do motivo (atestado, declaracao, etc)
motivoDescricao: v.optional(v.string()), // Descrição do motivo
observacoes: v.optional(v.string()),
// Tipo de ajuste (se for ajuste de banco de horas)
tipoAjuste: v.optional(v.union(
v.literal("compensar"),
v.literal("abonar"),
v.literal("descontar")
)),
// Período do ajuste (se for ajuste de banco de horas)
periodoDias: v.optional(v.number()),
periodoHoras: v.optional(v.number()),
periodoMinutos: v.optional(v.number()),
// Ajuste em minutos (calculado)
ajusteMinutos: v.optional(v.number()),
criadoEm: v.number(),
})
.index("by_funcionario", ["funcionarioId"])
.index("by_gestor", ["gestorId"])
.index("by_registro", ["registroId"])
.index("by_data", ["criadoEm"]),
// Dispensas de Registro - Períodos onde funcionário está dispensado de registrar ponto
dispensasRegistro: defineTable({
funcionarioId: v.id("funcionarios"),
gestorId: v.id("usuarios"),
dataInicio: v.string(), // YYYY-MM-DD
horaInicio: v.number(),
minutoInicio: v.number(),
dataFim: v.string(), // YYYY-MM-DD
horaFim: v.number(),
minutoFim: v.number(),
motivo: v.string(),
isento: v.boolean(), // Se true, não expira (casos excepcionais)
ativo: v.boolean(),
criadoEm: v.number(),
})
.index("by_funcionario", ["funcionarioId"])
.index("by_gestor", ["gestorId"])
.index("by_ativo", ["ativo"])
.index("by_data_inicio", ["dataInicio"])
.index("by_data_fim", ["dataFim"]),
});