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("fromAt") fromAt: java.time.OffsetDateTime,
|
||||||
@Param("toAt") toAt: java.time.OffsetDateTime
|
@Param("toAt") toAt: java.time.OffsetDateTime
|
||||||
): Boolean
|
): 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