Files

102 lines
2.7 KiB
TypeScript

import { prisma } from "@/lib/prisma";
import { Prisma } from "@/app/generated/prisma/client";
export const bookingRepo = {
async findById(id: string) {
return prisma.booking.findUnique({ where: { id } });
},
async findByParticipantId(participantId: string) {
return prisma.booking.findUnique({
where: { participantId },
include: { payments: { orderBy: { createdAt: "desc" } } },
});
},
async findByTripAndUser(tripId: string, userId: string) {
return prisma.booking.findUnique({
where: { tripId_userId: { tripId, userId } },
include: { payments: { orderBy: { createdAt: "desc" } } },
});
},
/**
* Detail booking lengkap untuk admin investigation: payments (with raw
* callback), refunds, payout, trip + organizer, user. Dipakai oleh
* `/admin/bookings/[id]` untuk timeline lengkap money flow.
*/
async findByIdForAdmin(id: string) {
return prisma.booking.findUnique({
where: { id },
include: {
trip: {
select: {
id: true,
title: true,
destination: true,
location: true,
date: true,
endDate: true,
price: true,
status: true,
organizer: { select: { id: true, name: true, email: true } },
},
},
user: { select: { id: true, name: true, email: true, image: true } },
participant: true,
payments: { orderBy: { createdAt: "asc" } },
refunds: {
orderBy: { createdAt: "asc" },
include: {
reviewedBy: { select: { id: true, name: true, email: true } },
},
},
payout: {
include: {
processedBy: { select: { id: true, name: true, email: true } },
},
},
},
});
},
async create(
data: Pick<
Prisma.BookingUncheckedCreateInput,
"tripId" | "userId" | "participantId" | "amount" | "status"
>
) {
return prisma.booking.create({ data });
},
async updateStatus(id: string, status: Prisma.BookingUpdateInput["status"]) {
return prisma.booking.update({
where: { id },
data: { status },
});
},
async updateStatusByParticipantId(
participantId: string,
status: Prisma.BookingUpdateInput["status"]
) {
return prisma.booking.updateMany({
where: { participantId },
data: { status },
});
},
/**
* Jumlah booking PAID/PARTIALLY_REFUNDED di trip. Dipakai untuk preview
* dampak cancel-trip (berapa peserta yang akan dapat auto-refund).
*/
async countSettledForTrip(tripId: string) {
return prisma.booking.count({
where: {
tripId,
status: { in: ["PAID", "PARTIALLY_REFUNDED"] },
},
});
},
};