Files
advx/src/server/routes/documentos.ts
T
2025-04-10 23:07:21 -03:00

412 lines
11 KiB
TypeScript

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;