Files
playzer/apps/backend/src/modules/admin-booking/features/update-admin-booking-status/update-admin-booking-status.business.ts
2026-06-26 14:05:37 -03:00

77 lines
2.3 KiB
TypeScript

import { Errors } from '@/lib/errors';
import { db } from '@/lib/prisma';
import type { Result } from '@/lib/result';
import { err, ok } from '@/lib/result';
import type { UpdateAdminBookingStatusInput } from '@repo/api-contract';
import { v7 as uuidv7 } from 'uuid';
import { mapBookingResponse } from '../../shared/helpers';
export async function updateAdminBookingStatus(
userId: string,
bookingId: string,
input: UpdateAdminBookingStatusInput
): Promise<Result<ReturnType<typeof mapBookingResponse>>> {
const booking = await db.courtBooking.findFirst({
where: {
id: bookingId,
court: {
complex: { users: { some: { userId } } },
},
},
include: {
court: {
select: {
id: true,
name: true,
sport: { select: { id: true, name: true, slug: true } },
complex: { select: { id: true, complexName: true } },
},
},
},
});
if (!booking) {
return err(Errors.notFound('Reserva no encontrada.'));
}
if (input.status === 'CANCELLED' && booking.status !== 'CONFIRMED') {
return err(Errors.conflict('Solo se pueden cancelar reservas en estado confirmada.'));
}
if (input.status === 'COMPLETED' && booking.status !== 'CONFIRMED') {
return err(Errors.conflict('Solo se pueden marcar como cumplidas las reservas confirmadas.'));
}
if (input.status === 'NOSHOW' && booking.status !== 'CONFIRMED') {
return err(Errors.conflict('Solo se pueden marcar como no show las reservas confirmadas.'));
}
await db.courtBookingLog.create({
data: {
id: uuidv7(),
bookingCode: booking.bookingCode,
courtId: booking.court.id,
bookingDate: booking.bookingDate,
startTime: booking.startTime,
endTime: booking.endTime,
customerName: booking.customerName,
customerPhone: booking.customerPhone,
customerEmail: booking.customerEmail,
previousStatus: booking.status,
newStatus: input.status,
changedAt: new Date(),
},
});
if (input.status === 'COMPLETED' || input.status === 'NOSHOW') {
await db.courtBooking.update({
where: { id: booking.id },
data: { status: input.status },
});
} else {
await db.courtBooking.delete({ where: { id: booking.id } });
}
return ok(mapBookingResponse({ ...booking, status: input.status }));
}