diff --git a/apps/api/app/controllers/clients_controller.ts b/apps/api/app/controllers/clients_controller.ts index 78b7759..fd74d50 100644 --- a/apps/api/app/controllers/clients_controller.ts +++ b/apps/api/app/controllers/clients_controller.ts @@ -1,10 +1,22 @@ import Client from '#models/client' +import Invoice from '#models/invoice' import ClientTransformer from '#transformers/client_transformer' +import InvoiceTransformer from '#transformers/invoice_transformer' import { createClientValidator, updateClientValidator } from '#validators/client' import { bulkComputeClientStats } from '#services/client_stats' import type { HttpContext } from '@adonisjs/core/http' import { Exception } from '@adonisjs/core/exceptions' +// Priorité d'affichage : ce qui est actionnable en haut. +const INVOICE_STATUS_PRIORITY: Record = { + awaiting_user_confirmation: 0, + in_relance: 1, + pending: 2, + litigation: 3, + paid: 4, + cancelled: 5, +} + /** * Petite cohérence d'identification orgnisation : si l'utilisateur * n'en a pas, on est dans un état illégal V1 — on bloque ferme. @@ -96,11 +108,27 @@ export default class ClientsController { const statsMap = await bulkComputeClientStats(organizationId, [client.id]) const stats = statsMap.get(client.id)! + // Factures du client — actionnables en premier, puis échéance asc. + const invoices = await Invoice.query() + .where('organization_id', organizationId) + .where('client_id', client.id) + .preload('client') + .preload('plan') + .exec() + + invoices.sort((a, b) => { + const dp = + (INVOICE_STATUS_PRIORITY[a.status] ?? 99) - + (INVOICE_STATUS_PRIORITY[b.status] ?? 99) + if (dp !== 0) return dp + return a.dueDate.toMillis() - b.dueDate.toMillis() + }) + return response.json({ data: { ...serializeClient(client), ...stats, - invoices: [], // TODO: brancher quand le domaine Invoice arrive + invoices: invoices.map((inv) => new InvoiceTransformer(inv).toObject()), }, }) }