import mail from '@adonisjs/mail/services/main' import env from '#start/env' import { renderTemplate, formatAmountFr, formatDateFr } from '#services/template' import type Invoice from '#models/invoice' import type Client from '#models/client' import type PlanStep from '#models/plan_step' import type User from '#models/user' type RelancePayload = { invoice: Invoice client: Client step: PlanStep user: User | null } /** * Envoie un email de relance à un client à partir d'un step. * Le subject/body du step contiennent des placeholders Mustache-like * (`{{client.name}}`, `{{numero}}`, `{{amount}}`, `{{dueDate}}`, * `{{signature}}`) qu'on interpole avant l'envoi. * * Le mailer effectif est piloté par MAIL_DRIVER (`smtp` Mailpit en dev, * `resend` en prod). */ export async function sendRelanceEmail({ invoice, client, step, user }: RelancePayload) { const vars = { client: { name: client.name, email: client.email }, numero: invoice.numero, amount: formatAmountFr(invoice.amountTtcCents), dueDate: formatDateFr(invoice.dueDate.toJSDate()), issueDate: formatDateFr(invoice.issueDate.toJSDate()), signature: user?.signature ?? user?.fullName ?? '', } const subject = renderTemplate(step.subject, vars) const body = renderTemplate(step.body, vars) const mailer = mail.use(env.get('MAIL_DRIVER', 'smtp')) await mailer.send((m) => { m.from(env.get('MAIL_FROM_ADDRESS', 'relances@rubis-sur-l-ongle.fr'), env.get('MAIL_FROM_NAME', "Rubis Sur l'Ongle")) .to(client.email, client.name) .subject(subject) // Texte brut pour V1 — on ajoutera un template HTML quand on aura // décidé d'un look graphique pour les relances. .text(body) }) } type CheckinPayload = { invoice: Invoice client: Client user: User paidUrl: string pendingUrl: string } /** * Envoie le check-in à l'**utilisateur** (pas au client). Lui demande * si la facture a été payée, avec 2 liens publics qui modifient l'état * côté API et redirigent ensuite vers le SPA. * * Texte brut V1. Un template HTML viendra quand on aura figé le look * graphique (cf. ADR-021). */ export async function sendCheckinEmail({ invoice, client, user, paidUrl, pendingUrl, }: CheckinPayload) { const subject = `Facture ${invoice.numero} — payée par ${client.name} ?` const body = `Bonjour ${user.fullName ?? ''}, La facture ${invoice.numero} (${formatAmountFr(invoice.amountTtcCents)}) émise pour ${client.name} arrive à échéance aujourd'hui (${formatDateFr(invoice.dueDate.toJSDate())}). Avant que Rubis n'envoie la première relance, dites-nous où vous en êtes : ✓ J'ai été payé(e), pas besoin de relancer : ${paidUrl} → Toujours en attente, lance la relance comme prévu : ${pendingUrl} Ces liens expirent dans 24h. Merci, L'équipe Rubis` const mailer = mail.use(env.get('MAIL_DRIVER', 'smtp')) await mailer.send((m) => { m.from(env.get('MAIL_FROM_ADDRESS', 'relances@rubis-sur-l-ongle.fr'), env.get('MAIL_FROM_NAME', "Rubis Sur l'Ongle")) .to(user.email, user.fullName ?? user.email) .subject(subject) .text(body) }) }