fix(pdf): adiciona logo dinamica e trata overflow em descricoes longas no recibo
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s Details

This commit is contained in:
Sidney 2026-06-07 15:28:41 -03:00
parent 7951787b16
commit e79b472279
2 changed files with 68 additions and 15 deletions

View File

@ -1674,36 +1674,85 @@ async function sendEvolutionMessage(asaasPaymentId, eventType, fallbackValorArg
if (isPaymentConfirmation) {
// GERAÇÃO DE RECIBO PROFISSIONAL (BACKEND - NODE COMPATIBLE)
try {
let logoDataUrl = null;
let logoFormat = 'JPEG';
try {
const appData = await getSchoolData();
const logoUrl = firstRow.logo || appData.logo;
if (logoUrl) {
if (logoUrl.startsWith('data:image')) {
logoDataUrl = logoUrl;
logoFormat = logoUrl.toLowerCase().includes('png') ? 'PNG' : (logoUrl.toLowerCase().includes('webp') ? 'WEBP' : 'JPEG');
} else if (logoUrl.startsWith('http')) {
const res = await fetch(logoUrl);
if (res.ok) {
const buffer = Buffer.from(await res.arrayBuffer());
logoFormat = 'PNG';
const pngBuffer = await sharp(buffer).png().toBuffer();
logoDataUrl = `data:image/png;base64,${pngBuffer.toString('base64')}`;
}
}
}
} catch (e) {
console.error('[WhatsApp] Erro ao obter logo:', e.message);
}
const doc = new jsPDF();
let currentY = 10;
// Moldura e Cabeçalho
doc.setDrawColor(0);
doc.setLineWidth(0.5);
doc.rect(10, 10, 190, 100);
if (logoDataUrl) {
try {
doc.addImage(logoDataUrl, logoFormat, 20, currentY + 5, 20, 20, undefined, 'FAST');
} catch(e) {
console.error('[WhatsApp] Erro ao desenhar logo no PDF:', e.message);
}
}
doc.setFontSize(14);
doc.setFont('helvetica', 'bold');
doc.text(profile.name || 'EduManager School', 105, 25, { align: 'center' });
doc.text(profile.name || 'EduManager School', 105, currentY + 15, { align: 'center' });
doc.setFontSize(9);
doc.setFont('helvetica', 'normal');
doc.text(`CNPJ: ${profile.cnpj || '---'} | Contato: ${profile.phone || ''}`, 105, 32, { align: 'center' });
doc.text(`CNPJ: ${profile.cnpj || '---'} | Contato: ${profile.phone || ''}`, 105, currentY + 22, { align: 'center' });
currentY += 40;
doc.setFontSize(16);
doc.text('RECIBO DE PAGAMENTO', 105, 50, { align: 'center' });
doc.setFont('helvetica', 'bold');
doc.text('RECIBO DE PAGAMENTO', 105, currentY, { align: 'center' });
currentY += 15;
doc.setFontSize(11);
doc.text(`Recebemos de: ${aluno.name}`, 20, 65);
doc.text(`A quantia de: R$ ${valorFormatado}`, 20, 75);
doc.text(`Referente a: ${descricao}`, 20, 85);
doc.setFont('helvetica', 'normal');
doc.text(`Recebemos de: ${aluno.name}`, 20, currentY);
currentY += 10;
doc.text(`A quantia de: R$ ${valorFormatado}`, 20, currentY);
currentY += 10;
const refText = `Referente a: ${descricao}`;
const splitRef = doc.splitTextToSize(refText, 170);
doc.text(splitRef, 20, currentY);
currentY += (splitRef.length * 6) + 4;
const dataHj = new Date().toLocaleDateString('pt-BR');
const dataPagamento = fallbackVencimento ? formatCobrancaDate(typeof fallbackVencimento === 'string' ? fallbackVencimento : dataHj) : dataHj;
doc.text(`Data do Pagamento: ${dataPagamento}`, 20, 95);
doc.text(`Data do Pagamento: ${dataPagamento}`, 20, currentY);
doc.line(60, 105, 150, 105);
currentY += 15;
doc.line(60, currentY, 150, currentY);
currentY += 5;
doc.setFontSize(8);
doc.text('Autenticação Digital EduManager', 105, 108, { align: 'center' });
doc.text('Autenticação Digital EduManager', 105, currentY, { align: 'center' });
currentY += 5;
// Moldura Dinâmica
doc.setDrawColor(0);
doc.setLineWidth(0.5);
doc.rect(10, 10, 190, currentY - 10);
const pdfArrayBuffer = doc.output('arraybuffer');
const pdfBuffer = Buffer.from(pdfArrayBuffer);

View File

@ -599,8 +599,12 @@ export const pdfService = {
const typeLabel = payment.type === 'registration' ? 'Taxa de Matrícula' :
payment.type === 'monthly' ? 'Mensalidade do Curso' : 'Outros Serviços';
doc.text(`Referente a: ${typeLabel} ${payment.description ? `(${payment.description})` : ''}`, 20, 95);
doc.text(`Data de Vencimento: ${payment.dueDate ? payment.dueDate.split('T')[0].split('-').reverse().join('/') : ''}`, 20, 105);
const refText = `Referente a: ${typeLabel} ${payment.description ? `(${payment.description})` : ''}`;
const splitRef = doc.splitTextToSize(refText, 170);
doc.text(splitRef, 20, 95);
const nextY = 95 + (splitRef.length * 6);
doc.text(`Data de Vencimento: ${payment.dueDate ? payment.dueDate.split('T')[0].split('-').reverse().join('/') : ''}`, 20, nextY);
if (payment.status === 'paid' && payment.paidDate) {
doc.setFontSize(12);