заказы для админа

This commit is contained in:
dasha 2023-12-24 17:28:56 +04:00
parent f11ebc82f5
commit 4bf7ebb6bf
13 changed files with 113 additions and 24 deletions

View File

@ -3,6 +3,7 @@ package com.example.myapplication.api
import com.example.myapplication.api.cinema.CinemaRemote
import com.example.myapplication.api.cinema.CinemaWithSessionsRemote
import com.example.myapplication.api.order.OrderRemote
import com.example.myapplication.api.order.OrderWithUserRemote
import com.example.myapplication.api.session.ReportRemote
import com.example.myapplication.api.session.SessionFromCinemaRemote
import com.example.myapplication.api.session.SessionRemote
@ -137,6 +138,12 @@ interface MyServerService {
@Query("_limit") limit: Int,
): List<OrderRemote>
@GET("orders?_expand=user")
suspend fun getOrders(
@Query("_page") page: Int,
@Query("_limit") limit: Int,
): List<OrderWithUserRemote>
@GET("orders/{id}")
suspend fun getOrder(
@Path("id") id: Int,

View File

@ -20,5 +20,5 @@ fun OrderRemote.toOrder(): Order = Order(
)
fun Order.toOrderRemote(): OrderRemote = OrderRemote(
uid, userId!!, dateTime, sessions = emptyList()
uid, userId, dateTime, sessions = emptyList()
)

View File

@ -7,9 +7,14 @@ import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.myapplication.LiveStore
import com.example.myapplication.api.MyServerService
import com.example.myapplication.api.user.toUser
import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.model.User
import com.example.myapplication.database.entities.model.UserRole
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
import com.example.myapplication.database.entities.repository.OfflineUserRepository
import com.example.myapplication.database.remotekeys.model.RemoteKeyType
import com.example.myapplication.database.remotekeys.model.RemoteKeys
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
@ -20,9 +25,10 @@ import java.io.IOException
class OrderRemoteMediator(
private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : RemoteMediator<Int, Order>() {
) : RemoteMediator<Int, OrderWithUser>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
@ -30,7 +36,7 @@ class OrderRemoteMediator(
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, Order>
state: PagingState<Int, OrderWithUser>
): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
@ -52,14 +58,23 @@ class OrderRemoteMediator(
}
try {
val orders = service.getOrders(
userId = LiveStore.user.value?.uid ?: 0,
page = page, limit = state.config.pageSize
).map { it.toOrder() }
val user = LiveStore.user
var users: List<User> = emptyList()
val orders: List<Order> = if (user.value?.role == UserRole.ADMIN) {
val temp = service.getOrders(page = page, limit = state.config.pageSize)
users = temp.map { it.user.toUser() }
temp.map { it.toOrder() }
} else {
service.getOrders(
userId = user.value?.uid ?: 0, page = page, limit = state.config.pageSize
).map { it.toOrder() }
}
val endOfPaginationReached = orders.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER)
dbUserRepository.clearUsers()
dbOrderRepository.clearOrders()
}
val prevKey = if (page == 1) null else page - 1
@ -74,6 +89,7 @@ class OrderRemoteMediator(
}
dbRemoteKeyRepository.createRemoteKeys(keys)
dbOrderRepository.insertOrders(orders)
dbUserRepository.insertUsers(users)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
@ -83,14 +99,14 @@ class OrderRemoteMediator(
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Order>): RemoteKeys? {
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, OrderWithUser>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { order ->
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Order>): RemoteKeys? {
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, OrderWithUser>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { order ->
dbRemoteKeyRepository.getAllRemoteKeys(order.uid, RemoteKeyType.ORDER)
@ -98,7 +114,7 @@ class OrderRemoteMediator(
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, Order>
state: PagingState<Int, OrderWithUser>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { orderUid ->

View File

@ -0,0 +1,22 @@
package com.example.myapplication.api.order
import com.example.myapplication.api.session.SessionFromOrderRemote
import com.example.myapplication.api.user.UserRemote
import com.example.myapplication.database.entities.model.Order
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.threeten.bp.LocalDateTime
@Serializable
data class OrderWithUserRemote(
val id: Int = 0,
val userId: Int = 0,
val user: UserRemote,
@Contextual
val dateTime: LocalDateTime = LocalDateTime.now(),
var sessions: List<SessionFromOrderRemote> = emptyList()
)
fun OrderWithUserRemote.toOrder(): Order = Order(
id, userId, dateTime
)

View File

@ -10,9 +10,11 @@ import com.example.myapplication.database.AppContainer
import com.example.myapplication.database.AppDatabase
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderSessionCrossRef
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.model.SessionFromOrder
import com.example.myapplication.database.entities.repository.OfflineOrderRepository
import com.example.myapplication.database.entities.repository.OfflineOrderSessionRepository
import com.example.myapplication.database.entities.repository.OfflineUserRepository
import com.example.myapplication.database.entities.repository.OrderRepository
import com.example.myapplication.database.remotekeys.repository.OfflineRemoteKeyRepository
import kotlinx.coroutines.flow.Flow
@ -20,11 +22,12 @@ import kotlinx.coroutines.flow.Flow
class RestOrderRepository(
private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbUserRepository: OfflineUserRepository,
private val dbOrderSessionRepository: OfflineOrderSessionRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : OrderRepository {
override fun getAllOrders(): Flow<PagingData<Order>> {
override fun getAllOrders(): Flow<PagingData<OrderWithUser>> {
val pagingSourceFactory = { dbOrderRepository.getAllOrdersPagingSource() }
@OptIn(ExperimentalPagingApi::class)
return Pager(
@ -35,6 +38,7 @@ class RestOrderRepository(
remoteMediator = OrderRemoteMediator(
service,
dbOrderRepository,
dbUserRepository,
dbRemoteKeyRepository,
database,
),

View File

@ -80,6 +80,7 @@ class AppDataContainer(private val context: Context) : AppContainer {
RestOrderRepository(
MyServerService.getInstance(),
orderRepository,
userRepository,
orderSessionRepository,
remoteKeyRepository,
AppDatabase.getInstance(context)

View File

@ -24,7 +24,9 @@ import androidx.navigation.NavController
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey
import com.example.myapplication.LiveStore
import com.example.myapplication.composeui.navigation.Screen
import com.example.myapplication.database.entities.model.UserRole
import com.example.myapplication.ui.theme.PmudemoTheme
import org.threeten.bp.format.DateTimeFormatter
@ -66,10 +68,17 @@ fun OrderList(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
"Заказ №${order.uid}, ${formattedDate}",
color = MaterialTheme.colorScheme.onSecondary
)
if (LiveStore.user.value?.role == UserRole.ADMIN)
Text(
"Заказ №${order.uid}, ${formattedDate}\n" +
"Пользователь: ${order.user?.login ?: "Неизвестно"}",
color = MaterialTheme.colorScheme.onSecondary
)
else
Text(
"Заказ №${order.uid}, $formattedDate",
color = MaterialTheme.colorScheme.onSecondary
)
}
}
}

View File

@ -3,11 +3,12 @@ package com.example.myapplication.database.entities.composeui
import androidx.paging.PagingData
import com.example.myapplication.composeui.MyViewModel
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.repository.OrderRepository
import kotlinx.coroutines.flow.Flow
class OrderListViewModel(
orderRepository: OrderRepository
) : MyViewModel() {
var orderListUiState: Flow<PagingData<Order>> = orderRepository.getAllOrders()
val orderListUiState: Flow<PagingData<OrderWithUser>> = orderRepository.getAllOrders()
}

View File

@ -8,12 +8,17 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.model.SessionFromOrder
@Dao
interface OrderDao {
@Query("select * from orders where user_id = :userId")
fun getAll(userId: Int?): PagingSource<Int, Order>
fun getAll(userId: Int?): PagingSource<Int, OrderWithUser>
@Query("select * from orders " +
"left join users on orders.user_id = users.uid")
fun getAll(): PagingSource<Int, OrderWithUser>
@Query(
"SELECT o.*, s.*, os.count, os.frozen_price " +

View File

@ -12,7 +12,7 @@ data class Order(
@PrimaryKey(autoGenerate = true)
val uid: Int,
@ColumnInfo(name = "user_id", index = true)
val userId: Int?,
val userId: Int = 0,
@ColumnInfo(name = "date_time")
val dateTime: LocalDateTime,
) {

View File

@ -0,0 +1,18 @@
package com.example.myapplication.database.entities.model
import androidx.room.ColumnInfo
import androidx.room.Relation
import org.threeten.bp.LocalDateTime
data class OrderWithUser(
val uid: Int,
@ColumnInfo(name = "user_id", index = true)
val userId: Int = 0,
@ColumnInfo(name = "date_time")
val dateTime: LocalDateTime,
@Relation(
parentColumn = "user_id",
entity = User::class,
entityColumn = "uid"
) val user: User?
)

View File

@ -8,24 +8,29 @@ import com.example.myapplication.LiveStore
import com.example.myapplication.database.AppContainer
import com.example.myapplication.database.entities.dao.OrderDao
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.model.SessionFromOrder
import com.example.myapplication.database.entities.model.UserRole
import kotlinx.coroutines.flow.Flow
class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
override fun getAllOrders(): Flow<PagingData<Order>> = Pager(
override fun getAllOrders(): Flow<PagingData<OrderWithUser>> = Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
pagingSourceFactory = { orderDao.getAll(LiveStore.user.value?.uid ?: 0) }
pagingSourceFactory = { getAllOrdersPagingSource() }
).flow
override suspend fun getOrder(uid: Int): List<SessionFromOrder> = orderDao.getByUid(uid)
override suspend fun insertOrder(order: Order): Long = orderDao.insert(order).first()
fun getAllOrdersPagingSource(): PagingSource<Int, Order> {
return orderDao.getAll(LiveStore.user.value?.uid ?: 0)
fun getAllOrdersPagingSource(): PagingSource<Int, OrderWithUser> {
val user = LiveStore.user.value
if (user?.role == UserRole.ADMIN)
return orderDao.getAll()
return orderDao.getAll(user?.uid ?: 0)
}
suspend fun clearOrders() = orderDao.deleteAll()

View File

@ -2,11 +2,12 @@ package com.example.myapplication.database.entities.repository
import androidx.paging.PagingData
import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderWithUser
import com.example.myapplication.database.entities.model.SessionFromOrder
import kotlinx.coroutines.flow.Flow
interface OrderRepository {
fun getAllOrders(): Flow<PagingData<Order>>
fun getAllOrders(): Flow<PagingData<OrderWithUser>>
suspend fun getOrder(uid: Int): List<SessionFromOrder>
suspend fun insertOrder(order: Order): Long
}