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
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 2m3s
Details
This commit is contained in:
parent
7951787b16
commit
e79b472279
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue