Add active room stays endpoint
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 27s
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package com.android.trisolarisserver.controller
|
||||
|
||||
import com.android.trisolarisserver.component.PropertyAccess
|
||||
import com.android.trisolarisserver.controller.dto.ActiveRoomStayResponse
|
||||
import com.android.trisolarisserver.models.property.Role
|
||||
import com.android.trisolarisserver.repo.PropertyUserRepo
|
||||
import com.android.trisolarisserver.repo.RoomStayRepo
|
||||
import com.android.trisolarisserver.security.MyPrincipal
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import java.util.UUID
|
||||
|
||||
@RestController
|
||||
class RoomStays(
|
||||
private val propertyAccess: PropertyAccess,
|
||||
private val propertyUserRepo: PropertyUserRepo,
|
||||
private val roomStayRepo: RoomStayRepo
|
||||
) {
|
||||
|
||||
@GetMapping("/properties/{propertyId}/room-stays/active")
|
||||
fun listActiveRoomStays(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?
|
||||
): List<ActiveRoomStayResponse> {
|
||||
if (principal == null) {
|
||||
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing principal")
|
||||
}
|
||||
propertyAccess.requireMember(propertyId, principal.userId)
|
||||
|
||||
val roles = propertyUserRepo.findRolesByPropertyAndUser(propertyId, principal.userId)
|
||||
if (isAgentOnly(roles)) {
|
||||
throw ResponseStatusException(HttpStatus.FORBIDDEN, "Agents cannot view active stays")
|
||||
}
|
||||
|
||||
return roomStayRepo.findActiveByPropertyIdWithDetails(propertyId).map { stay ->
|
||||
val booking = stay.booking
|
||||
val guest = booking.primaryGuest
|
||||
val room = stay.room
|
||||
val roomType = room.roomType
|
||||
ActiveRoomStayResponse(
|
||||
roomStayId = stay.id!!,
|
||||
bookingId = booking.id!!,
|
||||
guestId = guest?.id,
|
||||
guestName = guest?.name,
|
||||
guestPhone = guest?.phoneE164,
|
||||
roomId = room.id!!,
|
||||
roomNumber = room.roomNumber,
|
||||
roomTypeId = roomType.id!!,
|
||||
roomTypeName = roomType.name,
|
||||
fromAt = stay.fromAt.toString(),
|
||||
checkinAt = booking.checkinAt?.toString(),
|
||||
expectedCheckoutAt = booking.expectedCheckoutAt?.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAgentOnly(roles: Set<Role>): Boolean {
|
||||
if (!roles.contains(Role.AGENT)) return false
|
||||
val privileged = setOf(
|
||||
Role.ADMIN,
|
||||
Role.MANAGER,
|
||||
Role.STAFF,
|
||||
Role.HOUSEKEEPING,
|
||||
Role.FINANCE,
|
||||
Role.SUPERVISOR,
|
||||
Role.GUIDE
|
||||
)
|
||||
return roles.none { it in privileged }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.android.trisolarisserver.controller.dto
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
data class ActiveRoomStayResponse(
|
||||
val roomStayId: UUID,
|
||||
val bookingId: UUID,
|
||||
val guestId: UUID?,
|
||||
val guestName: String?,
|
||||
val guestPhone: String?,
|
||||
val roomId: UUID,
|
||||
val roomNumber: Int,
|
||||
val roomTypeId: UUID,
|
||||
val roomTypeName: String,
|
||||
val fromAt: String,
|
||||
val checkinAt: String?,
|
||||
val expectedCheckoutAt: String?
|
||||
)
|
||||
@@ -62,4 +62,17 @@ interface RoomStayRepo : JpaRepository<RoomStay, UUID> {
|
||||
@Param("fromAt") fromAt: java.time.OffsetDateTime,
|
||||
@Param("toAt") toAt: java.time.OffsetDateTime
|
||||
): Boolean
|
||||
|
||||
@Query("""
|
||||
select rs
|
||||
from RoomStay rs
|
||||
join fetch rs.room r
|
||||
join fetch r.roomType rt
|
||||
join fetch rs.booking b
|
||||
left join fetch b.primaryGuest g
|
||||
where rs.property.id = :propertyId
|
||||
and rs.toAt is null
|
||||
order by r.roomNumber
|
||||
""")
|
||||
fun findActiveByPropertyIdWithDetails(@Param("propertyId") propertyId: UUID): List<RoomStay>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user