Files
TrisolarisServer/src/main/kotlin/com/android/trisolarisserver/controller/BookingSnapshotBuilder.kt
androidlover5842 d692deb402
All checks were successful
build-and-deploy / build-deploy (push) Successful in 33s
Include vehicle numbers in booking detail
2026-01-31 14:07:00 +05:30

90 lines
3.7 KiB
Kotlin

package com.android.trisolarisserver.controller
import com.android.trisolarisserver.controller.dto.BookingDetailResponse
import com.android.trisolarisserver.db.repo.BookingRepo
import com.android.trisolarisserver.repo.GuestVehicleRepo
import com.android.trisolarisserver.repo.PaymentRepo
import com.android.trisolarisserver.repo.RoomStayRepo
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import org.springframework.web.server.ResponseStatusException
import java.util.UUID
@Component
class BookingSnapshotBuilder(
private val bookingRepo: BookingRepo,
private val roomStayRepo: RoomStayRepo,
private val paymentRepo: PaymentRepo,
private val guestVehicleRepo: GuestVehicleRepo
) {
fun build(propertyId: UUID, bookingId: UUID): BookingDetailResponse {
val booking = bookingRepo.findById(bookingId).orElseThrow {
ResponseStatusException(HttpStatus.NOT_FOUND, "Booking not found")
}
if (booking.property.id != propertyId) {
throw ResponseStatusException(HttpStatus.NOT_FOUND, "Booking not found for property")
}
val stays = roomStayRepo.findByBookingId(bookingId)
val activeRooms = stays.filter { it.toAt == null }
val roomsToShow = activeRooms.ifEmpty { stays }
val roomNumbers = roomsToShow.map { it.room.roomNumber }
.distinct()
.sorted()
val guest = booking.primaryGuest
val vehicleNumbers = if (guest?.id != null) {
guestVehicleRepo.findByGuestIdIn(listOf(guest.id!!))
.map { it.vehicleNumber }
.distinct()
.sorted()
} else {
emptyList()
}
val signatureUrl = guest?.signaturePath?.let {
"/properties/$propertyId/guests/${guest.id}/signature/file"
}
val totalNightlyRate = roomsToShow.sumOf { it.nightlyRate ?: 0L }
val expectedPay = computeExpectedPayTotal(stays, booking.expectedCheckoutAt, booking.property.timezone)
val accruedPay = computeExpectedPay(stays, booking.property.timezone)
val amountCollected = paymentRepo.sumAmountByBookingId(bookingId)
val pending = accruedPay - amountCollected
return BookingDetailResponse(
id = booking.id!!,
status = booking.status.name,
guestId = guest?.id,
guestName = guest?.name,
guestPhone = guest?.phoneE164,
guestNationality = guest?.nationality,
guestAddressText = guest?.addressText,
guestSignatureUrl = signatureUrl,
vehicleNumbers = vehicleNumbers,
roomNumbers = roomNumbers,
source = booking.source,
fromCity = booking.fromCity,
toCity = booking.toCity,
memberRelation = booking.memberRelation?.name,
transportMode = booking.transportMode?.name,
checkInAt = booking.checkinAt?.toString(),
checkOutAt = booking.checkoutAt?.toString(),
expectedCheckInAt = booking.expectedCheckinAt?.toString(),
expectedCheckOutAt = booking.expectedCheckoutAt?.toString(),
adultCount = booking.adultCount,
childCount = booking.childCount,
maleCount = booking.maleCount,
femaleCount = booking.femaleCount,
totalGuestCount = booking.totalGuestCount,
expectedGuestCount = booking.expectedGuestCount,
notes = booking.notes,
registeredByName = booking.createdBy?.name,
registeredByPhone = booking.createdBy?.phoneE164,
totalNightlyRate = totalNightlyRate,
expectedPay = expectedPay,
amountCollected = amountCollected,
pending = pending
)
}
}