167 lines
5.2 KiB
TypeScript
167 lines
5.2 KiB
TypeScript
import { v } from 'convex/values';
|
|
import { mutation, query, internalQuery } from './_generated/server';
|
|
import { encryptSMTPPassword } from './auth/utils';
|
|
import { registrarAtividade } from './logsAtividades';
|
|
|
|
/**
|
|
* Obter configuração de busca de código de barras ativa (credenciais mascaradas)
|
|
*/
|
|
export const obterConfigBuscaCodigoBarras = query({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
const config = await ctx.db
|
|
.query('configuracaoBuscaCodigoBarras')
|
|
.withIndex('by_ativo', (q) => q.eq('ativo', true))
|
|
.first();
|
|
|
|
if (!config) {
|
|
return null;
|
|
}
|
|
|
|
// Retornar config com credenciais mascaradas
|
|
return {
|
|
_id: config._id,
|
|
// GS1 Brasil
|
|
gs1BrasilClientId: config.gs1BrasilClientId || '',
|
|
gs1BrasilClientSecret: '********', // Mascarar
|
|
gs1BrasilTokenUrl: config.gs1BrasilTokenUrl || '',
|
|
gs1BrasilApiUrl: config.gs1BrasilApiUrl || '',
|
|
gs1BrasilAtivo: config.gs1BrasilAtivo,
|
|
// Bluesoft Cosmo
|
|
bluesoftApiKey: '********', // Mascarar
|
|
bluesoftApiUrl: config.bluesoftApiUrl || '',
|
|
bluesoftAtivo: config.bluesoftAtivo,
|
|
// Product-Search.net
|
|
productSearchApiKey: '********', // Mascarar
|
|
productSearchApiUrl: config.productSearchApiUrl || '',
|
|
productSearchAtivo: config.productSearchAtivo,
|
|
ativo: config.ativo,
|
|
atualizadoEm: config.atualizadoEm
|
|
};
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Salvar configuração de busca de código de barras
|
|
*/
|
|
export const salvarConfigBuscaCodigoBarras = mutation({
|
|
args: {
|
|
// GS1 Brasil
|
|
gs1BrasilClientId: v.optional(v.string()),
|
|
gs1BrasilClientSecret: v.optional(v.string()),
|
|
gs1BrasilTokenUrl: v.optional(v.string()),
|
|
gs1BrasilApiUrl: v.optional(v.string()),
|
|
gs1BrasilAtivo: v.boolean(),
|
|
// Bluesoft Cosmo
|
|
bluesoftApiKey: v.optional(v.string()),
|
|
bluesoftApiUrl: v.optional(v.string()),
|
|
bluesoftAtivo: v.boolean(),
|
|
// Product-Search.net
|
|
productSearchApiKey: v.optional(v.string()),
|
|
productSearchApiUrl: v.optional(v.string()),
|
|
productSearchAtivo: v.boolean(),
|
|
configuradoPorId: v.id('usuarios')
|
|
},
|
|
returns: v.union(
|
|
v.object({ sucesso: v.literal(true), configId: v.id('configuracaoBuscaCodigoBarras') }),
|
|
v.object({ sucesso: v.literal(false), erro: v.string() })
|
|
),
|
|
handler: async (ctx, args) => {
|
|
// Buscar config ativa anterior para manter credenciais se não fornecidas
|
|
const configAtiva = await ctx.db
|
|
.query('configuracaoBuscaCodigoBarras')
|
|
.withIndex('by_ativo', (q) => q.eq('ativo', true))
|
|
.first();
|
|
|
|
// Determinar credenciais: usar novas se fornecidas, senão manter as atuais
|
|
let gs1BrasilClientSecret: string | undefined;
|
|
if (args.gs1BrasilClientSecret && args.gs1BrasilClientSecret.trim().length > 0) {
|
|
// Nova credencial fornecida, criptografar
|
|
gs1BrasilClientSecret = await encryptSMTPPassword(args.gs1BrasilClientSecret);
|
|
} else if (configAtiva?.gs1BrasilClientSecret) {
|
|
// Credencial não fornecida, manter a atual
|
|
gs1BrasilClientSecret = configAtiva.gs1BrasilClientSecret;
|
|
}
|
|
|
|
let bluesoftApiKey: string | undefined;
|
|
if (args.bluesoftApiKey && args.bluesoftApiKey.trim().length > 0) {
|
|
bluesoftApiKey = await encryptSMTPPassword(args.bluesoftApiKey);
|
|
} else if (configAtiva?.bluesoftApiKey) {
|
|
bluesoftApiKey = configAtiva.bluesoftApiKey;
|
|
}
|
|
|
|
let productSearchApiKey: string | undefined;
|
|
if (args.productSearchApiKey && args.productSearchApiKey.trim().length > 0) {
|
|
productSearchApiKey = await encryptSMTPPassword(args.productSearchApiKey);
|
|
} else if (configAtiva?.productSearchApiKey) {
|
|
productSearchApiKey = configAtiva.productSearchApiKey;
|
|
}
|
|
|
|
// Desativar config anterior
|
|
const configsAntigas = await ctx.db
|
|
.query('configuracaoBuscaCodigoBarras')
|
|
.withIndex('by_ativo', (q) => q.eq('ativo', true))
|
|
.collect();
|
|
|
|
for (const config of configsAntigas) {
|
|
await ctx.db.patch(config._id, { ativo: false });
|
|
}
|
|
|
|
// Criar nova config
|
|
const configId = await ctx.db.insert('configuracaoBuscaCodigoBarras', {
|
|
gs1BrasilClientId: args.gs1BrasilClientId || undefined,
|
|
gs1BrasilClientSecret,
|
|
gs1BrasilTokenUrl: args.gs1BrasilTokenUrl || undefined,
|
|
gs1BrasilApiUrl: args.gs1BrasilApiUrl || undefined,
|
|
gs1BrasilAtivo: args.gs1BrasilAtivo,
|
|
bluesoftApiKey,
|
|
bluesoftApiUrl: args.bluesoftApiUrl || undefined,
|
|
bluesoftAtivo: args.bluesoftAtivo,
|
|
productSearchApiKey,
|
|
productSearchApiUrl: args.productSearchApiUrl || undefined,
|
|
productSearchAtivo: args.productSearchAtivo,
|
|
ativo: true,
|
|
configuradoPor: args.configuradoPorId,
|
|
atualizadoEm: Date.now()
|
|
});
|
|
|
|
// Log de atividade
|
|
await registrarAtividade(
|
|
ctx,
|
|
args.configuradoPorId,
|
|
'configurar',
|
|
'buscaCodigoBarras',
|
|
JSON.stringify({
|
|
gs1BrasilAtivo: args.gs1BrasilAtivo,
|
|
bluesoftAtivo: args.bluesoftAtivo,
|
|
productSearchAtivo: args.productSearchAtivo
|
|
}),
|
|
configId
|
|
);
|
|
|
|
return { sucesso: true as const, configId };
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Obter configuração de busca de código de barras (internal query)
|
|
* Usado pela action de busca para obter credenciais descriptografadas
|
|
*/
|
|
export const obterConfigBuscaCodigoBarrasInternal = internalQuery({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
const config = await ctx.db
|
|
.query('configuracaoBuscaCodigoBarras')
|
|
.withIndex('by_ativo', (q) => q.eq('ativo', true))
|
|
.first();
|
|
|
|
if (!config) {
|
|
return null;
|
|
}
|
|
|
|
// Retornar config completa (para uso interno)
|
|
return config;
|
|
}
|
|
});
|
|
|