import { v } from 'convex/values'; import { internalQuery, mutation, query } from './_generated/server'; import { internal } from './_generated/api'; import { getCurrentUserFunction } from './auth'; export const obterConfiguracao = query({ args: {}, handler: async (ctx) => { // Verificar se usuário tem permissão de TI await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { recurso: 'almoxarifado', acao: 'configurar' }); const config = await ctx.db .query('configuracoesAlmoxarifado') .filter((q) => q.eq(q.field('ativo'), true)) .first(); // Se não existe configuração, retornar valores padrão if (!config) { return { estoqueMinimoPadrao: 10, diasAntecedenciaAlerta: 7, permitirEstoqueNegativo: false, requerAprovacaoRequisicao: true, rolesAprovacao: [], emailAlertasAtivo: false, emailsDestinatarios: [], periodicidadeInventario: 30, ultimoInventario: undefined, ativo: true }; } return config; } }); export const atualizarConfiguracao = mutation({ args: { estoqueMinimoPadrao: v.optional(v.number()), diasAntecedenciaAlerta: v.optional(v.number()), permitirEstoqueNegativo: v.optional(v.boolean()), requerAprovacaoRequisicao: v.optional(v.boolean()), rolesAprovacao: v.optional(v.array(v.string())), emailAlertasAtivo: v.optional(v.boolean()), emailsDestinatarios: v.optional(v.array(v.string())), periodicidadeInventario: v.optional(v.number()), ultimoInventario: v.optional(v.number()) }, handler: async (ctx, args) => { // Verificar se usuário tem permissão de TI_MASTER await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { recurso: 'almoxarifado', acao: 'configurar' }); const usuario = await getCurrentUserFunction(ctx); if (!usuario) throw new Error('Usuário não autenticado'); // Buscar configuração existente let config = await ctx.db .query('configuracoesAlmoxarifado') .filter((q) => q.eq(q.field('ativo'), true)) .first(); const dadosAnteriores = config ? { ...config } : undefined; if (config) { // Desativar configuração antiga await ctx.db.patch(config._id, { ativo: false }); // Criar nova configuração const dadosNovos = { ...config, ...args, ativo: true, atualizadoPor: usuario._id, atualizadoEm: Date.now() }; const novaConfigId = await ctx.db.insert('configuracoesAlmoxarifado', dadosNovos); // Registrar histórico if (usuario) { await ctx.db.insert('historicoAlteracoes', { tipoEntidade: 'configuracao', entidadeId: novaConfigId, acao: 'edicao', usuarioId: usuario._id, dadosAnteriores: dadosAnteriores ? JSON.stringify(dadosAnteriores) : undefined, dadosNovos: JSON.stringify(dadosNovos), timestamp: Date.now(), observacoes: 'Atualização de configurações do almoxarifado' }); } return novaConfigId; } else { // Criar primeira configuração const dadosNovos = { estoqueMinimoPadrao: args.estoqueMinimoPadrao ?? 10, diasAntecedenciaAlerta: args.diasAntecedenciaAlerta ?? 7, permitirEstoqueNegativo: args.permitirEstoqueNegativo ?? false, requerAprovacaoRequisicao: args.requerAprovacaoRequisicao ?? true, rolesAprovacao: args.rolesAprovacao ?? [], emailAlertasAtivo: args.emailAlertasAtivo ?? false, emailsDestinatarios: args.emailsDestinatarios ?? [], periodicidadeInventario: args.periodicidadeInventario ?? 30, ultimoInventario: args.ultimoInventario, ativo: true, atualizadoPor: usuario._id, atualizadoEm: Date.now() }; const novaConfigId = await ctx.db.insert('configuracoesAlmoxarifado', dadosNovos); // Registrar histórico if (usuario) { await ctx.db.insert('historicoAlteracoes', { tipoEntidade: 'configuracao', entidadeId: novaConfigId, acao: 'criacao', usuarioId: usuario._id, dadosAnteriores: undefined, dadosNovos: JSON.stringify(dadosNovos), timestamp: Date.now(), observacoes: 'Criação de configurações do almoxarifado' }); } return novaConfigId; } } }); // ========== INTERNAL QUERIES ========== export const obterConfiguracaoInterno = internalQuery({ args: {}, handler: async (ctx) => { const config = await ctx.db .query('configuracoesAlmoxarifado') .filter((q) => q.eq(q.field('ativo'), true)) .first(); if (!config) { return { estoqueMinimoPadrao: 10, diasAntecedenciaAlerta: 7, permitirEstoqueNegativo: false, requerAprovacaoRequisicao: true, rolesAprovacao: [], emailAlertasAtivo: false, emailsDestinatarios: [], periodicidadeInventario: 30, ultimoInventario: undefined, ativo: true }; } return config; } });