Compare commits

...

4 Commits

Author SHA1 Message Date
androidlover5842
d69ed60a6e agents -_- 2026-02-04 15:32:44 +05:30
androidlover5842
56f13f5e79 ability to see open bookings list 2026-02-04 15:20:17 +05:30
androidlover5842
9555ae2e40 activeScreen:improve menu 2026-02-04 15:07:27 +05:30
androidlover5842
9d942d6411 createBooking: change checkout date based on property policy while editing checking date 2026-02-04 14:58:16 +05:30
8 changed files with 206 additions and 40 deletions

View File

@@ -56,6 +56,7 @@ data class BookingListItem(
val guestId: String? = null, val guestId: String? = null,
val guestName: String? = null, val guestName: String? = null,
val guestPhone: String? = null, val guestPhone: String? = null,
val vehicleNumbers: List<String> = emptyList(),
val roomNumbers: List<Int> = emptyList(), val roomNumbers: List<Int> = emptyList(),
val source: String? = null, val source: String? = null,
val fromCity: String? = null, val fromCity: String? = null,
@@ -112,6 +113,22 @@ data class BookingBillableNightsResponse(
val billableNights: Long? = null val billableNights: Long? = null
) )
data class BookingExpectedCheckoutPreviewRequest(
val checkInAt: String,
val billableNights: Int? = null,
val billingMode: BookingBillingMode? = null,
val billingCheckinTime: String? = null,
val billingCheckoutTime: String? = null
)
data class BookingExpectedCheckoutPreviewResponse(
val expectedCheckOutAt: String? = null,
val billableNights: Int? = null,
val billingMode: BookingBillingMode? = null,
val billingCheckinTime: String? = null,
val billingCheckoutTime: String? = null
)
data class BookingDetailsResponse( data class BookingDetailsResponse(
val id: String? = null, val id: String? = null,
val status: String? = null, val status: String? = null,

View File

@@ -13,6 +13,8 @@ import com.android.trisolarispms.data.api.model.BookingListItem
import com.android.trisolarispms.data.api.model.BookingBulkCheckInRequest import com.android.trisolarispms.data.api.model.BookingBulkCheckInRequest
import com.android.trisolarispms.data.api.model.BookingBillableNightsRequest import com.android.trisolarispms.data.api.model.BookingBillableNightsRequest
import com.android.trisolarispms.data.api.model.BookingBillableNightsResponse import com.android.trisolarispms.data.api.model.BookingBillableNightsResponse
import com.android.trisolarispms.data.api.model.BookingExpectedCheckoutPreviewRequest
import com.android.trisolarispms.data.api.model.BookingExpectedCheckoutPreviewResponse
import com.android.trisolarispms.data.api.model.BookingExpectedDatesRequest import com.android.trisolarispms.data.api.model.BookingExpectedDatesRequest
import com.android.trisolarispms.data.api.model.BookingDetailsResponse import com.android.trisolarispms.data.api.model.BookingDetailsResponse
import com.android.trisolarispms.data.api.model.BookingBalanceResponse import com.android.trisolarispms.data.api.model.BookingBalanceResponse
@@ -69,6 +71,12 @@ interface BookingApi {
@Body body: BookingBillableNightsRequest @Body body: BookingBillableNightsRequest
): Response<BookingBillableNightsResponse> ): Response<BookingBillableNightsResponse>
@POST("properties/{propertyId}/bookings/expected-checkout-preview")
suspend fun previewExpectedCheckout(
@Path("propertyId") propertyId: String,
@Body body: BookingExpectedCheckoutPreviewRequest
): Response<BookingExpectedCheckoutPreviewResponse>
@POST("properties/{propertyId}/bookings/{bookingId}/billing-policy") @POST("properties/{propertyId}/bookings/{bookingId}/billing-policy")
suspend fun updateBookingBillingPolicy( suspend fun updateBookingBillingPolicy(
@Path("propertyId") propertyId: String, @Path("propertyId") propertyId: String,

View File

@@ -59,31 +59,43 @@ fun BookingCreateScreen(
val checkOutTime = remember { mutableStateOf("11:00") } val checkOutTime = remember { mutableStateOf("11:00") }
val checkInNow = remember { mutableStateOf(true) } val checkInNow = remember { mutableStateOf(true) }
val sourceMenuExpanded = remember { mutableStateOf(false) } val sourceMenuExpanded = remember { mutableStateOf(false) }
val sourceOptions = listOf("WALKIN", "OTA", "AGENT") val sourceOptions = listOf("DIRECT", "AGENT")
val relationMenuExpanded = remember { mutableStateOf(false) } val relationMenuExpanded = remember { mutableStateOf(false) }
val relationOptions = listOf("FRIENDS", "FAMILY", "GROUP", "ALONE") val relationOptions = listOf("FRIENDS", "FAMILY", "GROUP", "ALONE")
val transportMenuExpanded = remember { mutableStateOf(false) } val transportMenuExpanded = remember { mutableStateOf(false) }
val transportOptions = listOf("CAR", "BIKE", "TRAIN", "PLANE", "BUS", "FOOT", "CYCLE", "OTHER") val transportOptions = listOf("CAR", "BIKE", "TRAIN", "PLANE", "BUS", "FOOT", "CYCLE", "OTHER")
val billingModeMenuExpanded = remember { mutableStateOf(false) } val billingModeMenuExpanded = remember { mutableStateOf(false) }
val displayFormatter = remember { DateTimeFormatter.ofPattern("dd-MM-yy HH:mm") } val displayFormatter = remember { DateTimeFormatter.ofPattern("dd-MM-yy HH:mm") }
val timeFormatter = remember { DateTimeFormatter.ofPattern("HH:mm") }
val phoneCountryMenuExpanded = remember { mutableStateOf(false) } val phoneCountryMenuExpanded = remember { mutableStateOf(false) }
val phoneCountries = remember { phoneCountryOptions() } val phoneCountries = remember { phoneCountryOptions() }
val phoneCountrySearch = remember { mutableStateOf("") } val phoneCountrySearch = remember { mutableStateOf("") }
val applyCheckInSelection: (LocalDate, String) -> Unit = { date, time ->
checkInDate.value = date
checkInTime.value = time
val checkInAt = formatBookingIso(date, time)
viewModel.onExpectedCheckInAtChange(checkInAt)
viewModel.autoSetBillingFromCheckIn(checkInAt)
viewModel.refreshExpectedCheckoutPreview(propertyId)
}
LaunchedEffect(propertyId) { LaunchedEffect(propertyId) {
viewModel.reset() viewModel.reset()
viewModel.loadBillingPolicy(propertyId) viewModel.loadBillingPolicy(propertyId)
val now = OffsetDateTime.now() val now = OffsetDateTime.now()
checkInDate.value = now.toLocalDate()
checkInTime.value = now.format(DateTimeFormatter.ofPattern("HH:mm"))
val nowIso = now.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
viewModel.onExpectedCheckInAtChange(nowIso)
viewModel.autoSetBillingFromCheckIn(nowIso)
checkInNow.value = true checkInNow.value = true
val defaultCheckoutDate = now.toLocalDate().plusDays(1) val defaultCheckoutDate = now.toLocalDate().plusDays(1)
checkOutDate.value = defaultCheckoutDate checkOutDate.value = defaultCheckoutDate
checkOutTime.value = "11:00" checkOutTime.value = "11:00"
viewModel.onExpectedCheckOutAtChange(formatBookingIso(defaultCheckoutDate, checkOutTime.value)) viewModel.onExpectedCheckOutAtChange(formatBookingIso(defaultCheckoutDate, checkOutTime.value))
applyCheckInSelection(now.toLocalDate(), now.format(timeFormatter))
}
LaunchedEffect(state.expectedCheckOutAt) {
val parsed = runCatching { OffsetDateTime.parse(state.expectedCheckOutAt) }.getOrNull() ?: return@LaunchedEffect
checkOutDate.value = parsed.toLocalDate()
checkOutTime.value = parsed.format(timeFormatter)
} }
SaveTopBarScaffold( SaveTopBarScaffold(
@@ -111,11 +123,7 @@ fun BookingCreateScreen(
checkInNow.value = enabled checkInNow.value = enabled
if (enabled) { if (enabled) {
val now = OffsetDateTime.now() val now = OffsetDateTime.now()
checkInDate.value = now.toLocalDate() applyCheckInSelection(now.toLocalDate(), now.format(timeFormatter))
checkInTime.value = now.format(DateTimeFormatter.ofPattern("HH:mm"))
val nowIso = now.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
viewModel.onExpectedCheckInAtChange(nowIso)
viewModel.autoSetBillingFromCheckIn(nowIso)
} else { } else {
viewModel.onExpectedCheckInAtChange("") viewModel.onExpectedCheckInAtChange("")
} }
@@ -181,6 +189,7 @@ fun BookingCreateScreen(
onClick = { onClick = {
billingModeMenuExpanded.value = false billingModeMenuExpanded.value = false
viewModel.onBillingModeChange(mode) viewModel.onBillingModeChange(mode)
viewModel.refreshExpectedCheckoutPreview(propertyId)
} }
) )
} }
@@ -191,7 +200,10 @@ fun BookingCreateScreen(
BookingTimePickerTextField( BookingTimePickerTextField(
value = state.billingCheckoutTime, value = state.billingCheckoutTime,
label = { Text("Billing check-out (HH:mm)") }, label = { Text("Billing check-out (HH:mm)") },
onTimeSelected = viewModel::onBillingCheckoutTimeChange, onTimeSelected = { selectedTime ->
viewModel.onBillingCheckoutTimeChange(selectedTime)
viewModel.refreshExpectedCheckoutPreview(propertyId)
},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
} }
@@ -481,10 +493,7 @@ fun BookingCreateScreen(
minDate = LocalDate.now(), minDate = LocalDate.now(),
onDismiss = { showCheckInPicker.value = false }, onDismiss = { showCheckInPicker.value = false },
onConfirm = { date, time -> onConfirm = { date, time ->
checkInDate.value = date applyCheckInSelection(date, time)
checkInTime.value = time
val formatted = formatBookingIso(date, time)
viewModel.onExpectedCheckInAtChange(formatted)
showCheckInPicker.value = false showCheckInPicker.value = false
} }
) )

View File

@@ -12,7 +12,7 @@ data class BookingCreateState(
val expectedCheckOutAt: String = "", val expectedCheckOutAt: String = "",
val billingMode: BookingBillingMode = BookingBillingMode.PROPERTY_POLICY, val billingMode: BookingBillingMode = BookingBillingMode.PROPERTY_POLICY,
val billingCheckoutTime: String = "", val billingCheckoutTime: String = "",
val source: String = "WALKIN", val source: String = "DIRECT",
val fromCity: String = "", val fromCity: String = "",
val toCity: String = "", val toCity: String = "",
val memberRelation: String = "", val memberRelation: String = "",

View File

@@ -6,6 +6,7 @@ import com.android.trisolarispms.data.api.core.ApiClient
import com.android.trisolarispms.data.api.model.BookingBillingMode import com.android.trisolarispms.data.api.model.BookingBillingMode
import com.android.trisolarispms.data.api.model.BookingCreateRequest import com.android.trisolarispms.data.api.model.BookingCreateRequest
import com.android.trisolarispms.data.api.model.BookingCreateResponse import com.android.trisolarispms.data.api.model.BookingCreateResponse
import com.android.trisolarispms.data.api.model.BookingExpectedCheckoutPreviewRequest
import com.android.trisolarispms.data.api.model.GuestDto import com.android.trisolarispms.data.api.model.GuestDto
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -14,10 +15,16 @@ import kotlinx.coroutines.launch
import java.time.OffsetDateTime import java.time.OffsetDateTime
class BookingCreateViewModel : ViewModel() { class BookingCreateViewModel : ViewModel() {
private companion object {
const val DEFAULT_PREVIEW_BILLABLE_NIGHTS = 1
}
private val _state = MutableStateFlow(BookingCreateState()) private val _state = MutableStateFlow(BookingCreateState())
val state: StateFlow<BookingCreateState> = _state val state: StateFlow<BookingCreateState> = _state
private var expectedCheckoutPreviewRequestId: Long = 0
fun reset() { fun reset() {
expectedCheckoutPreviewRequestId = 0
_state.value = BookingCreateState() _state.value = BookingCreateState()
} }
@@ -76,6 +83,50 @@ class BookingCreateViewModel : ViewModel() {
_state.update { it.copy(billingCheckoutTime = value, error = null) } _state.update { it.copy(billingCheckoutTime = value, error = null) }
} }
fun refreshExpectedCheckoutPreview(propertyId: String) {
if (propertyId.isBlank()) return
val requestBody = buildExpectedCheckoutPreviewRequest(_state.value) ?: return
val requestId = ++expectedCheckoutPreviewRequestId
viewModelScope.launch {
try {
val api = ApiClient.create()
val response = api.previewExpectedCheckout(
propertyId = propertyId,
body = requestBody
)
val expectedCheckOutAt = response.body()?.expectedCheckOutAt?.trim().orEmpty()
if (!response.isSuccessful || expectedCheckOutAt.isBlank() || requestId != expectedCheckoutPreviewRequestId) {
return@launch
}
_state.update { current ->
if (requestId != expectedCheckoutPreviewRequestId) {
current
} else {
current.copy(expectedCheckOutAt = expectedCheckOutAt, error = null)
}
}
} catch (_: Exception) {
// Keep user-entered check-out on preview failures.
}
}
}
private fun buildExpectedCheckoutPreviewRequest(state: BookingCreateState): BookingExpectedCheckoutPreviewRequest? {
val expectedCheckInAt = state.expectedCheckInAt.trim()
if (expectedCheckInAt.isBlank()) return null
val customBillingCheckoutTime = state.billingCheckoutTime.trim().ifBlank { null }
return BookingExpectedCheckoutPreviewRequest(
checkInAt = expectedCheckInAt,
billableNights = DEFAULT_PREVIEW_BILLABLE_NIGHTS,
billingMode = state.billingMode,
billingCheckoutTime = if (state.billingMode == BookingBillingMode.CUSTOM_WINDOW) {
customBillingCheckoutTime
} else {
null
}
)
}
fun onPhoneCountryChange(value: String) { fun onPhoneCountryChange(value: String) {
val option = findPhoneCountryOption(value) val option = findPhoneCountryOption(value)
_state.update { current -> _state.update { current ->

View File

@@ -1,5 +1,6 @@
package com.android.trisolarispms.ui.roomstay package com.android.trisolarispms.ui.roomstay
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@@ -12,6 +13,8 @@ import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.CalendarMonth
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.People import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.filled.MeetingRoom import androidx.compose.material.icons.filled.MeetingRoom
import androidx.compose.material.icons.filled.Payment import androidx.compose.material.icons.filled.Payment
@@ -21,6 +24,8 @@ import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -63,6 +68,11 @@ fun ActiveRoomStaysScreen(
) { ) {
val state by viewModel.state.collectAsState() val state by viewModel.state.collectAsState()
val selectedBooking = remember { mutableStateOf<BookingListItem?>(null) } val selectedBooking = remember { mutableStateOf<BookingListItem?>(null) }
val menuExpanded = remember { mutableStateOf(false) }
BackHandler(enabled = state.showOpenBookings) {
viewModel.hideOpenBookings()
}
LaunchedEffect(propertyId) { LaunchedEffect(propertyId) {
viewModel.load(propertyId) viewModel.load(propertyId)
@@ -70,23 +80,63 @@ fun ActiveRoomStaysScreen(
BackTopBarScaffold( BackTopBarScaffold(
title = propertyName, title = propertyName,
onBack = onBack, onBack = {
if (state.showOpenBookings) {
viewModel.hideOpenBookings()
} else {
onBack()
}
},
showBack = showBack, showBack = showBack,
actions = { actions = {
IconButton(onClick = onViewRooms) { IconButton(onClick = onViewRooms) {
Icon(Icons.Default.MeetingRoom, contentDescription = "Available Rooms") Icon(Icons.Default.MeetingRoom, contentDescription = "Available Rooms")
} }
IconButton(onClick = onOpenSettings) { IconButton(onClick = viewModel::toggleShowOpenBookings) {
Icon(Icons.Default.Settings, contentDescription = "Settings") Icon(
Icons.Default.CalendarMonth,
contentDescription = "Show Open Bookings",
tint = if (state.showOpenBookings) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurfaceVariant
}
)
} }
if (showRazorpaySettings) { IconButton(onClick = { menuExpanded.value = true }) {
IconButton(onClick = onRazorpaySettings) { Icon(Icons.Default.MoreVert, contentDescription = "Menu")
Icon(Icons.Default.Payment, contentDescription = "Razorpay Settings") }
DropdownMenu(
expanded = menuExpanded.value,
onDismissRequest = { menuExpanded.value = false }
) {
DropdownMenuItem(
text = { Text("Settings") },
leadingIcon = { Icon(Icons.Default.Settings, contentDescription = null) },
onClick = {
menuExpanded.value = false
onOpenSettings()
}
)
if (showRazorpaySettings) {
DropdownMenuItem(
text = { Text("Razorpay Settings") },
leadingIcon = { Icon(Icons.Default.Payment, contentDescription = null) },
onClick = {
menuExpanded.value = false
onRazorpaySettings()
}
)
} }
} if (showUserAdmin) {
if (showUserAdmin) { DropdownMenuItem(
IconButton(onClick = onUserAdmin) { text = { Text("Property Users") },
Icon(Icons.Default.People, contentDescription = "Property Users") leadingIcon = { Icon(Icons.Default.People, contentDescription = null) },
onClick = {
menuExpanded.value = false
onUserAdmin()
}
)
} }
} }
}, },
@@ -106,14 +156,24 @@ fun ActiveRoomStaysScreen(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
state.error?.let { state.error?.let {
Text(text = it, color = MaterialTheme.colorScheme.error) Text(text = it, color = MaterialTheme.colorScheme.error)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
if (!state.isLoading && state.error == null) { if (!state.isLoading && state.error == null) {
if (state.checkedInBookings.isNotEmpty()) { val shownBookings = if (state.showOpenBookings) {
Text(text = "Checked-in bookings", style = MaterialTheme.typography.titleMedium) state.openBookings
} else {
state.checkedInBookings
}
if (shownBookings.isNotEmpty()) {
val sectionTitle = if (state.showOpenBookings) {
"Open bookings"
} else {
"Checked-in bookings"
}
Text(text = sectionTitle, style = MaterialTheme.typography.titleMedium)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Fixed(2), columns = GridCells.Fixed(2),
@@ -121,7 +181,7 @@ fun ActiveRoomStaysScreen(
horizontalArrangement = Arrangement.spacedBy(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(12.dp)
) { ) {
items(state.checkedInBookings) { booking -> items(shownBookings) { booking ->
CheckedInBookingCard( CheckedInBookingCard(
booking = booking, booking = booking,
onClick = { onOpenBookingDetails(booking) }) onClick = { onOpenBookingDetails(booking) })
@@ -129,7 +189,12 @@ fun ActiveRoomStaysScreen(
} }
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
} else { } else {
Text(text = "No checked-in bookings") val emptyLabel = if (state.showOpenBookings) {
"No open bookings"
} else {
"No checked-in bookings"
}
Text(text = emptyLabel)
} }
} }
} }
@@ -188,10 +253,6 @@ private fun CheckedInBookingCard(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
val source = booking.source?.takeIf { it.isNotBlank() }
if (source != null) {
Text(text = source, style = MaterialTheme.typography.bodySmall)
}
val expectedCount = booking.expectedGuestCount val expectedCount = booking.expectedGuestCount
val totalCount = booking.totalGuestCount val totalCount = booking.totalGuestCount
val countLine = when { val countLine = when {
@@ -216,6 +277,14 @@ private fun CheckedInBookingCard(
color = MaterialTheme.colorScheme.error color = MaterialTheme.colorScheme.error
) )
} }
val vehicleNumbers = booking.vehicleNumbers.filter { it.isNotBlank() }
if (vehicleNumbers.isNotEmpty()) {
Spacer(modifier = Modifier.height(6.dp))
Text(
text = vehicleNumbers.joinToString(", "),
style = MaterialTheme.typography.bodySmall
)
}
val checkInAt = booking.checkInAt?.takeIf { it.isNotBlank() } val checkInAt = booking.checkInAt?.takeIf { it.isNotBlank() }
val checkOutAt = booking.expectedCheckOutAt?.takeIf { it.isNotBlank() } val checkOutAt = booking.expectedCheckOutAt?.takeIf { it.isNotBlank() }
if (checkInAt != null && checkOutAt != null) { if (checkInAt != null && checkOutAt != null) {

View File

@@ -7,5 +7,7 @@ data class ActiveRoomStaysState(
val isLoading: Boolean = false, val isLoading: Boolean = false,
val error: String? = null, val error: String? = null,
val items: List<ActiveRoomStayDto> = emptyList(), val items: List<ActiveRoomStayDto> = emptyList(),
val checkedInBookings: List<BookingListItem> = emptyList() val checkedInBookings: List<BookingListItem> = emptyList(),
val openBookings: List<BookingListItem> = emptyList(),
val showOpenBookings: Boolean = false
) )

View File

@@ -11,6 +11,14 @@ class ActiveRoomStaysViewModel : ViewModel() {
private val _state = MutableStateFlow(ActiveRoomStaysState()) private val _state = MutableStateFlow(ActiveRoomStaysState())
val state: StateFlow<ActiveRoomStaysState> = _state val state: StateFlow<ActiveRoomStaysState> = _state
fun toggleShowOpenBookings() {
_state.update { it.copy(showOpenBookings = !it.showOpenBookings) }
}
fun hideOpenBookings() {
_state.update { it.copy(showOpenBookings = false) }
}
fun load(propertyId: String) { fun load(propertyId: String) {
if (propertyId.isBlank()) return if (propertyId.isBlank()) return
launchRequest( launchRequest(
@@ -22,12 +30,14 @@ class ActiveRoomStaysViewModel : ViewModel() {
val api = ApiClient.create() val api = ApiClient.create()
val activeResponse = api.listActiveRoomStays(propertyId) val activeResponse = api.listActiveRoomStays(propertyId)
val bookingsResponse = api.listBookings(propertyId, status = "CHECKED_IN") val bookingsResponse = api.listBookings(propertyId, status = "CHECKED_IN")
val openBookingsResponse = api.listBookings(propertyId, status = "OPEN")
if (activeResponse.isSuccessful) { if (activeResponse.isSuccessful) {
_state.update { _state.update {
it.copy( it.copy(
isLoading = false, isLoading = false,
items = activeResponse.body().orEmpty(), items = activeResponse.body().orEmpty(),
checkedInBookings = bookingsResponse.body().orEmpty(), checkedInBookings = bookingsResponse.body().orEmpty(),
openBookings = openBookingsResponse.body().orEmpty(),
error = null error = null
) )
} }