Added booking logs to keep track of cancelled bookings and no shows
This commit is contained in:
@@ -77,6 +77,11 @@ export type CourtPriceRule = Prisma.CourtPriceRuleModel
|
||||
*
|
||||
*/
|
||||
export type CourtBooking = Prisma.CourtBookingModel
|
||||
/**
|
||||
* Model CourtBookingLog
|
||||
*
|
||||
*/
|
||||
export type CourtBookingLog = Prisma.CourtBookingLogModel
|
||||
/**
|
||||
* Model OnboardingRequest
|
||||
*
|
||||
|
||||
@@ -101,6 +101,11 @@ export type CourtPriceRule = Prisma.CourtPriceRuleModel
|
||||
*
|
||||
*/
|
||||
export type CourtBooking = Prisma.CourtBookingModel
|
||||
/**
|
||||
* Model CourtBookingLog
|
||||
*
|
||||
*/
|
||||
export type CourtBookingLog = Prisma.CourtBookingLogModel
|
||||
/**
|
||||
* Model OnboardingRequest
|
||||
*
|
||||
|
||||
@@ -33,7 +33,8 @@ export type DayOfWeek = (typeof DayOfWeek)[keyof typeof DayOfWeek]
|
||||
export const CourtBookingStatus = {
|
||||
CONFIRMED: 'CONFIRMED',
|
||||
CANCELLED: 'CANCELLED',
|
||||
COMPLETED: 'COMPLETED'
|
||||
COMPLETED: 'COMPLETED',
|
||||
NOSHOW: 'NOSHOW'
|
||||
} as const
|
||||
|
||||
export type CourtBookingStatus = (typeof CourtBookingStatus)[keyof typeof CourtBookingStatus]
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -396,6 +396,7 @@ export const ModelName = {
|
||||
CourtAvailability: 'CourtAvailability',
|
||||
CourtPriceRule: 'CourtPriceRule',
|
||||
CourtBooking: 'CourtBooking',
|
||||
CourtBookingLog: 'CourtBookingLog',
|
||||
OnboardingRequest: 'OnboardingRequest',
|
||||
PasswordResetRequest: 'PasswordResetRequest',
|
||||
Plan: 'Plan'
|
||||
@@ -414,7 +415,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
omit: GlobalOmitOptions
|
||||
}
|
||||
meta: {
|
||||
modelProps: "user" | "session" | "account" | "verification" | "complex" | "complexUser" | "complexInvitation" | "sport" | "court" | "courtAvailability" | "courtPriceRule" | "courtBooking" | "onboardingRequest" | "passwordResetRequest" | "plan"
|
||||
modelProps: "user" | "session" | "account" | "verification" | "complex" | "complexUser" | "complexInvitation" | "sport" | "court" | "courtAvailability" | "courtPriceRule" | "courtBooking" | "courtBookingLog" | "onboardingRequest" | "passwordResetRequest" | "plan"
|
||||
txIsolationLevel: TransactionIsolationLevel
|
||||
}
|
||||
model: {
|
||||
@@ -1306,6 +1307,80 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
}
|
||||
}
|
||||
}
|
||||
CourtBookingLog: {
|
||||
payload: Prisma.$CourtBookingLogPayload<ExtArgs>
|
||||
fields: Prisma.CourtBookingLogFieldRefs
|
||||
operations: {
|
||||
findUnique: {
|
||||
args: Prisma.CourtBookingLogFindUniqueArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload> | null
|
||||
}
|
||||
findUniqueOrThrow: {
|
||||
args: Prisma.CourtBookingLogFindUniqueOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
findFirst: {
|
||||
args: Prisma.CourtBookingLogFindFirstArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload> | null
|
||||
}
|
||||
findFirstOrThrow: {
|
||||
args: Prisma.CourtBookingLogFindFirstOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
findMany: {
|
||||
args: Prisma.CourtBookingLogFindManyArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>[]
|
||||
}
|
||||
create: {
|
||||
args: Prisma.CourtBookingLogCreateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
createMany: {
|
||||
args: Prisma.CourtBookingLogCreateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
createManyAndReturn: {
|
||||
args: Prisma.CourtBookingLogCreateManyAndReturnArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>[]
|
||||
}
|
||||
delete: {
|
||||
args: Prisma.CourtBookingLogDeleteArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
update: {
|
||||
args: Prisma.CourtBookingLogUpdateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
deleteMany: {
|
||||
args: Prisma.CourtBookingLogDeleteManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
updateMany: {
|
||||
args: Prisma.CourtBookingLogUpdateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
updateManyAndReturn: {
|
||||
args: Prisma.CourtBookingLogUpdateManyAndReturnArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>[]
|
||||
}
|
||||
upsert: {
|
||||
args: Prisma.CourtBookingLogUpsertArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$CourtBookingLogPayload>
|
||||
}
|
||||
aggregate: {
|
||||
args: Prisma.CourtBookingLogAggregateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.AggregateCourtBookingLog>
|
||||
}
|
||||
groupBy: {
|
||||
args: Prisma.CourtBookingLogGroupByArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.CourtBookingLogGroupByOutputType>[]
|
||||
}
|
||||
count: {
|
||||
args: Prisma.CourtBookingLogCountArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.CourtBookingLogCountAggregateOutputType> | number
|
||||
}
|
||||
}
|
||||
}
|
||||
OnboardingRequest: {
|
||||
payload: Prisma.$OnboardingRequestPayload<ExtArgs>
|
||||
fields: Prisma.OnboardingRequestFieldRefs
|
||||
@@ -1738,6 +1813,23 @@ export const CourtBookingScalarFieldEnum = {
|
||||
export type CourtBookingScalarFieldEnum = (typeof CourtBookingScalarFieldEnum)[keyof typeof CourtBookingScalarFieldEnum]
|
||||
|
||||
|
||||
export const CourtBookingLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
bookingCode: 'bookingCode',
|
||||
courtId: 'courtId',
|
||||
bookingDate: 'bookingDate',
|
||||
startTime: 'startTime',
|
||||
endTime: 'endTime',
|
||||
previousStatus: 'previousStatus',
|
||||
newStatus: 'newStatus',
|
||||
customerName: 'customerName',
|
||||
customerPhone: 'customerPhone',
|
||||
changedAt: 'changedAt'
|
||||
} as const
|
||||
|
||||
export type CourtBookingLogScalarFieldEnum = (typeof CourtBookingLogScalarFieldEnum)[keyof typeof CourtBookingLogScalarFieldEnum]
|
||||
|
||||
|
||||
export const OnboardingRequestScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
@@ -2068,6 +2160,7 @@ export type GlobalOmitConfig = {
|
||||
courtAvailability?: Prisma.CourtAvailabilityOmit
|
||||
courtPriceRule?: Prisma.CourtPriceRuleOmit
|
||||
courtBooking?: Prisma.CourtBookingOmit
|
||||
courtBookingLog?: Prisma.CourtBookingLogOmit
|
||||
onboardingRequest?: Prisma.OnboardingRequestOmit
|
||||
passwordResetRequest?: Prisma.PasswordResetRequestOmit
|
||||
plan?: Prisma.PlanOmit
|
||||
|
||||
@@ -63,6 +63,7 @@ export const ModelName = {
|
||||
CourtAvailability: 'CourtAvailability',
|
||||
CourtPriceRule: 'CourtPriceRule',
|
||||
CourtBooking: 'CourtBooking',
|
||||
CourtBookingLog: 'CourtBookingLog',
|
||||
OnboardingRequest: 'OnboardingRequest',
|
||||
PasswordResetRequest: 'PasswordResetRequest',
|
||||
Plan: 'Plan'
|
||||
@@ -255,6 +256,23 @@ export const CourtBookingScalarFieldEnum = {
|
||||
export type CourtBookingScalarFieldEnum = (typeof CourtBookingScalarFieldEnum)[keyof typeof CourtBookingScalarFieldEnum]
|
||||
|
||||
|
||||
export const CourtBookingLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
bookingCode: 'bookingCode',
|
||||
courtId: 'courtId',
|
||||
bookingDate: 'bookingDate',
|
||||
startTime: 'startTime',
|
||||
endTime: 'endTime',
|
||||
previousStatus: 'previousStatus',
|
||||
newStatus: 'newStatus',
|
||||
customerName: 'customerName',
|
||||
customerPhone: 'customerPhone',
|
||||
changedAt: 'changedAt'
|
||||
} as const
|
||||
|
||||
export type CourtBookingLogScalarFieldEnum = (typeof CourtBookingLogScalarFieldEnum)[keyof typeof CourtBookingLogScalarFieldEnum]
|
||||
|
||||
|
||||
export const OnboardingRequestScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
|
||||
@@ -20,6 +20,7 @@ export type * from './models/Court'
|
||||
export type * from './models/CourtAvailability'
|
||||
export type * from './models/CourtPriceRule'
|
||||
export type * from './models/CourtBooking'
|
||||
export type * from './models/CourtBookingLog'
|
||||
export type * from './models/OnboardingRequest'
|
||||
export type * from './models/PasswordResetRequest'
|
||||
export type * from './models/Plan'
|
||||
|
||||
@@ -164,7 +164,7 @@ function mapBookingResponse(booking: {
|
||||
endTime: string;
|
||||
customerName: string;
|
||||
customerPhone: string;
|
||||
status: 'CONFIRMED' | 'CANCELLED' | 'COMPLETED';
|
||||
status: 'CONFIRMED' | 'CANCELLED' | 'COMPLETED' | 'NOSHOW';
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
court: {
|
||||
@@ -494,34 +494,42 @@ export async function updateAdminBookingStatus(
|
||||
);
|
||||
}
|
||||
|
||||
const updated = await db.courtBooking.update({
|
||||
where: { id: booking.id },
|
||||
if(input.status === 'NOSHOW' && booking.status !== 'CONFIRMED') {
|
||||
throw new AdminBookingServiceError(
|
||||
'Solo se pueden marcar como no show las reservas confirmadas.',
|
||||
409
|
||||
);
|
||||
}
|
||||
|
||||
await db.courtBookingLog.create({
|
||||
data: {
|
||||
status:
|
||||
input.status === 'COMPLETED' ? CourtBookingStatus.COMPLETED : CourtBookingStatus.CANCELLED,
|
||||
},
|
||||
include: {
|
||||
court: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
sport: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
},
|
||||
},
|
||||
complex: {
|
||||
select: {
|
||||
id: true,
|
||||
complexName: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
id: uuidv7(),
|
||||
bookingCode: booking.bookingCode,
|
||||
courtId: booking.court.id,
|
||||
bookingDate: booking.bookingDate,
|
||||
startTime: booking.startTime,
|
||||
endTime: booking.endTime,
|
||||
customerName: booking.customerName,
|
||||
customerPhone: booking.customerPhone,
|
||||
previousStatus: booking.status,
|
||||
newStatus: input.status,
|
||||
changedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
return mapBookingResponse(updated);
|
||||
if(input.status === 'COMPLETED' || input.status ==='NOSHOW') {
|
||||
await db.courtBooking.update({
|
||||
where: { id: booking.id },
|
||||
data: {
|
||||
status: input.status,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// if the booking is cancelled we delete it to free up the slot, but we keep a log of it with the cancelled status
|
||||
await db.courtBooking.delete({
|
||||
where: { id: booking.id },
|
||||
})
|
||||
}
|
||||
|
||||
return mapBookingResponse({...booking, status: input.status });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user