Require guest identity and signature before checkout
All checks were successful
build-and-deploy / build-deploy (push) Successful in 36s

This commit is contained in:
androidlover5842
2026-02-05 09:56:32 +05:30
parent cb6fb94bf7
commit f46893e0c3
2 changed files with 32 additions and 1 deletions

View File

@@ -1850,6 +1850,8 @@ BOOKING APIS
- 404 Not Found - 404 Not Found
- 409 Conflict - 409 Conflict
- Booking not checked in - Booking not checked in
- Primary guest missing / guest name missing / guest phone missing / guest signature missing
- checkOutAt must be after checkInAt
- Room stay amount outside allowed range - Room stay amount outside allowed range
- Ledger mismatch tolerance failure - Ledger mismatch tolerance failure
@@ -1878,7 +1880,11 @@ BOOKING APIS
- 401 Unauthorized - 401 Unauthorized
- 403 Forbidden - 403 Forbidden
- 404 Not Found (booking/stay) - 404 Not Found (booking/stay)
- 409 Conflict (booking not checked in / amount or minimum duration invalid) - 409 Conflict
- booking not checked in
- Primary guest missing / guest name missing / guest phone missing / guest signature missing
- checkOutAt must be after checkInAt
- amount or minimum duration invalid
- Cancel booking API is this one: - Cancel booking API is this one:

View File

@@ -651,6 +651,7 @@ class BookingFlow(
} }
val now = OffsetDateTime.now() val now = OffsetDateTime.now()
val checkOutAt = parseOffset(request.checkOutAt) ?: now val checkOutAt = parseOffset(request.checkOutAt) ?: now
validateCheckoutPrerequisites(booking, checkOutAt)
val stays = roomStayRepo.findActiveByBookingId(bookingId) val stays = roomStayRepo.findActiveByBookingId(bookingId)
if (stays.any { !isCheckoutAmountValid(it) || !isMinimumStayDurationValid(it, checkOutAt) }) { if (stays.any { !isCheckoutAmountValid(it) || !isMinimumStayDurationValid(it, checkOutAt) }) {
@@ -723,6 +724,7 @@ class BookingFlow(
val now = OffsetDateTime.now() val now = OffsetDateTime.now()
val checkOutAt = parseOffset(request.checkOutAt) ?: now val checkOutAt = parseOffset(request.checkOutAt) ?: now
validateCheckoutPrerequisites(booking, checkOutAt)
if (!isCheckoutAmountValid(stay)) { if (!isCheckoutAmountValid(stay)) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Room stay amount is outside allowed range") throw ResponseStatusException(HttpStatus.CONFLICT, "Room stay amount is outside allowed range")
} }
@@ -1060,6 +1062,29 @@ class BookingFlow(
return java.time.Duration.between(stay.fromAt, checkOutAt).toMinutes() >= 60 return java.time.Duration.between(stay.fromAt, checkOutAt).toMinutes() >= 60
} }
private fun validateCheckoutPrerequisites(
booking: com.android.trisolarisserver.models.booking.Booking,
checkOutAt: OffsetDateTime
) {
val guest = booking.primaryGuest
?: throw ResponseStatusException(HttpStatus.CONFLICT, "Primary guest required before checkout")
if (guest.name.isNullOrBlank()) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Guest name required before checkout")
}
if (guest.phoneE164.isNullOrBlank()) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Guest phone required before checkout")
}
if (guest.signaturePath.isNullOrBlank()) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Guest signature required before checkout")
}
val checkInAt = booking.checkinAt ?: booking.expectedCheckinAt
?: throw ResponseStatusException(HttpStatus.CONFLICT, "Check-in time missing for booking")
if (!checkOutAt.isAfter(checkInAt)) {
throw ResponseStatusException(HttpStatus.CONFLICT, "checkOutAt must be after checkInAt")
}
}
private fun ensureLedgerToleranceForCheckout( private fun ensureLedgerToleranceForCheckout(
bookingId: UUID, bookingId: UUID,
timezone: String?, timezone: String?,