import { Router } from 'express'; import { prisma } from '../prismaClient'; import { authMiddleware } from '../../middleware/auth'; import { TipoDocumento } from '@prisma/client'; import { PdfService } from '../services/PdfService'; import multer from 'multer'; import path from 'path'; import fs from 'fs'; const router = Router(); router.use(authMiddleware); // Listar documentos router.get('/', async (req, res) => { try { const { processoId, atendimentoId, tipo } = req.query; const where: any = {}; if (processoId) where.processoId = processoId; if (atendimentoId) where.atendimentoId = atendimentoId; if (tipo) where.tipo = tipo as TipoDocumento; const documentos = await prisma.documento.findMany({ where, include: { criadoPor: { select: { id: true, nome: true } } }, orderBy: { criadoEm: 'desc' } }); res.json(documentos); } catch (error) { console.error('Erro ao listar documentos:', error); res.status(500).json({ error: 'Erro ao listar documentos' }); } }); // Criar documento router.post('/', async (req, res) => { try { const { nome, tipo, conteudo, processoId, atendimentoId } = req.body; if (!req.user?.id) { return res.status(401).json({ error: 'Usuário não autenticado' }); } const documento = await prisma.documento.create({ data: { nome, tipo, conteudo, processoId, atendimentoId, criadoPorId: req.user.id } }); res.status(201).json(documento); } catch (error) { console.error('Erro ao criar documento:', error); res.status(500).json({ error: 'Erro ao criar documento' }); } }); // Criar documento a partir de modelo router.post('/from-modelo/:modeloId', async (req, res) => { try { const { modeloId } = req.params; const { processoId, atendimentoId, variaveis } = req.body; if (!req.user?.id) { return res.status(401).json({ error: 'Usuário não autenticado' }); } // Buscar modelo const modelo = await prisma.documentoModelo.findUnique({ where: { id: modeloId } }); if (!modelo) { return res.status(404).json({ error: 'Modelo não encontrado' }); } // Buscar dados adicionais se necessário let clienteData; if (variaveis?.cliente?.id) { const cliente = await prisma.cliente.findUnique({ where: { id: variaveis.cliente.id } }); if (cliente) { clienteData = cliente; } } // Substituir variáveis no conteúdo let conteudo = modelo.conteudo; if (clienteData) { const substituicoes = { 'cliente.nome': clienteData.nome, 'cliente.cpf': clienteData.cpfCnpj, 'cliente.rg': clienteData.rg, 'cliente.estadoCivil': clienteData.estadoCivil, 'cliente.profissao': clienteData.profissao, 'cliente.enderecoCompleto': clienteData.enderecoCompleto, 'data.atualExtenso': new Date().toLocaleDateString('pt-BR', { day: 'numeric', month: 'long', year: 'numeric' }) }; Object.entries(substituicoes).forEach(([key, value]) => { const regex = new RegExp(`{{${key}}}`, 'g'); conteudo = conteudo.replace(regex, value || ''); }); } // Criar o documento const documento = await prisma.documento.create({ data: { nome: modelo.nome, // Usando o nome do modelo tipo: modelo.tipo, conteudo, processoId, atendimentoId, criadoPorId: req.user.id, modeloId: modelo.id } }); res.status(201).json({ ...documento, clienteId: variaveis?.cliente?.id }); } catch (error) { console.error('Erro ao criar documento:', error); res.status(500).json({ error: 'Erro ao criar documento' }); } }); // Atualizar a rota de configurações router.post('/configuracoes', async (req, res) => { try { const escritorioId = req.user.escritorioId; // Assumindo que você tem o ID do escritório no token // Usar upsert para criar ou atualizar const config = await prisma.configuracaoDocumento.upsert({ where: { escritorioId }, update: { ...req.body, margensTemplate: req.body.margensTemplate || { top: 35, bottom: 29, left: 25, right: 25 } }, create: { escritorioId, ...req.body, margensTemplate: req.body.margensTemplate || { top: 35, bottom: 29, left: 25, right: 25 } } }); res.json(config); } catch (error) { console.error('Erro ao salvar configuração:', error); res.status(500).json({ error: 'Erro ao salvar configuração' }); } }); // Rota para buscar última configuração router.get('/configuracoes', async (req, res) => { try { console.log('Buscando configurações de documento'); const config = await prisma.configuracaoDocumento.findFirst({ orderBy: { criadoEm: 'desc' } }); if (!config) { // Criar configuração padrão se não existir const defaultConfig = await prisma.configuracaoDocumento.create({ data: { timbradoMarginTop: 100, timbradoMarginBottom: 50, timbradoMarginLeft: 50, timbradoMarginRight: 50, margensTemplate: { top: 113, bottom: 90, left: 35, right: 35 } } }); return res.json(defaultConfig); } res.json(config); } catch (error) { console.error('Erro ao buscar configurações:', error); res.status(500).json({ error: 'Erro ao buscar configurações' }); } }); // Atualizar configuração do documento router.post('/configuracao', authMiddleware, async (req, res) => { try { // Primeiro, tente encontrar uma configuração existente const configExistente = await prisma.configuracaoDocumento.findFirst({ where: { escritorioId: req.user.escritorioId } }); let config; if (configExistente) { // Se existir, atualiza config = await prisma.configuracaoDocumento.update({ where: { id: configExistente.id }, data: { timbradoUrl: req.body.timbradoUrl, timbradoMarginTop: req.body.timbradoMarginTop, timbradoMarginBottom: req.body.timbradoMarginBottom, timbradoMarginLeft: req.body.timbradoMarginLeft, timbradoMarginRight: req.body.timbradoMarginRight, templatePadrao: req.body.templatePadrao || "", margensTemplate: req.body.margensTemplate } }); } else { // Se não existir, cria config = await prisma.configuracaoDocumento.create({ data: { escritorioId: req.user.escritorioId, timbradoUrl: req.body.timbradoUrl, timbradoMarginTop: req.body.timbradoMarginTop, timbradoMarginBottom: req.body.timbradoMarginBottom, timbradoMarginLeft: req.body.timbradoMarginLeft, timbradoMarginRight: req.body.timbradoMarginRight, templatePadrao: req.body.templatePadrao || "", margensTemplate: req.body.margensTemplate } }); } res.json(config); } catch (error) { console.error('Erro ao salvar configuração:', error); res.status(500).json({ error: 'Falha ao salvar configuração do documento' }); } }); // Atualizar documento com manipulação de erro aprimorada router.put('/:id', async (req, res) => { try { const { id } = req.params; const { nome, tipo, conteudo } = req.body; // Verificar se o documento existe const documentoExistente = await prisma.documento.findUnique({ where: { id }, select: { id: true, criadoPorId: true } }); if (!documentoExistente) { return res.status(404).json({ error: 'Documento não encontrado' }); } // Verificar permissão (apenas quem criou ou é admin pode editar) if (documentoExistente.criadoPorId !== req.user.id && req.user.perfil !== 'ADVOGADO_ADMIN') { return res.status(403).json({ error: 'Sem permissão para editar este documento' }); } // Validar dados if (!nome || !tipo || !conteudo) { return res.status(400).json({ error: 'Dados incompletos para atualização do documento' }); } // Atualizar o documento const documento = await prisma.documento.update({ where: { id }, data: { nome, tipo: tipo as TipoDocumento, conteudo, atualizadoEm: new Date() } }); // Registrar evento de atualização (opcional) // await prisma.auditoria.create({ // data: { // entidade: 'DOCUMENTO', // entidadeId: id, // acao: 'ATUALIZAÇÃO', // usuarioId: req.user.id // } // }); res.json(documento); } catch (error) { console.error('Erro ao atualizar documento:', error); res.status(500).json({ error: 'Erro ao atualizar documento' }); } }); // Excluir documento router.delete('/:id', async (req, res) => { try { await prisma.documento.delete({ where: { id: req.params.id } }); res.status(204).send(); } catch (error) { console.error('Erro ao excluir documento:', error); res.status(500).json({ error: 'Erro ao excluir documento' }); } }); // Adicionar nova rota para exportar PDF router.post('/exportar-pdf', async (req, res) => { try { const { conteudo, escritorio } = req.body; const pdfService = new PdfService(); const pdfBuffer = await pdfService.gerarPDF(conteudo, escritorio); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename=documento.pdf'); res.send(pdfBuffer); } catch (error) { console.error('Erro ao gerar PDF:', error); res.status(500).json({ error: 'Erro ao gerar PDF' }); } }); // Configuração do multer para upload de arquivos const storage = multer.diskStorage({ destination: (req, file, cb) => { const uploadDir = path.join(process.cwd(), 'public', 'uploads'); if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); } cb(null, uploadDir); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); cb(null, `timbrado-${uniqueSuffix}-${file.originalname}`); } }); const fileFilter = (req: any, file: any, cb: any) => { // Atualizar para aceitar PDF const allowedTypes = ['image/png', 'image/svg+xml', 'application/pdf']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error('Formato de arquivo não suportado. Use PNG, SVG ou PDF.')); } }; const upload = multer({ storage, fileFilter, limits: { fileSize: 5 * 1024 * 1024 // Aumentar para 5MB } }); // Rota de upload do timbrado router.post('/upload-timbrado', upload.single('timbrado'), async (req, res) => { try { if (!req.file) { throw new Error('Nenhum arquivo enviado'); } // Criar URL relativa para o arquivo const fileUrl = `/uploads/${req.file.filename}`; res.json({ url: fileUrl }); } catch (error: any) { console.error('Erro no upload do timbrado:', error); res.status(400).json({ error: error.message }); } }); export default router;