"feat-pdf-bigger-font-invite-par-user"
This commit is contained in:
@@ -330,7 +330,7 @@ router.post('/:id/send', wrap(async (req: AuthRequest, res: Response): Promise<v
|
|||||||
.sort((a, b) => a.order - b.order)
|
.sort((a, b) => a.order - b.order)
|
||||||
.map((img) => path.join(config.uploadsDir, 'images', img.path));
|
.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 ───────────────────────────────────────────
|
// ── Envoi email ───────────────────────────────────────────
|
||||||
await sendInvoiceEmail(user, invoice.company_email, pdfPath, pdfFilename);
|
await sendInvoiceEmail(user, invoice.company_email, pdfPath, pdfFilename);
|
||||||
|
|||||||
+14
-12
@@ -15,11 +15,13 @@ export interface PdfGuest {
|
|||||||
* - Une page par image (ticket/reçu)
|
* - 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
|
* - 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.
|
* 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(
|
export async function generateInvoicePdf(
|
||||||
imagePaths: string[],
|
imagePaths: string[],
|
||||||
guests: PdfGuest[],
|
guests: PdfGuest[],
|
||||||
outputPath: string
|
outputPath: string,
|
||||||
|
userName = 'Moi'
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const pdfDoc = await PDFDocument.create();
|
const pdfDoc = await PDFDocument.create();
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ export async function generateInvoicePdf(
|
|||||||
// Normaliser à une largeur A4 (595pt) pour que la section invités
|
// Normaliser à une largeur A4 (595pt) pour que la section invités
|
||||||
// soit visible. Sans normalisation, image.width est en pixels
|
// soit visible. Sans normalisation, image.width est en pixels
|
||||||
// (ex. 3024px), ce qui donne une page de 42 pouces de large et
|
// (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 PAGE_W = 595;
|
||||||
const scale = PAGE_W / image.width;
|
const scale = PAGE_W / image.width;
|
||||||
const imgW = PAGE_W;
|
const imgW = PAGE_W;
|
||||||
@@ -47,9 +49,9 @@ export async function generateInvoicePdf(
|
|||||||
const addList = isLast && guests.length > 0;
|
const addList = isLast && guests.length > 0;
|
||||||
|
|
||||||
// Hauteur supplémentaire pour la liste d'invités (sous le ticket)
|
// Hauteur supplémentaire pour la liste d'invités (sous le ticket)
|
||||||
const PADDING = 20; // marge entre ticket et liste
|
const PADDING = 24; // marge entre ticket et liste
|
||||||
const LINE_H = 22; // hauteur par ligne d'invité
|
const LINE_H = 44; // hauteur par ligne d'invité (×2)
|
||||||
const HEADER_H = 50; // titre + séparateur
|
const HEADER_H = 80; // titre + séparateur (×2)
|
||||||
const listH = addList
|
const listH = addList
|
||||||
? HEADER_H + guests.length * LINE_H + PADDING * 2
|
? HEADER_H + guests.length * LINE_H + PADDING * 2
|
||||||
: 0;
|
: 0;
|
||||||
@@ -75,14 +77,14 @@ export async function generateInvoicePdf(
|
|||||||
color: rgb(0.8, 0.8, 0.8),
|
color: rgb(0.8, 0.8, 0.8),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Titre
|
// Titre "Invité par <prénom>"
|
||||||
page.drawText('Invités', {
|
page.drawText(`Invité par ${userName}`, {
|
||||||
x: M, y,
|
x: M, y,
|
||||||
size: 13,
|
size: 26,
|
||||||
font: fontBold,
|
font: fontBold,
|
||||||
color: rgb(0.15, 0.15, 0.15),
|
color: rgb(0.15, 0.15, 0.15),
|
||||||
});
|
});
|
||||||
y -= HEADER_H - PADDING - 8;
|
y -= HEADER_H - PADDING - 10;
|
||||||
|
|
||||||
// Séparateur sous le titre
|
// Séparateur sous le titre
|
||||||
page.drawLine({
|
page.drawLine({
|
||||||
@@ -91,14 +93,14 @@ export async function generateInvoicePdf(
|
|||||||
thickness: 0.5,
|
thickness: 0.5,
|
||||||
color: rgb(0.75, 0.75, 0.75),
|
color: rgb(0.75, 0.75, 0.75),
|
||||||
});
|
});
|
||||||
y -= 16;
|
y -= 22;
|
||||||
|
|
||||||
// Lignes invités
|
// Lignes invités
|
||||||
for (const guest of guests) {
|
for (const guest of guests) {
|
||||||
if (y < 4) break;
|
if (y < 4) break;
|
||||||
page.drawText(guest.name, {
|
page.drawText(guest.name, {
|
||||||
x: M, y,
|
x: M, y,
|
||||||
size: 11,
|
size: 22,
|
||||||
font: fontBold,
|
font: fontBold,
|
||||||
color: rgb(0.1, 0.1, 0.1),
|
color: rgb(0.1, 0.1, 0.1),
|
||||||
maxWidth: guest.company ? (pageW - M * 2) / 2 - 10 : pageW - M * 2,
|
maxWidth: guest.company ? (pageW - M * 2) / 2 - 10 : pageW - M * 2,
|
||||||
@@ -107,7 +109,7 @@ export async function generateInvoicePdf(
|
|||||||
page.drawText(guest.company, {
|
page.drawText(guest.company, {
|
||||||
x: M + (pageW - M * 2) / 2,
|
x: M + (pageW - M * 2) / 2,
|
||||||
y,
|
y,
|
||||||
size: 11,
|
size: 22,
|
||||||
font,
|
font,
|
||||||
color: rgb(0.35, 0.35, 0.35),
|
color: rgb(0.35, 0.35, 0.35),
|
||||||
maxWidth: (pageW - M * 2) / 2,
|
maxWidth: (pageW - M * 2) / 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user