import "server-only"; import { BookingStatus, RentalBookingStatus, } from "@/generated/prisma/enums"; import { prisma } from "@/lib/prisma"; /** * KPIs agrégés à l'échelle d'une organisation CE. * - carbets : nombre de carbets co-gérés via OrganizationCarbetMembership * - rentalItems : items des providers liés à l'org * - bookings30d : bookings confirmées sur les carbets de l'org (30 derniers jours) * - rentalBookings30d : RentalBooking confirmées sur les providers de l'org * - revenue30d : somme des amounts (booking + rental) sur 30j */ export async function getCeOrgKpis(organizationId: string) { const since = new Date(Date.now() - 30 * 86_400_000); const [carbetsCount, providers, bookings30d, rentalBookings30d] = await Promise.all([ prisma.organizationCarbetMembership.count({ where: { organizationId } }), prisma.rentalProvider.findMany({ where: { organizationId }, select: { id: true, approved: true, active: true, _count: { select: { items: true } }, }, }), prisma.booking.findMany({ where: { status: BookingStatus.CONFIRMED, createdAt: { gte: since }, carbet: { organizations: { some: { organizationId } } }, }, select: { amount: true, currency: true }, }), prisma.rentalBooking.findMany({ where: { status: RentalBookingStatus.CONFIRMED, createdAt: { gte: since }, provider: { organizationId }, }, select: { amount: true, currency: true }, }), ]); const itemsCount = providers.reduce((s, p) => s + p._count.items, 0); const revenue30d = [ ...bookings30d.map((b) => Number(b.amount)), ...rentalBookings30d.map((r) => Number(r.amount)), ].reduce((s, n) => s + n, 0); return { carbetsCount, providersCount: providers.length, rentalItemsCount: itemsCount, rentalProviderApproved: providers.every((p) => p.approved), bookings30dCount: bookings30d.length, rentalBookings30dCount: rentalBookings30d.length, revenue30d, }; } /** * Liste les carbets co-gérés par une org (joinés via membership). */ export async function listCeCarbets(organizationId: string) { const memberships = await prisma.organizationCarbetMembership.findMany({ where: { organizationId }, orderBy: { addedAt: "desc" }, select: { carbet: { select: { id: true, slug: true, title: true, river: true, status: true, capacity: true, nightlyPrice: true, ownerId: true, owner: { select: { firstName: true, lastName: true } }, }, }, }, }); return memberships.map((m) => m.carbet); }