102 lines
2.7 KiB
TypeScript
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"] },
|
|
},
|
|
});
|
|
},
|
|
};
|