ViewModel корзины

This commit is contained in:
Данила Мочалов 2023-11-26 22:48:44 +04:00
parent 6a063c1f59
commit 6a2e730973
7 changed files with 210 additions and 109 deletions

View File

@ -24,4 +24,6 @@ interface OrderDao {
fun getByUserId(userId: Int): Flow<List<OrderWithProducts>> fun getByUserId(userId: Int): Flow<List<OrderWithProducts>>
@Query("select * from orders where orders.user_id =:userId and orders.order_status = 'Неоплачено'") @Query("select * from orders where orders.user_id =:userId and orders.order_status = 'Неоплачено'")
fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts> fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts>
@Query("select * from orders where orders.user_id =:userId and orders.order_status = 'Готовится'")
fun getPaidByUser(userId: Int) : Flow<List<OrderWithProducts>>
} }

View File

@ -1,6 +1,7 @@
package com.example.shawarma.data.interfaces.dao package com.example.shawarma.data.interfaces.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
@ -11,7 +12,8 @@ interface OrderProductDao {
suspend fun insert(order: OrderProductModel) suspend fun insert(order: OrderProductModel)
@Update @Update
suspend fun update(order: OrderProductModel) suspend fun update(order: OrderProductModel)
@Query("delete from order_product WHERE product_id = :productId") @Query("delete from order_product WHERE product_id = :productId")
suspend fun deleteByProductId(productId: Int); suspend fun deleteByProductId(productId: Int);
@Delete
suspend fun delete(order: OrderProductModel)
} }

View File

@ -21,7 +21,7 @@ data class OrderModel(
@ColumnInfo(name = "id") @ColumnInfo(name = "id")
val id: Int?, val id: Int?,
@ColumnInfo(name = "order_status") @ColumnInfo(name = "order_status")
val status: String, var status: String,
@ColumnInfo(name = "user_id", index = true) @ColumnInfo(name = "user_id", index = true)
val userId: Int?, val userId: Int?,
@ColumnInfo(name = "date") @ColumnInfo(name = "date")

View File

@ -13,4 +13,8 @@ class OrderProductRepository @Inject constructor(
suspend fun update(order: OrderProductModel) { suspend fun update(order: OrderProductModel) {
return orderProductDao.update(order) return orderProductDao.update(order)
} }
suspend fun delete(order: OrderProductModel) {
return orderProductDao.delete(order)
}
} }

View File

