ViewModel главного экрана + фикс удаления продукта

This commit is contained in:
Данила Мочалов 2023-11-22 05:11:16 +04:00
parent 65ff36e9bc
commit 377da2968c
10 changed files with 137 additions and 56 deletions

View File

@ -3,6 +3,8 @@ package com.example.shawarma
import android.app.Application
import androidx.room.Room
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.repos.OrderProductRepository
import com.example.shawarma.data.repos.OrderRepository
import com.example.shawarma.data.repos.ProductRepository
import com.example.shawarma.data.repos.UserRepository
import dagger.Module
@ -33,6 +35,18 @@ object AppModule {
@Provides
@Singleton
fun provideProductRepository(db: AppDatabase) : ProductRepository {
return ProductRepository(db.productDao())
return ProductRepository(db.productDao(), db.orderProductDao())
}
@Provides
@Singleton
fun provideOrderRepository(db: AppDatabase) : OrderRepository {
return OrderRepository(db.orderDao())
}
@Provides
@Singleton
fun provideOrderProductRepository(db: AppDatabase) : OrderProductRepository {
return OrderProductRepository(db.orderProductDao())
}
}

View File

@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface OrderDao {
@Insert
suspend fun insert(order: OrderModel)
suspend fun insert(order: OrderModel) : Long
@Update
suspend fun update(order: OrderModel)
@Delete
@ -22,4 +22,6 @@ interface OrderDao {
fun getById(id: Int): Flow<List<OrderWithProducts>>
@Query("select * from orders where orders.user_id =:userId")
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>
}

View File

@ -2,9 +2,16 @@ package com.example.shawarma.data.interfaces.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.shawarma.data.models.OrderProductModel
@Dao
interface OrderProductDao {
@Insert
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);
}

View File

