diff --git a/backend/src/routes/invoices.ts b/backend/src/routes/invoices.ts index c5b2231..a3c3b8d 100644 --- a/backend/src/routes/invoices.ts +++ b/backend/src/routes/invoices.ts @@ -330,7 +330,7 @@ router.post('/:id/send', wrap(async (req: AuthRequest, res: Response): Promise a.order - b.order) .map((img) => path.join(config.uploadsDir, 'images', img.path)); - await generateInvoicePdf(imagePaths, invoice.guests, pdfPath); + await generateInvoicePdf(imagePaths, invoice.guests, pdfPath, user.name); // ── Envoi email ─────────────────────────────────────────── await sendInvoiceEmail(user, invoice.company_email, pdfPath, pdfFilename); diff --git a/backend/src/services/pdf.ts b/backend/src/services/pdf.ts index a3398e1..ea37df4 100644 --- a/backend/src/services/pdf.ts +++ b/backend/src/services/pdf.ts @@ -15,11 +15,13 @@ export interface PdfGuest { * - Une page par image (ticket/reçu) * - Si des invités sont présents, la liste est ajoutée EN BAS de la dernière * page d'image (même page, sous le ticket), sans page séparée. + * - userName : prénom affiché dans l'en-tête "Invité par …" */ export async function generateInvoicePdf( imagePaths: string[], guests: PdfGuest[], - outputPath: string + outputPath: string, + userName = 'Moi' ): Promise { const pdfDoc = await PDFDocument.create(); @@ -37,7 +39,7 @@ export async function generateInvoicePdf( // Normaliser à une largeur A4 (595pt) pour que la section invités // soit visible. Sans normalisation, image.width est en pixels // (ex. 3024px), ce qui donne une page de 42 pouces de large et - // rend la section invités (~134pt) imperceptible en bas de page. + // rend la section invités imperceptible en bas de page. const PAGE_W = 595; const scale = PAGE_W / image.width; const imgW = PAGE_W; @@ -47,9 +49,9 @@ export async function generateInvoicePdf( const addList = isLast && guests.length > 0; // Hauteur supplémentaire pour la liste d'invités (sous le ticket) - const PADDING = 20; // marge entre ticket et liste - const LINE_H = 22; // hauteur par ligne d'invité - const HEADER_H = 50; // titre + séparateur + const PADDING = 24; // marge entre ticket et liste + const LINE_H = 44; // hauteur par ligne d'invité (×2) + const HEADER_H = 80; // titre + séparateur (×2) const listH = addList ? HEADER_H + guests.length * LINE_H + PADDING * 2 : 0; @@ -75,14 +77,14 @@ export async function generateInvoicePdf( color: rgb(0.8, 0.8, 0.8), }); - // Titre - page.drawText('Invités', { + // Titre "Invité par " + page.drawText(`Invité par ${userName}`, { x: M, y, - size: 13, + size: 26, font: fontBold, color: rgb(0.15, 0.15, 0.15), }); - y -= HEADER_H - PADDING - 8; + y -= HEADER_H - PADDING - 10; // Séparateur sous le titre page.drawLine({ @@ -91,14 +93,14 @@ export async function generateInvoicePdf( thickness: 0.5, color: rgb(0.75, 0.75, 0.75), }); - y -= 16; + y -= 22; // Lignes invités for (const guest of guests) { if (y < 4) break; page.drawText(guest.name, { x: M, y, - size: 11, + size: 22, font: fontBold, color: rgb(0.1, 0.1, 0.1), maxWidth: guest.company ? (pageW - M * 2) / 2 - 10 : pageW - M * 2, @@ -107,7 +109,7 @@ export async function generateInvoicePdf( page.drawText(guest.company, { x: M + (pageW - M * 2) / 2, y, - size: 11, + size: 22, font, color: rgb(0.35, 0.35, 0.35), maxWidth: (pageW - M * 2) / 2,