@ -30,4 +30,7 @@ class OrderRepository @Inject constructor(
fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts?> { fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts?> {
return orderDao.getUnpaidByUser(userId) return orderDao.getUnpaidByUser(userId)
} }
fun getPaidByUser(userId: Int) : Flow<List<OrderWithProducts>> {
return orderDao.getPaidByUser(userId)
}
} }

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@ -20,12 +21,9 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -33,23 +31,20 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import com.example.shawarma.R import androidx.hilt.navigation.compose.hiltViewModel
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.models.OrderStatus
import com.example.shawarma.data.models.OrderWithProducts import com.example.shawarma.data.models.OrderWithProducts
import com.example.shawarma.data.sharedpref.PreferencesManager
import com.example.shawarma.ui.theme.MarckFamily import com.example.shawarma.ui.theme.MarckFamily
import com.example.shawarma.ui.theme.MyLightRed import com.example.shawarma.ui.theme.MyLightYellow
import com.example.shawarma.ui.theme.MyMainBackground import com.example.shawarma.ui.theme.MyMainBackground
import com.example.shawarma.ui.theme.MyOrange import com.example.shawarma.ui.theme.MyOrange
import com.example.shawarma.ui.theme.NunitoFamily import com.example.shawarma.ui.theme.NunitoFamily
import com.example.shawarma.viewmodels.CartViewModel
import com.example.shawarma.widgets.ShawarmaLogo2 import com.example.shawarma.widgets.ShawarmaLogo2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable @Composable
fun CartScreen() { fun CartScreen() {
@ -63,29 +58,13 @@ fun CartScreen() {
@Composable @Composable
fun CartWidget(){ fun CartWidget(){
val preferencesManager = PreferencesManager(LocalContext.current)
val context = LocalContext.current val cartViewModel: CartViewModel = hiltViewModel<CartViewModel>()
val orders = remember { mutableStateListOf<OrderWithProducts>() } cartViewModel.getOrders(preferencesManager.getData("user_id", "null"))
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).orderDao().getByUserId(1).collect { data ->
orders.clear()
orders.addAll(data)
}
}
}
var unpaidOrder: OrderWithProducts? = null var unpaidOrder: OrderWithProducts? = cartViewModel.unpaidOrder.observeAsState().value
val preparingOrders = mutableListOf<OrderWithProducts>() val preparingOrders = cartViewModel.paidOrders.observeAsState().value
for(order in orders) {
if (order.order.status == OrderStatus.Неоплачено.toString()) {
unpaidOrder = order
}
if (order.order.status == OrderStatus.Готовится.toString() || order.order.status == OrderStatus.Готово.toString()) {
preparingOrders.add(order)
}
}
Box( Box(
modifier = Modifier modifier = Modifier
@ -94,7 +73,6 @@ fun CartWidget(){
.fillMaxSize() .fillMaxSize()
.background(color = MyMainBackground) .background(color = MyMainBackground)
.zIndex(2f), .zIndex(2f),
contentAlignment = Alignment.TopCenter contentAlignment = Alignment.TopCenter
) { ) {
Text( Text(
@ -110,7 +88,6 @@ fun CartWidget(){
.padding(top = 55.dp) .padding(top = 55.dp)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
Text( Text(
text = "Оплачено:", text = "Оплачено:",
fontFamily = NunitoFamily, fontFamily = NunitoFamily,
@ -123,10 +100,12 @@ fun CartWidget(){
.width(340.dp) .width(340.dp)
.height(200.dp) .height(200.dp)
) { ) {
if (preparingOrders != null) {
items(preparingOrders.size) { index -> items(preparingOrders.size) { index ->
PaidItem(preparingOrders[index]) PaidItem(preparingOrders[index])
} }
} }
}
Text( Text(
text = "Ожидает оплаты:", text = "Ожидает оплаты:",
fontFamily = NunitoFamily, fontFamily = NunitoFamily,
@ -137,9 +116,7 @@ fun CartWidget(){
if (unpaidOrder != null) { if (unpaidOrder != null) {
CartItem(order = unpaidOrder) CartItem(order = unpaidOrder)
} }
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
Button( Button(
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = Color(0xFF91FF87) backgroundColor = Color(0xFF91FF87)
@ -147,7 +124,11 @@ fun CartWidget(){
shape = RoundedCornerShape(20.dp), shape = RoundedCornerShape(20.dp),
border = BorderStroke(2.dp, Color(0x66000000)), border = BorderStroke(2.dp, Color(0x66000000)),
modifier = Modifier.size(240.dp, 60.dp), modifier = Modifier.size(240.dp, 60.dp),
onClick = { /*TODO*/ } onClick = {
if (unpaidOrder != null) {
cartViewModel.payForOrder(unpaidOrder)
}
}
) { ) {
Text( Text(
"Оплатить", "Оплатить",
@ -156,10 +137,7 @@ fun CartWidget(){
fontWeight = FontWeight(700), fontWeight = FontWeight(700),
) )
} }
Spacer(modifier = Modifier.height(70.dp)) Spacer(modifier = Modifier.height(70.dp))
} }
} }
} }
@ -170,11 +148,8 @@ fun PaidItem(order : OrderWithProducts) {
border = BorderStroke(width = 2.dp, color = MyOrange), border = BorderStroke(width = 2.dp, color = MyOrange),
shape = RoundedCornerShape(size = 20.dp), shape = RoundedCornerShape(size = 20.dp),
backgroundColor = Color.White, backgroundColor = Color.White,
modifier = Modifier.size(340.dp, 100.dp) modifier = Modifier.size(340.dp, 150.dp)
) { ) {
LazyColumn {
items(order.orderWithProducts.size) { index ->
if (index == 0) {
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier modifier = Modifier
@ -198,7 +173,11 @@ fun PaidItem(order : OrderWithProducts) {
color = Color.Gray color = Color.Gray
) )
} }
} LazyColumn(
modifier = Modifier.padding(top = 40.dp)
) {
items(order.orderWithProducts.size) { index ->
if (order.orderWithProducts.isNotEmpty()) {
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier modifier = Modifier
@ -230,11 +209,14 @@ fun PaidItem(order : OrderWithProducts) {
} }
} }
} }
}
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
@Composable @Composable
fun CartItem(order : OrderWithProducts) { fun CartItem(order : OrderWithProducts) {
val cartViewModel: CartViewModel = hiltViewModel<CartViewModel>()
Card( Card(
border = BorderStroke(width = 2.dp, color = MyOrange), border = BorderStroke(width = 2.dp, color = MyOrange),
shape = RoundedCornerShape(size = 20.dp), shape = RoundedCornerShape(size = 20.dp),
@ -245,13 +227,17 @@ fun CartItem(order : OrderWithProducts) {
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
items(order.orderWithProducts.size) {index -> items(order.orderWithProducts.size) {index ->
var count = remember { mutableStateOf(0)}
count.value = order.orderWithProducts[index].orderProductModel.quantity
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.padding(20.dp).size(340.dp, 60.dp) modifier = Modifier
.padding(20.dp)
.size(340.dp, 80.dp)
) { ) {
Column( Column(
modifier = Modifier.fillMaxWidth(0.5f) modifier = Modifier.fillMaxWidth()
) { ) {
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -263,40 +249,71 @@ fun CartItem(order : OrderWithProducts) {
fontSize = 20.sp, fontSize = 20.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
Text(
text = "x" + order.orderWithProducts[index].orderProductModel.quantity,
fontFamily = NunitoFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
}
Text( Text(
text = order.orderWithProducts[index].orderProductModel.totalPrice.toString() + " руб.", text = order.orderWithProducts[index].orderProductModel.totalPrice.toString() + " руб.",
fontFamily = NunitoFamily, fontFamily = NunitoFamily,
fontSize = 20.sp, fontSize = 18.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
} }
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
) {
Button( Button(
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightRed backgroundColor = MyLightYellow
), ),
shape = RoundedCornerShape(size = 10.dp), shape = RoundedCornerShape(size = 20.dp),
modifier = Modifier modifier = Modifier
.size(100.dp, 60.dp) .fillMaxHeight()
.weight(1f)
.fillMaxSize(0.5f), .fillMaxSize(0.5f),
onClick = { /*TODO*/ } onClick = {
cartViewModel.removeProductFromOrder(order, index)
count.value -= 1
}
) { ) {
Icon( Text(
painter = painterResource(id = R.drawable.trash), text = "-",
contentDescription = "Delete", fontSize = 18.sp,
modifier = Modifier.size(42.dp) fontWeight = FontWeight.Bold
) )
} }
Spacer(modifier = Modifier.fillMaxWidth(0.2f))
Text(
text = "x" + count.value + " ",
fontFamily = NunitoFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.fillMaxWidth(0.2f))
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow
),
shape = RoundedCornerShape(size = 20.dp),
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.fillMaxSize(0.5f),
onClick = {
cartViewModel.addProductToOrder(order, index)
count.value += 1
}
) {
Text(
text = "+",
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
}
}
}
}
} }
}
} }
} }
} }