@ -15,7 +15,7 @@ interface ProductDao {
@Update
suspend fun update(product: ProductModel)
@Delete
@Delete()
suspend fun delete(product: ProductModel)
@Query("select * from products where products.product_old_price is null")

View File

@ -10,7 +10,7 @@ data class OrderProductModel(
@ColumnInfo(name = "product_id", index = true)
var productId: Int,
@ColumnInfo(name = "quantity")
val quantity: Int,
var quantity: Int,
@ColumnInfo(name = "total_price")
val totalPrice: Int
var totalPrice: Int
)

View File

@ -1,8 +1,5 @@
package com.example.shawarma.data.repos
import androidx.room.Dao
import androidx.room.Insert
import com.example.shawarma.data.interfaces.dao.OrderDao
import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.models.OrderProductModel
import javax.inject.Inject
@ -13,4 +10,7 @@ class OrderProductRepository @Inject constructor(
suspend fun insert(order: OrderProductModel) {
return orderProductDao.insert(order)
}
suspend fun update(order: OrderProductModel) {
return orderProductDao.update(order)
}
}

View File

@ -1,12 +1,6 @@
package com.example.shawarma.data.repos
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.shawarma.data.interfaces.dao.OrderDao
import com.example.shawarma.data.interfaces.dao.ProductDao
import com.example.shawarma.data.models.OrderModel
import com.example.shawarma.data.models.OrderWithProducts
import kotlinx.coroutines.flow.Flow
@ -15,7 +9,7 @@ import javax.inject.Inject
class OrderRepository @Inject constructor(
private val orderDao: OrderDao
){
suspend fun insert(order: OrderModel) {
suspend fun insert(order: OrderModel): Long {
return orderDao.insert(order)
}
suspend fun update(order:OrderModel) {
@ -33,4 +27,7 @@ class OrderRepository @Inject constructor(
fun getByUserId(userId: Int): Flow<List<OrderWithProducts>> {
return orderDao.getByUserId(userId)
}
fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts?> {
return orderDao.getUnpaidByUser(userId)
}
}

View File

@ -1,17 +1,14 @@
package com.example.shawarma.data.repos
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.interfaces.dao.ProductDao
import com.example.shawarma.data.interfaces.dao.UserDao
import com.example.shawarma.data.models.ProductModel
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class ProductRepository @Inject constructor(
private val productDao: ProductDao
private val productDao: ProductDao,
private val orderProductDao: OrderProductDao
) {
suspend fun insert(product: ProductModel) {
return productDao.insert(product)
@ -20,6 +17,7 @@ class ProductRepository @Inject constructor(
return productDao.update(product)
}
suspend fun delete(product: ProductModel) {
orderProductDao.deleteByProductId(product.id!!)
return productDao.delete(product)
}
fun getAll(): Flow<List<ProductModel>> {

View File

@ -20,9 +20,7 @@ import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -33,18 +31,18 @@ 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 androidx.hilt.navigation.compose.hiltViewModel
import com.example.shawarma.R
import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.models.ProductModel
import com.example.shawarma.data.sharedpref.PreferencesManager
import com.example.shawarma.ui.theme.MarckFamily
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.MyPriceBackground
import com.example.shawarma.ui.theme.NunitoFamily
import com.example.shawarma.viewmodels.HomeViewModel
import com.example.shawarma.widgets.ShawarmaLogo2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun HomeScreen() {
@ -58,16 +56,10 @@ fun HomeScreen() {
@Composable
fun HomeList(){
val context = LocalContext.current
val products = remember { mutableStateListOf<ProductModel>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).productDao().getAll().collect { data ->
products.clear()
products.addAll(data)
}
}
}
val homeViewModel: HomeViewModel = hiltViewModel<HomeViewModel>()
val products = homeViewModel.products.observeAsState().value
Box(
modifier = Modifier
@ -76,7 +68,6 @@ fun HomeList(){
.fillMaxSize()
.background(color = MyMainBackground)
.zIndex(2f),
contentAlignment = Alignment.TopCenter
){
Text(
@ -90,19 +81,9 @@ fun HomeList(){
modifier = Modifier.padding(top = 80.dp)
)
{
items(products.size) { index ->
if (index % 2 == 0 && index == products.size - 1) {
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier
.fillMaxWidth()
.padding(top = 10.dp)
) {
ProductCard(products[index])
}
}
else {
if (index % 2 != 1) {
if (products != null) {
items(products.size) { index ->
if (index % 2 == 0 && index == products.size - 1) {
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier
@ -110,12 +91,23 @@ fun HomeList(){
.padding(top = 10.dp)
) {
ProductCard(products[index])
ProductCard(products[index + 1])
}
} else {
if (index % 2 != 1) {
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = Modifier
.fillMaxWidth()
.padding(top = 10.dp)
) {
ProductCard(products[index])
ProductCard(products[index + 1])
}
}
}
}
if (index == products.size - 1) {
Spacer(modifier = Modifier.height(70.dp))
if (index == products.size - 1) {
Spacer(modifier = Modifier.height(70.dp))
}
}
}
}
@ -124,6 +116,9 @@ fun HomeList(){
@Composable
fun ProductCard(product: ProductModel){
val homeViewModel: HomeViewModel = hiltViewModel<HomeViewModel>()
val preferencesManager = PreferencesManager(LocalContext.current)
Card(
shape = RoundedCornerShape(20.dp),
backgroundColor = Color.White,
@ -155,6 +150,7 @@ fun ProductCard(product: ProductModel){
.size(160.dp, 36.dp)
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween
){
Text(
text = product.price.toString() + " руб.",
@ -164,7 +160,9 @@ fun ProductCard(product: ProductModel){
modifier = Modifier.padding(start = 12.dp, top = 6.dp)
)
Button(
onClick = { /*TODO*/ },
onClick = {
product.id?.let { homeViewModel.addProductToCart(it, preferencesManager.getData("user_id", "null")) }
},
colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow,
contentColor = Color.Black

View File

@ -0,0 +1,65 @@
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.OrderModel
import com.example.shawarma.data.models.OrderProductModel
import com.example.shawarma.data.models.OrderStatus
import com.example.shawarma.data.models.ProductModel
import com.example.shawarma.data.repos.OrderProductRepository
import com.example.shawarma.data.repos.OrderRepository
import com.example.shawarma.data.repos.ProductRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.util.Date
import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
private val productRepository: ProductRepository,
private val orderRepository: OrderRepository,
private val orderProductRepository: OrderProductRepository
) : ViewModel() {
private val _products = MutableLiveData<List<ProductModel>>()
val products: LiveData<List<ProductModel>>
get() = _products
init {
viewModelScope.launch {
productRepository.getAll().collect {
_products.postValue(it)
}
}
}
fun addProductToCart(productId: Int, userId: String) {
if (userId == "null") return
viewModelScope.launch {
val product = productRepository.getById(productId).first()
val order = orderRepository.getUnpaidByUser(userId.toInt()).first()
if (order == null) {
val newOrderId = orderRepository.insert(OrderModel(null, OrderStatus.Неоплачено.name, userId.toInt(), Date()))
orderProductRepository.insert(OrderProductModel(newOrderId.toInt(), productId, 1, product.price))
}
else {
var isAlreadyAdded = false
for (prod in order.orderWithProducts) {
if (prod.product.id == productId) {
val model = prod.orderProductModel
model.quantity += 1
model.totalPrice += prod.product.price
orderProductRepository.update(model)
isAlreadyAdded = true
}
}
if (!isAlreadyAdded) {
orderProductRepository.insert(OrderProductModel(order.order.id!!, productId, 1, product.price))
}
}
}
}
}