Add booking create endpoint
All checks were successful
build-and-deploy / build-deploy (push) Successful in 34s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 34s
This commit is contained in:
@@ -95,6 +95,7 @@ Properties
|
||||
- Property create/update accepts addressText, otaAliases, emailAddresses, allowedTransportModes.
|
||||
|
||||
Booking flow
|
||||
- POST /properties/{propertyId}/bookings (create booking)
|
||||
- /properties/{propertyId}/bookings/{bookingId}/check-in (creates RoomStay rows)
|
||||
- /properties/{propertyId}/bookings/{bookingId}/check-out (closes RoomStay)
|
||||
- /properties/{propertyId}/bookings/{bookingId}/cancel
|
||||
|
||||
@@ -5,6 +5,8 @@ import com.android.trisolarisserver.component.RoomBoardEvents
|
||||
import com.android.trisolarisserver.controller.dto.BookingCancelRequest
|
||||
import com.android.trisolarisserver.controller.dto.BookingCheckInRequest
|
||||
import com.android.trisolarisserver.controller.dto.BookingCheckOutRequest
|
||||
import com.android.trisolarisserver.controller.dto.BookingCreateRequest
|
||||
import com.android.trisolarisserver.controller.dto.BookingCreateResponse
|
||||
import com.android.trisolarisserver.controller.dto.BookingNoShowRequest
|
||||
import com.android.trisolarisserver.controller.dto.RoomStayPreAssignRequest
|
||||
import com.android.trisolarisserver.db.repo.BookingRepo
|
||||
@@ -13,6 +15,7 @@ import com.android.trisolarisserver.models.booking.TransportMode
|
||||
import com.android.trisolarisserver.models.room.RoomStay
|
||||
import com.android.trisolarisserver.models.property.Role
|
||||
import com.android.trisolarisserver.repo.AppUserRepo
|
||||
import com.android.trisolarisserver.repo.PropertyRepo
|
||||
import com.android.trisolarisserver.repo.RoomRepo
|
||||
import com.android.trisolarisserver.repo.RoomStayRepo
|
||||
import com.android.trisolarisserver.security.MyPrincipal
|
||||
@@ -37,9 +40,62 @@ class BookingFlow(
|
||||
private val roomRepo: RoomRepo,
|
||||
private val roomStayRepo: RoomStayRepo,
|
||||
private val appUserRepo: AppUserRepo,
|
||||
private val propertyRepo: PropertyRepo,
|
||||
private val roomBoardEvents: RoomBoardEvents
|
||||
) {
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@Transactional
|
||||
fun createBooking(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
@RequestBody request: BookingCreateRequest
|
||||
): BookingCreateResponse {
|
||||
val actor = requireActor(propertyId, principal)
|
||||
val property = propertyRepo.findById(propertyId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found")
|
||||
}
|
||||
|
||||
val expectedCheckInAt = parseOffset(request.expectedCheckInAt)
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "expectedCheckInAt required")
|
||||
val expectedCheckOutAt = parseOffset(request.expectedCheckOutAt)
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "expectedCheckOutAt required")
|
||||
if (!expectedCheckOutAt.isAfter(expectedCheckInAt)) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid date range")
|
||||
}
|
||||
|
||||
val now = OffsetDateTime.now()
|
||||
val booking = com.android.trisolarisserver.models.booking.Booking(
|
||||
property = property,
|
||||
status = BookingStatus.OPEN,
|
||||
source = request.source?.trim().takeIf { !it.isNullOrBlank() } ?: "WALKIN",
|
||||
expectedCheckinAt = expectedCheckInAt,
|
||||
expectedCheckoutAt = expectedCheckOutAt,
|
||||
transportMode = request.transportMode?.let {
|
||||
val mode = parseTransportMode(it)
|
||||
if (!isTransportModeAllowed(property, mode)) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Transport mode disabled")
|
||||
}
|
||||
mode
|
||||
},
|
||||
transportVehicleNumber = request.transportVehicleNumber,
|
||||
adultCount = request.adultCount,
|
||||
totalGuestCount = request.totalGuestCount,
|
||||
notes = request.notes,
|
||||
createdBy = actor,
|
||||
updatedAt = now
|
||||
)
|
||||
|
||||
val saved = bookingRepo.save(booking)
|
||||
return BookingCreateResponse(
|
||||
id = saved.id!!,
|
||||
status = saved.status.name,
|
||||
expectedCheckInAt = expectedCheckInAt.toString(),
|
||||
expectedCheckOutAt = expectedCheckOutAt.toString()
|
||||
)
|
||||
}
|
||||
|
||||
@PostMapping("/{bookingId}/check-in")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@Transactional
|
||||
|
||||
@@ -10,6 +10,24 @@ data class BookingCheckInRequest(
|
||||
val notes: String? = null
|
||||
)
|
||||
|
||||
data class BookingCreateRequest(
|
||||
val source: String? = null,
|
||||
val expectedCheckInAt: String,
|
||||
val expectedCheckOutAt: String,
|
||||
val transportMode: String? = null,
|
||||
val transportVehicleNumber: String? = null,
|
||||
val adultCount: Int? = null,
|
||||
val totalGuestCount: Int? = null,
|
||||
val notes: String? = null
|
||||
)
|
||||
|
||||
data class BookingCreateResponse(
|
||||
val id: UUID,
|
||||
val status: String,
|
||||
val expectedCheckInAt: String,
|
||||
val expectedCheckOutAt: String
|
||||
)
|
||||
|
||||
data class BookingCheckOutRequest(
|
||||
val checkOutAt: String? = null,
|
||||
val notes: String? = null
|
||||
|
||||
Reference in New Issue
Block a user