feat: add price field to CourtBooking model and related schemas
- Added `price` field to `CourtBookingScalarFieldEnum` in `prismaNamespace.ts` and `prismaNamespaceBrowser.ts`. - Updated `CourtBooking` model to include average and sum aggregations for `price`. - Enhanced input types and aggregate input types to support `price`. - Modified `public-booking.service.ts` to calculate and return price information for bookings. - Updated frontend components to display price information in booking confirmation and selection pages. - Introduced `priceRangeSchema` in API contract to validate price ranges.
This commit is contained in:
@@ -82,6 +82,7 @@ model CourtBooking {
|
||||
bookingDate DateTime @map("booking_date") @db.Date
|
||||
startTime String @map("start_time") @db.VarChar(5)
|
||||
endTime String @map("end_time") @db.VarChar(5)
|
||||
price Decimal? @map("price") @db.Decimal(19, 2)
|
||||
customerName String @map("customer_name") @db.VarChar(120)
|
||||
customerPhone String @map("customer_phone") @db.VarChar(30)
|
||||
status CourtBookingStatus @default(CONFIRMED)
|
||||
|
||||
@@ -280,6 +280,17 @@ export type EnumDayOfWeekNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
_max?: Prisma.NestedEnumDayOfWeekNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type DecimalNullableFilter<$PrismaModel = never> = {
|
||||
equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
|
||||
in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type EnumCourtBookingStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
@@ -287,6 +298,22 @@ export type EnumCourtBookingStatusFilter<$PrismaModel = never> = {
|
||||
not?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> | $Enums.CourtBookingStatus
|
||||
}
|
||||
|
||||
export type DecimalNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
|
||||
in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type EnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
@@ -625,6 +652,17 @@ export type NestedEnumDayOfWeekNullableWithAggregatesFilter<$PrismaModel = never
|
||||
_max?: Prisma.NestedEnumDayOfWeekNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedDecimalNullableFilter<$PrismaModel = never> = {
|
||||
equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
|
||||
in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
}
|
||||
|
||||
export type NestedEnumCourtBookingStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
@@ -632,6 +670,22 @@ export type NestedEnumCourtBookingStatusFilter<$PrismaModel = never> = {
|
||||
not?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> | $Enums.CourtBookingStatus
|
||||
}
|
||||
|
||||
export type NestedDecimalNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null
|
||||
in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedDecimalNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedEnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1728,6 +1728,7 @@ export const CourtBookingScalarFieldEnum = {
|
||||
bookingDate: 'bookingDate',
|
||||
startTime: 'startTime',
|
||||
endTime: 'endTime',
|
||||
price: 'price',
|
||||
customerName: 'customerName',
|
||||
customerPhone: 'customerPhone',
|
||||
status: 'status',
|
||||
|
||||
@@ -245,6 +245,7 @@ export const CourtBookingScalarFieldEnum = {
|
||||
bookingDate: 'bookingDate',
|
||||
startTime: 'startTime',
|
||||
endTime: 'endTime',
|
||||
price: 'price',
|
||||
customerName: 'customerName',
|
||||
customerPhone: 'customerPhone',
|
||||
status: 'status',
|
||||
|
||||
@@ -20,10 +20,20 @@ export type CourtBookingModel = runtime.Types.Result.DefaultSelection<Prisma.$Co
|
||||
|
||||
export type AggregateCourtBooking = {
|
||||
_count: CourtBookingCountAggregateOutputType | null
|
||||
_avg: CourtBookingAvgAggregateOutputType | null
|
||||
_sum: CourtBookingSumAggregateOutputType | null
|
||||
_min: CourtBookingMinAggregateOutputType | null
|
||||
_max: CourtBookingMaxAggregateOutputType | null
|
||||
}
|
||||
|
||||
export type CourtBookingAvgAggregateOutputType = {
|
||||
price: runtime.Decimal | null
|
||||
}
|
||||
|
||||
export type CourtBookingSumAggregateOutputType = {
|
||||
price: runtime.Decimal | null
|
||||
}
|
||||
|
||||
export type CourtBookingMinAggregateOutputType = {
|
||||
id: string | null
|
||||
bookingCode: string | null
|
||||
@@ -31,6 +41,7 @@ export type CourtBookingMinAggregateOutputType = {
|
||||
bookingDate: Date | null
|
||||
startTime: string | null
|
||||
endTime: string | null
|
||||
price: runtime.Decimal | null
|
||||
customerName: string | null
|
||||
customerPhone: string | null
|
||||
status: $Enums.CourtBookingStatus | null
|
||||
@@ -45,6 +56,7 @@ export type CourtBookingMaxAggregateOutputType = {
|
||||
bookingDate: Date | null
|
||||
startTime: string | null
|
||||
endTime: string | null
|
||||
price: runtime.Decimal | null
|
||||
customerName: string | null
|
||||
customerPhone: string | null
|
||||
status: $Enums.CourtBookingStatus | null
|
||||
@@ -59,6 +71,7 @@ export type CourtBookingCountAggregateOutputType = {
|
||||
bookingDate: number
|
||||
startTime: number
|
||||
endTime: number
|
||||
price: number
|
||||
customerName: number
|
||||
customerPhone: number
|
||||
status: number
|
||||
@@ -68,6 +81,14 @@ export type CourtBookingCountAggregateOutputType = {
|
||||
}
|
||||
|
||||
|
||||
export type CourtBookingAvgAggregateInputType = {
|
||||
price?: true
|
||||
}
|
||||
|
||||
export type CourtBookingSumAggregateInputType = {
|
||||
price?: true
|
||||
}
|
||||
|
||||
export type CourtBookingMinAggregateInputType = {
|
||||
id?: true
|
||||
bookingCode?: true
|
||||
@@ -75,6 +96,7 @@ export type CourtBookingMinAggregateInputType = {
|
||||
bookingDate?: true
|
||||
startTime?: true
|
||||
endTime?: true
|
||||
price?: true
|
||||
customerName?: true
|
||||
customerPhone?: true
|
||||
status?: true
|
||||
@@ -89,6 +111,7 @@ export type CourtBookingMaxAggregateInputType = {
|
||||
bookingDate?: true
|
||||
startTime?: true
|
||||
endTime?: true
|
||||
price?: true
|
||||
customerName?: true
|
||||
customerPhone?: true
|
||||
status?: true
|
||||
@@ -103,6 +126,7 @@ export type CourtBookingCountAggregateInputType = {
|
||||
bookingDate?: true
|
||||
startTime?: true
|
||||
endTime?: true
|
||||
price?: true
|
||||
customerName?: true
|
||||
customerPhone?: true
|
||||
status?: true
|
||||
@@ -146,6 +170,18 @@ export type CourtBookingAggregateArgs<ExtArgs extends runtime.Types.Extensions.I
|
||||
* Count returned CourtBookings
|
||||
**/
|
||||
_count?: true | CourtBookingCountAggregateInputType
|
||||
/**
|
||||
* {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs}
|
||||
*
|
||||
* Select which fields to average
|
||||
**/
|
||||
_avg?: CourtBookingAvgAggregateInputType
|
||||
/**
|
||||
* {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs}
|
||||
*
|
||||
* Select which fields to sum
|
||||
**/
|
||||
_sum?: CourtBookingSumAggregateInputType
|
||||
/**
|
||||
* {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs}
|
||||
*
|
||||
@@ -179,6 +215,8 @@ export type CourtBookingGroupByArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
take?: number
|
||||
skip?: number
|
||||
_count?: CourtBookingCountAggregateInputType | true
|
||||
_avg?: CourtBookingAvgAggregateInputType
|
||||
_sum?: CourtBookingSumAggregateInputType
|
||||
_min?: CourtBookingMinAggregateInputType
|
||||
_max?: CourtBookingMaxAggregateInputType
|
||||
}
|
||||
@@ -190,12 +228,15 @@ export type CourtBookingGroupByOutputType = {
|
||||
bookingDate: Date
|
||||
startTime: string
|
||||
endTime: string
|
||||
price: runtime.Decimal | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status: $Enums.CourtBookingStatus
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
_count: CourtBookingCountAggregateOutputType | null
|
||||
_avg: CourtBookingAvgAggregateOutputType | null
|
||||
_sum: CourtBookingSumAggregateOutputType | null
|
||||
_min: CourtBookingMinAggregateOutputType | null
|
||||
_max: CourtBookingMaxAggregateOutputType | null
|
||||
}
|
||||
@@ -225,6 +266,7 @@ export type CourtBookingWhereInput = {
|
||||
bookingDate?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
|
||||
startTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
endTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
price?: Prisma.DecimalNullableFilter<"CourtBooking"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
|
||||
@@ -240,6 +282,7 @@ export type CourtBookingOrderByWithRelationInput = {
|
||||
bookingDate?: Prisma.SortOrder
|
||||
startTime?: Prisma.SortOrder
|
||||
endTime?: Prisma.SortOrder
|
||||
price?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customerName?: Prisma.SortOrder
|
||||
customerPhone?: Prisma.SortOrder
|
||||
status?: Prisma.SortOrder
|
||||
@@ -259,6 +302,7 @@ export type CourtBookingWhereUniqueInput = Prisma.AtLeast<{
|
||||
bookingDate?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
|
||||
startTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
endTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
price?: Prisma.DecimalNullableFilter<"CourtBooking"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
|
||||
@@ -274,14 +318,17 @@ export type CourtBookingOrderByWithAggregationInput = {
|
||||
bookingDate?: Prisma.SortOrder
|
||||
startTime?: Prisma.SortOrder
|
||||
endTime?: Prisma.SortOrder
|
||||
price?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
customerName?: Prisma.SortOrder
|
||||
customerPhone?: Prisma.SortOrder
|
||||
status?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_count?: Prisma.CourtBookingCountOrderByAggregateInput
|
||||
_avg?: Prisma.CourtBookingAvgOrderByAggregateInput
|
||||
_max?: Prisma.CourtBookingMaxOrderByAggregateInput
|
||||
_min?: Prisma.CourtBookingMinOrderByAggregateInput
|
||||
_sum?: Prisma.CourtBookingSumOrderByAggregateInput
|
||||
}
|
||||
|
||||
export type CourtBookingScalarWhereWithAggregatesInput = {
|
||||
@@ -294,6 +341,7 @@ export type CourtBookingScalarWhereWithAggregatesInput = {
|
||||
bookingDate?: Prisma.DateTimeWithAggregatesFilter<"CourtBooking"> | Date | string
|
||||
startTime?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
|
||||
endTime?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
|
||||
price?: Prisma.DecimalNullableWithAggregatesFilter<"CourtBooking"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
|
||||
customerPhone?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string
|
||||
status?: Prisma.EnumCourtBookingStatusWithAggregatesFilter<"CourtBooking"> | $Enums.CourtBookingStatus
|
||||
@@ -307,6 +355,7 @@ export type CourtBookingCreateInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -322,6 +371,7 @@ export type CourtBookingUncheckedCreateInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -335,6 +385,7 @@ export type CourtBookingUpdateInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -350,6 +401,7 @@ export type CourtBookingUncheckedUpdateInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -364,6 +416,7 @@ export type CourtBookingCreateManyInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -377,6 +430,7 @@ export type CourtBookingUpdateManyMutationInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -391,6 +445,7 @@ export type CourtBookingUncheckedUpdateManyInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -421,6 +476,7 @@ export type CourtBookingCountOrderByAggregateInput = {
|
||||
bookingDate?: Prisma.SortOrder
|
||||
startTime?: Prisma.SortOrder
|
||||
endTime?: Prisma.SortOrder
|
||||
price?: Prisma.SortOrder
|
||||
customerName?: Prisma.SortOrder
|
||||
customerPhone?: Prisma.SortOrder
|
||||
status?: Prisma.SortOrder
|
||||
@@ -428,6 +484,10 @@ export type CourtBookingCountOrderByAggregateInput = {
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CourtBookingAvgOrderByAggregateInput = {
|
||||
price?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CourtBookingMaxOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
bookingCode?: Prisma.SortOrder
|
||||
@@ -435,6 +495,7 @@ export type CourtBookingMaxOrderByAggregateInput = {
|
||||
bookingDate?: Prisma.SortOrder
|
||||
startTime?: Prisma.SortOrder
|
||||
endTime?: Prisma.SortOrder
|
||||
price?: Prisma.SortOrder
|
||||
customerName?: Prisma.SortOrder
|
||||
customerPhone?: Prisma.SortOrder
|
||||
status?: Prisma.SortOrder
|
||||
@@ -449,6 +510,7 @@ export type CourtBookingMinOrderByAggregateInput = {
|
||||
bookingDate?: Prisma.SortOrder
|
||||
startTime?: Prisma.SortOrder
|
||||
endTime?: Prisma.SortOrder
|
||||
price?: Prisma.SortOrder
|
||||
customerName?: Prisma.SortOrder
|
||||
customerPhone?: Prisma.SortOrder
|
||||
status?: Prisma.SortOrder
|
||||
@@ -456,6 +518,10 @@ export type CourtBookingMinOrderByAggregateInput = {
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CourtBookingSumOrderByAggregateInput = {
|
||||
price?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CourtBookingCreateNestedManyWithoutCourtInput = {
|
||||
create?: Prisma.XOR<Prisma.CourtBookingCreateWithoutCourtInput, Prisma.CourtBookingUncheckedCreateWithoutCourtInput> | Prisma.CourtBookingCreateWithoutCourtInput[] | Prisma.CourtBookingUncheckedCreateWithoutCourtInput[]
|
||||
connectOrCreate?: Prisma.CourtBookingCreateOrConnectWithoutCourtInput | Prisma.CourtBookingCreateOrConnectWithoutCourtInput[]
|
||||
@@ -498,6 +564,14 @@ export type CourtBookingUncheckedUpdateManyWithoutCourtNestedInput = {
|
||||
deleteMany?: Prisma.CourtBookingScalarWhereInput | Prisma.CourtBookingScalarWhereInput[]
|
||||
}
|
||||
|
||||
export type NullableDecimalFieldUpdateOperationsInput = {
|
||||
set?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
increment?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
decrement?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
multiply?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
divide?: runtime.Decimal | runtime.DecimalJsLike | number | string
|
||||
}
|
||||
|
||||
export type EnumCourtBookingStatusFieldUpdateOperationsInput = {
|
||||
set?: $Enums.CourtBookingStatus
|
||||
}
|
||||
@@ -508,6 +582,7 @@ export type CourtBookingCreateWithoutCourtInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -521,6 +596,7 @@ export type CourtBookingUncheckedCreateWithoutCourtInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -564,6 +640,7 @@ export type CourtBookingScalarWhereInput = {
|
||||
bookingDate?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string
|
||||
startTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
endTime?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
price?: Prisma.DecimalNullableFilter<"CourtBooking"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
customerPhone?: Prisma.StringFilter<"CourtBooking"> | string
|
||||
status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus
|
||||
@@ -577,6 +654,7 @@ export type CourtBookingCreateManyCourtInput = {
|
||||
bookingDate: Date | string
|
||||
startTime: string
|
||||
endTime: string
|
||||
price?: runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status?: $Enums.CourtBookingStatus
|
||||
@@ -590,6 +668,7 @@ export type CourtBookingUpdateWithoutCourtInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -603,6 +682,7 @@ export type CourtBookingUncheckedUpdateWithoutCourtInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -616,6 +696,7 @@ export type CourtBookingUncheckedUpdateManyWithoutCourtInput = {
|
||||
bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
startTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
endTime?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
price?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null
|
||||
customerName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
customerPhone?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus
|
||||
@@ -632,6 +713,7 @@ export type CourtBookingSelect<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
bookingDate?: boolean
|
||||
startTime?: boolean
|
||||
endTime?: boolean
|
||||
price?: boolean
|
||||
customerName?: boolean
|
||||
customerPhone?: boolean
|
||||
status?: boolean
|
||||
@@ -647,6 +729,7 @@ export type CourtBookingSelectCreateManyAndReturn<ExtArgs extends runtime.Types.
|
||||
bookingDate?: boolean
|
||||
startTime?: boolean
|
||||
endTime?: boolean
|
||||
price?: boolean
|
||||
customerName?: boolean
|
||||
customerPhone?: boolean
|
||||
status?: boolean
|
||||
@@ -662,6 +745,7 @@ export type CourtBookingSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.
|
||||
bookingDate?: boolean
|
||||
startTime?: boolean
|
||||
endTime?: boolean
|
||||
price?: boolean
|
||||
customerName?: boolean
|
||||
customerPhone?: boolean
|
||||
status?: boolean
|
||||
@@ -677,6 +761,7 @@ export type CourtBookingSelectScalar = {
|
||||
bookingDate?: boolean
|
||||
startTime?: boolean
|
||||
endTime?: boolean
|
||||
price?: boolean
|
||||
customerName?: boolean
|
||||
customerPhone?: boolean
|
||||
status?: boolean
|
||||
@@ -684,7 +769,7 @@ export type CourtBookingSelectScalar = {
|
||||
updatedAt?: boolean
|
||||
}
|
||||
|
||||
export type CourtBookingOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "customerName" | "customerPhone" | "status" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]>
|
||||
export type CourtBookingOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "price" | "customerName" | "customerPhone" | "status" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]>
|
||||
export type CourtBookingInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
court?: boolean | Prisma.CourtDefaultArgs<ExtArgs>
|
||||
}
|
||||
@@ -707,6 +792,7 @@ export type $CourtBookingPayload<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
bookingDate: Date
|
||||
startTime: string
|
||||
endTime: string
|
||||
price: runtime.Decimal | null
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
status: $Enums.CourtBookingStatus
|
||||
@@ -1142,6 +1228,7 @@ export interface CourtBookingFieldRefs {
|
||||
readonly bookingDate: Prisma.FieldRef<"CourtBooking", 'DateTime'>
|
||||
readonly startTime: Prisma.FieldRef<"CourtBooking", 'String'>
|
||||
readonly endTime: Prisma.FieldRef<"CourtBooking", 'String'>
|
||||
readonly price: Prisma.FieldRef<"CourtBooking", 'Decimal'>
|
||||
readonly customerName: Prisma.FieldRef<"CourtBooking", 'String'>
|
||||
readonly customerPhone: Prisma.FieldRef<"CourtBooking", 'String'>
|
||||
readonly status: Prisma.FieldRef<"CourtBooking", 'CourtBookingStatus'>
|
||||
|
||||
@@ -202,6 +202,10 @@ async function getComplexWithBookingData(complexSlug: string) {
|
||||
availabilities: {
|
||||
orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }],
|
||||
},
|
||||
priceRules: {
|
||||
where: { isActive: true },
|
||||
orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }],
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'asc' },
|
||||
},
|
||||
@@ -233,6 +237,7 @@ function mapBookingResponse(input: {
|
||||
createdAt: Date;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
price: number;
|
||||
customerName: string;
|
||||
customerPhone: string;
|
||||
status: 'CONFIRMED' | 'CANCELLED' | 'COMPLETED';
|
||||
@@ -261,6 +266,7 @@ function mapBookingResponse(input: {
|
||||
date: formatIsoDate(input.bookingDate),
|
||||
startTime: input.startTime,
|
||||
endTime: input.endTime,
|
||||
price: input.price,
|
||||
customerName: input.customerName,
|
||||
customerPhone: input.customerPhone,
|
||||
status: input.status,
|
||||
@@ -284,6 +290,7 @@ export async function getPublicBookingConfirmation(complexSlug: string, bookingC
|
||||
bookingDate: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
price: true,
|
||||
status: true,
|
||||
createdAt: true,
|
||||
court: {
|
||||
@@ -325,6 +332,7 @@ export async function getPublicBookingConfirmation(complexSlug: string, bookingC
|
||||
slug: booking.court.sport.slug,
|
||||
},
|
||||
status: booking.status,
|
||||
price: Number(booking.price),
|
||||
createdAt: booking.createdAt.toISOString(),
|
||||
};
|
||||
}
|
||||
@@ -397,6 +405,50 @@ export async function listPublicAvailability(complexSlug: string, query: PublicA
|
||||
(slot) => !occupiedSlots.some((occupied) => hasOverlap(slot, occupied))
|
||||
);
|
||||
|
||||
const basePrice = Number(court.basePrice);
|
||||
const priceRuleMap = new Map<string, number>();
|
||||
|
||||
for (const rule of court.priceRules) {
|
||||
const ruleDay = rule.dayOfWeek;
|
||||
const ruleStart = rule.startTime;
|
||||
const ruleEnd = rule.endTime;
|
||||
const price = Number(rule.price);
|
||||
|
||||
if (ruleStart && ruleEnd && ruleDay) {
|
||||
const startMin = toMinutes(ruleStart);
|
||||
const endMin = toMinutes(ruleEnd);
|
||||
for (let mins = startMin; mins < endMin; mins += 30) {
|
||||
priceRuleMap.set(`${ruleDay}-${minutesToTime(mins)}`, price);
|
||||
}
|
||||
} else if (ruleDay && !ruleStart && !ruleEnd) {
|
||||
priceRuleMap.set(`day-${ruleDay}`, price);
|
||||
}
|
||||
}
|
||||
|
||||
const calcPrice = (startTime: string) => {
|
||||
if (!basePrice || basePrice <= 0) {
|
||||
return 0;
|
||||
}
|
||||
const timeKey = `${dayOfWeek}-${startTime}`;
|
||||
const dayKey = `day-${dayOfWeek}`;
|
||||
return priceRuleMap.get(timeKey) ?? priceRuleMap.get(dayKey) ?? basePrice;
|
||||
};
|
||||
|
||||
const price =
|
||||
availableSlots.length > 0
|
||||
? (() => {
|
||||
const prices = availableSlots.map((slot) => calcPrice(slot.startTime));
|
||||
const validPrices = prices.filter((p) => p > 0);
|
||||
if (validPrices.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
min: Math.min(...validPrices),
|
||||
max: Math.max(...validPrices),
|
||||
};
|
||||
})()
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
courtId: court.id,
|
||||
courtName: court.name,
|
||||
@@ -408,6 +460,7 @@ export async function listPublicAvailability(complexSlug: string, query: PublicA
|
||||
slotDurationMinutes: court.slotDurationMinutes,
|
||||
availabilityDay: dayOfWeek,
|
||||
availableSlots,
|
||||
price,
|
||||
};
|
||||
})
|
||||
.filter((court) => court.availableSlots.length > 0);
|
||||
@@ -476,6 +529,60 @@ export async function createPublicBooking(complexSlug: string, input: CreatePubl
|
||||
);
|
||||
}
|
||||
|
||||
function calcBookingPrice(
|
||||
court: {
|
||||
basePrice: number | null;
|
||||
priceRules: Array<{
|
||||
dayOfWeek: string | null;
|
||||
startTime: string | null;
|
||||
endTime: string | null;
|
||||
price: number;
|
||||
}>;
|
||||
},
|
||||
dayOfWeek: string,
|
||||
startTime: string
|
||||
): number {
|
||||
if (!court.basePrice) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const slotMinutes = toMinutes(startTime);
|
||||
|
||||
const exactMatch = court.priceRules.find((rule) => {
|
||||
if (!rule.dayOfWeek || rule.dayOfWeek !== dayOfWeek) {
|
||||
return false;
|
||||
}
|
||||
if (!rule.startTime || !rule.endTime) {
|
||||
return false;
|
||||
}
|
||||
const ruleStart = toMinutes(rule.startTime);
|
||||
const ruleEnd = toMinutes(rule.endTime);
|
||||
return slotMinutes >= ruleStart && slotMinutes < ruleEnd;
|
||||
});
|
||||
|
||||
if (exactMatch) {
|
||||
return Number(exactMatch.price);
|
||||
}
|
||||
|
||||
const dayMatch = court.priceRules.find((rule) => {
|
||||
if (!rule.dayOfWeek || rule.dayOfWeek !== dayOfWeek) {
|
||||
return false;
|
||||
}
|
||||
if (rule.startTime || rule.endTime) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (dayMatch) {
|
||||
return Number(dayMatch.price);
|
||||
}
|
||||
|
||||
return Number(court.basePrice);
|
||||
}
|
||||
|
||||
const bookingPrice = calcBookingPrice(selectedCourt, dayOfWeek, selectedSlot.startTime);
|
||||
|
||||
for (let attempt = 0; attempt < 5; attempt += 1) {
|
||||
try {
|
||||
const booking = await db.$transaction(async (tx) => {
|
||||
@@ -531,6 +638,7 @@ export async function createPublicBooking(complexSlug: string, input: CreatePubl
|
||||
bookingDate,
|
||||
startTime: selectedSlot.startTime,
|
||||
endTime: selectedSlot.endTime,
|
||||
price: bookingPrice,
|
||||
customerName: input.customerName.trim(),
|
||||
customerPhone: input.customerPhone.trim(),
|
||||
status: 'CONFIRMED',
|
||||
@@ -542,6 +650,7 @@ export async function createPublicBooking(complexSlug: string, input: CreatePubl
|
||||
createdAt: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
price: true,
|
||||
customerName: true,
|
||||
customerPhone: true,
|
||||
status: true,
|
||||
@@ -556,6 +665,7 @@ export async function createPublicBooking(complexSlug: string, input: CreatePubl
|
||||
createdAt: booking.createdAt,
|
||||
startTime: booking.startTime,
|
||||
endTime: booking.endTime,
|
||||
price: Number(booking.price),
|
||||
customerName: booking.customerName,
|
||||
customerPhone: booking.customerPhone,
|
||||
status: booking.status,
|
||||
|
||||
@@ -89,6 +89,15 @@ export function PublicBookingConfirmationPage({
|
||||
<p className="mt-1 text-base font-medium sm:text-lg">
|
||||
{confirmationQuery.data.courtName} · {confirmationQuery.data.sport.name}
|
||||
</p>
|
||||
|
||||
{confirmationQuery.data.price > 0 && (
|
||||
<>
|
||||
<p className="mt-4 text-sm text-muted-foreground">Precio</p>
|
||||
<p className="mt-1 text-base font-medium sm:text-lg">
|
||||
${confirmationQuery.data.price.toLocaleString('es-AR')}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
|
||||
@@ -122,6 +122,7 @@ type SelectedSlot = {
|
||||
sportName: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
price?: { min: number; max: number };
|
||||
};
|
||||
|
||||
function addDays(baseDate: Date, amount: number) {
|
||||
@@ -210,6 +211,7 @@ export function PublicBookingPage({ complexSlug }: PublicBookingPageProps) {
|
||||
const availabilityQuery = useQuery({
|
||||
queryKey: ['public-booking-availability', complexSlug, selectedDate, selectedSportId],
|
||||
enabled: Boolean(selectedDate),
|
||||
placeholderData: (previousData) => previousData,
|
||||
queryFn: () =>
|
||||
apiClient.publicBookings.getAvailability(complexSlug, {
|
||||
date: selectedDate,
|
||||
@@ -730,6 +732,18 @@ export function PublicBookingPage({ complexSlug }: PublicBookingPageProps) {
|
||||
{selectedSlot?.courtName ?? 'Seleccioná una cancha disponible'}
|
||||
</p>
|
||||
</div>
|
||||
{selectedSlot?.price && selectedSlot.price.min > 0 && (
|
||||
<div className="rounded-2xl border border-border/70 bg-background p-4">
|
||||
<p className="text-xs uppercase tracking-[0.24em] text-muted-foreground">
|
||||
Precio
|
||||
</p>
|
||||
<p className="mt-1 text-sm font-medium text-foreground">
|
||||
${selectedSlot.price.min.toLocaleString('es-AR')}
|
||||
{selectedSlot.price.min !== selectedSlot.price.max &&
|
||||
` - $${selectedSlot.price.max.toLocaleString('es-AR')}`}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{selectedSlot ? (
|
||||
|
||||
Reference in New Issue
Block a user