diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt b/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt index 15942a2..77d3ce9 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt @@ -8,6 +8,7 @@ import com.android.trisolarisserver.controller.dto.BookingBulkCheckInRequest 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.BookingExpectedDatesUpdateRequest import com.android.trisolarisserver.controller.dto.BookingLinkGuestRequest import com.android.trisolarisserver.controller.dto.BookingNoShowRequest import com.android.trisolarisserver.controller.dto.BookingListItem @@ -373,6 +374,51 @@ class BookingFlow( roomBoardEvents.emit(propertyId) } + @PostMapping("/{bookingId}/expected-dates") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Transactional + fun updateExpectedDates( + @PathVariable propertyId: UUID, + @PathVariable bookingId: UUID, + @AuthenticationPrincipal principal: MyPrincipal?, + @RequestBody request: BookingExpectedDatesUpdateRequest + ) { + requireActor(propertyId, principal) + val booking = requireBooking(propertyId, bookingId) + when (booking.status) { + BookingStatus.OPEN -> { + if (request.expectedCheckInAt != null) { + booking.expectedCheckinAt = parseOffset(request.expectedCheckInAt) + } + if (request.expectedCheckOutAt != null) { + booking.expectedCheckoutAt = parseOffset(request.expectedCheckOutAt) + } + } + BookingStatus.CHECKED_IN -> { + if (request.expectedCheckInAt != null) { + throw ResponseStatusException(HttpStatus.CONFLICT, "Cannot change expected check-in after check-in") + } + if (request.expectedCheckOutAt != null) { + booking.expectedCheckoutAt = parseOffset(request.expectedCheckOutAt) + } + } + BookingStatus.CHECKED_OUT, + BookingStatus.CANCELLED, + BookingStatus.NO_SHOW -> { + throw ResponseStatusException(HttpStatus.CONFLICT, "Booking closed") + } + } + + val expectedIn = booking.expectedCheckinAt + val expectedOut = booking.expectedCheckoutAt + if (expectedIn != null && expectedOut != null && !expectedOut.isAfter(expectedIn)) { + throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid date range") + } + + booking.updatedAt = OffsetDateTime.now() + bookingRepo.save(booking) + } + @PostMapping("/{bookingId}/check-out") @ResponseStatus(HttpStatus.NO_CONTENT) @Transactional diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/dto/BookingDtos.kt b/src/main/kotlin/com/android/trisolarisserver/controller/dto/BookingDtos.kt index 708723a..0d7c7df 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/dto/BookingDtos.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/dto/BookingDtos.kt @@ -79,6 +79,11 @@ data class BookingLinkGuestRequest( val guestId: UUID ) +data class BookingExpectedDatesUpdateRequest( + val expectedCheckInAt: String? = null, + val expectedCheckOutAt: String? = null +) + data class BookingCheckOutRequest( val checkOutAt: String? = null, val notes: String? = null