import { prisma } from "@/lib/prisma"; import { Prisma } from "@/app/generated/prisma/client"; import type { PayoutStatus } from "@/app/generated/prisma/enums"; const payoutListInclude = { booking: { select: { id: true, amount: true, status: true, user: { select: { id: true, name: true, email: true } }, }, }, trip: { select: { id: true, title: true, date: true, endDate: true, status: true }, }, organizer: { select: { id: true, name: true, email: true } }, processedBy: { select: { id: true, name: true, email: true } }, } satisfies Prisma.PayoutInclude; export const payoutRepo = { async findById(id: string) { return prisma.payout.findUnique({ where: { id }, include: payoutListInclude, }); }, async findByBookingId(bookingId: string, tx?: Prisma.TransactionClient) { const client = tx ?? prisma; return client.payout.findUnique({ where: { bookingId } }); }, async listByStatus( status: PayoutStatus, filters?: { dateFrom?: Date; dateTo?: Date; processorEmail?: string; } ) { const where: Prisma.PayoutWhereInput = { status }; if (filters?.dateFrom || filters?.dateTo) { where.createdAt = { ...(filters.dateFrom && { gte: filters.dateFrom }), ...(filters.dateTo && { lte: filters.dateTo }), }; } if (filters?.processorEmail) { where.processedBy = { email: filters.processorEmail }; } return prisma.payout.findMany({ where, orderBy: { heldUntil: "asc" }, include: payoutListInclude, }); }, async listForOrganizer(organizerId: string) { return prisma.payout.findMany({ where: { organizerId }, orderBy: { createdAt: "desc" }, include: { trip: { select: { id: true, title: true, date: true, endDate: true, status: true }, }, booking: { select: { id: true, amount: true, user: { select: { id: true, name: true } }, }, }, }, }); }, async countByStatus(status: PayoutStatus) { return prisma.payout.count({ where: { status } }); }, /** Payout terbaru untuk satu status — dipakai dashboard admin. */ async listRecent(status: PayoutStatus, limit = 3) { return prisma.payout.findMany({ where: { status }, orderBy: status === "HELD" ? { heldUntil: "asc" } : { updatedAt: "desc" }, take: limit, select: { id: true, amount: true, heldUntil: true, releasedAt: true, organizer: { select: { id: true, name: true } }, trip: { select: { id: true, title: true } }, }, }); }, async create( data: Pick< Prisma.PayoutUncheckedCreateInput, | "bookingId" | "tripId" | "organizerId" | "amount" | "heldUntil" | "bankName" | "bankAccountNumber" | "bankAccountName" >, tx?: Prisma.TransactionClient ) { const client = tx ?? prisma; return client.payout.create({ data }); }, async update( id: string, data: Prisma.PayoutUncheckedUpdateInput, tx?: Prisma.TransactionClient ) { const client = tx ?? prisma; return client.payout.update({ where: { id }, data }); }, /** Cari semua HELD payout yang sudah lewat heldUntil & trip-nya COMPLETED. */ async findEligibleForRelease(now: Date) { return prisma.payout.findMany({ where: { status: "HELD", heldUntil: { lte: now }, trip: { status: "COMPLETED" }, }, select: { id: true }, }); }, }; export type PayoutWithRelations = Awaited>;