Expose active temp card state on room responses
All checks were successful
build-and-deploy / build-deploy (push) Successful in 33s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 33s
This commit is contained in:
@@ -10,6 +10,7 @@ import com.android.trisolarisserver.controller.dto.RoomResponse
|
||||
import com.android.trisolarisserver.controller.dto.RoomUpsertRequest
|
||||
import com.android.trisolarisserver.repo.PropertyRepo
|
||||
import com.android.trisolarisserver.repo.PropertyUserRepo
|
||||
import com.android.trisolarisserver.repo.IssuedCardRepo
|
||||
import com.android.trisolarisserver.repo.RoomImageRepo
|
||||
import com.android.trisolarisserver.repo.RoomRepo
|
||||
import com.android.trisolarisserver.repo.RoomStayRepo
|
||||
@@ -31,6 +32,7 @@ import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter
|
||||
import java.time.LocalDate
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneId
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
@@ -45,6 +47,7 @@ class Rooms(
|
||||
private val roomStayRepo: RoomStayRepo,
|
||||
private val propertyRepo: PropertyRepo,
|
||||
private val roomTypeRepo: RoomTypeRepo,
|
||||
private val issuedCardRepo: IssuedCardRepo,
|
||||
private val propertyUserRepo: PropertyUserRepo,
|
||||
private val roomBoardEvents: RoomBoardEvents
|
||||
) {
|
||||
@@ -58,14 +61,15 @@ class Rooms(
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
val roles = propertyUserRepo.findRolesByPropertyAndUser(propertyId, principal.userId)
|
||||
val rooms = roomRepo.findByPropertyIdOrderByRoomNumber(propertyId)
|
||||
val tempCardsByRoom = loadActiveTempCardsByRoom(propertyId)
|
||||
if (isAgentOnly(roles)) {
|
||||
val occupiedRoomIds = roomStayRepo.findOccupiedRoomIds(propertyId).toHashSet()
|
||||
return rooms
|
||||
.filter { it.active && !it.maintenance && !occupiedRoomIds.contains(it.id) }
|
||||
.map { it.toRoomResponse() }
|
||||
.map { it.toRoomResponse(tempCardsByRoom[it.id]) }
|
||||
}
|
||||
return rooms
|
||||
.map { it.toRoomResponse() }
|
||||
.map { it.toRoomResponse(tempCardsByRoom[it.id]) }
|
||||
}
|
||||
|
||||
@GetMapping("/board")
|
||||
@@ -134,9 +138,10 @@ class Rooms(
|
||||
): List<RoomResponse> {
|
||||
val rooms = roomRepo.findByPropertyIdOrderByRoomNumber(propertyId)
|
||||
val occupiedRoomIds = roomStayRepo.findOccupiedRoomIds(propertyId).toHashSet()
|
||||
val tempCardsByRoom = loadActiveTempCardsByRoom(propertyId)
|
||||
return rooms
|
||||
.filter { it.active && !it.maintenance && !occupiedRoomIds.contains(it.id) }
|
||||
.map { it.toRoomResponse() }
|
||||
.map { it.toRoomResponse(tempCardsByRoom[it.id]) }
|
||||
}
|
||||
|
||||
@GetMapping("/by-type/{roomTypeCode}")
|
||||
@@ -152,14 +157,15 @@ class Rooms(
|
||||
|
||||
val rooms = roomRepo.findByPropertyIdOrderByRoomNumber(propertyId)
|
||||
.filter { it.roomType.id == roomType.id }
|
||||
val tempCardsByRoom = loadActiveTempCardsByRoom(propertyId)
|
||||
|
||||
if (availableOnly || (principal != null && isAgentOnly(propertyUserRepo.findRolesByPropertyAndUser(propertyId, principal.userId)))) {
|
||||
val occupiedRoomIds = roomStayRepo.findOccupiedRoomIds(propertyId).toHashSet()
|
||||
return rooms
|
||||
.filter { it.active && !it.maintenance && !occupiedRoomIds.contains(it.id) }
|
||||
.map { it.toRoomResponse() }
|
||||
.map { it.toRoomResponse(tempCardsByRoom[it.id]) }
|
||||
}
|
||||
return rooms.map { it.toRoomResponse() }
|
||||
return rooms.map { it.toRoomResponse(tempCardsByRoom[it.id]) }
|
||||
}
|
||||
|
||||
@GetMapping("/availability-range")
|
||||
@@ -238,7 +244,9 @@ class Rooms(
|
||||
hasNfc = saved.hasNfc,
|
||||
active = saved.active,
|
||||
maintenance = saved.maintenance,
|
||||
notes = saved.notes
|
||||
notes = saved.notes,
|
||||
tempCardActive = false,
|
||||
tempCardExpiresAt = null
|
||||
)
|
||||
roomBoardEvents.emit(propertyId)
|
||||
return response
|
||||
@@ -280,7 +288,9 @@ class Rooms(
|
||||
hasNfc = saved.hasNfc,
|
||||
active = saved.active,
|
||||
maintenance = saved.maintenance,
|
||||
notes = saved.notes
|
||||
notes = saved.notes,
|
||||
tempCardActive = false,
|
||||
tempCardExpiresAt = null
|
||||
)
|
||||
roomBoardEvents.emit(propertyId)
|
||||
return response
|
||||
@@ -348,9 +358,16 @@ class Rooms(
|
||||
return roomTypeRepo.findByPropertyIdAndCodeIgnoreCase(propertyId, code)
|
||||
?: throw ResponseStatusException(HttpStatus.NOT_FOUND, "Room type not found")
|
||||
}
|
||||
|
||||
private fun loadActiveTempCardsByRoom(propertyId: UUID): Map<UUID, OffsetDateTime> {
|
||||
val now = OffsetDateTime.now()
|
||||
return issuedCardRepo.findActiveTempCardsForProperty(propertyId, now)
|
||||
.groupBy { it.room.id ?: throw IllegalStateException("Room id is null") }
|
||||
.mapValues { (_, cards) -> cards.maxBy { it.expiresAt }.expiresAt }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Room.toRoomResponse(): RoomResponse {
|
||||
private fun Room.toRoomResponse(tempCardExpiresAt: OffsetDateTime? = null): RoomResponse {
|
||||
val roomId = id ?: throw IllegalStateException("Room id is null")
|
||||
return RoomResponse(
|
||||
id = roomId,
|
||||
@@ -360,6 +377,8 @@ private fun Room.toRoomResponse(): RoomResponse {
|
||||
hasNfc = hasNfc,
|
||||
active = active,
|
||||
maintenance = maintenance,
|
||||
notes = notes
|
||||
notes = notes,
|
||||
tempCardActive = tempCardExpiresAt != null,
|
||||
tempCardExpiresAt = tempCardExpiresAt?.toString()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ data class RoomResponse(
|
||||
val hasNfc: Boolean,
|
||||
val active: Boolean,
|
||||
val maintenance: Boolean,
|
||||
val notes: String?
|
||||
val notes: String?,
|
||||
val tempCardActive: Boolean = false,
|
||||
val tempCardExpiresAt: String? = null
|
||||
)
|
||||
|
||||
data class RoomBoardResponse(
|
||||
|
||||
@@ -33,4 +33,17 @@ interface IssuedCardRepo : JpaRepository<IssuedCard, UUID> {
|
||||
@org.springframework.data.repository.query.Param("roomStayId") roomStayId: UUID,
|
||||
@org.springframework.data.repository.query.Param("now") now: java.time.OffsetDateTime
|
||||
): Boolean
|
||||
|
||||
@org.springframework.data.jpa.repository.Query("""
|
||||
select c
|
||||
from IssuedCard c
|
||||
where c.property.id = :propertyId
|
||||
and c.roomStay is null
|
||||
and c.revokedAt is null
|
||||
and c.expiresAt > :now
|
||||
""")
|
||||
fun findActiveTempCardsForProperty(
|
||||
@org.springframework.data.repository.query.Param("propertyId") propertyId: UUID,
|
||||
@org.springframework.data.repository.query.Param("now") now: java.time.OffsetDateTime
|
||||
): List<IssuedCard>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user