View File

@ -0,0 +1,73 @@
package com.example.shawarma.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.shawarma.data.models.OrderStatus
import com.example.shawarma.data.models.OrderWithProducts
import com.example.shawarma.data.repos.OrderProductRepository
import com.example.shawarma.data.repos.OrderRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class CartViewModel @Inject constructor(
private val orderRepository: OrderRepository,
private val orderProductRepository: OrderProductRepository
) : ViewModel(){
private val _unpaidOrder = MutableLiveData<OrderWithProducts>()
val unpaidOrder: LiveData<OrderWithProducts>
get() = _unpaidOrder
private val _paidOrders = MutableLiveData<List<OrderWithProducts>>()
val paidOrders: LiveData<List<OrderWithProducts>>
get() = _paidOrders
fun getOrders(userId: String) {
if (userId == "null") return
viewModelScope.launch {
orderRepository.getUnpaidByUser(userId.toInt()).collect {
_unpaidOrder.postValue(it)
}
}
viewModelScope.launch {
orderRepository.getPaidByUser(userId.toInt()).collect {
_paidOrders.postValue(it)
}
}
}
fun payForOrder(order: OrderWithProducts) {
val model = order.order
model.status = OrderStatus.Готовится.name
viewModelScope.launch {
orderRepository.update(model)
}
}
fun removeProductFromOrder(order: OrderWithProducts, productId: Int) {
val model = order.orderWithProducts[productId].orderProductModel
if(model.quantity == 1) {
// delete
viewModelScope.launch {
orderProductRepository.delete(model)
}
}
else{
// update
model.quantity -= 1
viewModelScope.launch {
orderProductRepository.update(model)
}
}
}
fun addProductToOrder(order: OrderWithProducts, productId: Int) {
val model = order.orderWithProducts[productId].orderProductModel
// update
model.quantity += 1
viewModelScope.launch {
orderProductRepository.update(model)
}
}
}