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>>
@Query("select * from orders where orders.user_id =:userId and orders.order_status = 'Неоплачено'")
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
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
@ -11,7 +12,8 @@ interface OrderProductDao {
suspend fun insert(order: OrderProductModel)
@Update
suspend fun update(order: OrderProductModel)
@Query("delete from order_product WHERE product_id = :productId")
suspend fun deleteByProductId(productId: Int);
@Delete
suspend fun delete(order: OrderProductModel)
}

View File

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

View File

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