Compare commits

...

3 Commits

24 changed files with 909 additions and 119 deletions

View File

@ -0,0 +1,208 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "fd664bd9d0a27511fb20675444548276",
"entities": [
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_login` TEXT NOT NULL, `user_password` TEXT NOT NULL, `user_role` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "login",
"columnName": "user_login",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "user_password",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "role",
"columnName": "user_role",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "orders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `order_status` TEXT NOT NULL, `user_id` INTEGER, `date` INTEGER NOT NULL, FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "status",
"columnName": "order_status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_orders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_orders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": [
{
"table": "users",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"user_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "products",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `product_title` TEXT NOT NULL, `product_price` INTEGER NOT NULL, `product_old_price` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "product_title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "price",
"columnName": "product_price",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "oldPrice",
"columnName": "product_old_price",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "order_product",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`order_id` INTEGER NOT NULL, `product_id` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `total_price` INTEGER NOT NULL, PRIMARY KEY(`order_id`, `product_id`))",
"fields": [
{
"fieldPath": "orderId",
"columnName": "order_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "productId",
"columnName": "product_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "quantity",
"columnName": "quantity",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "totalPrice",
"columnName": "total_price",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"order_id",
"product_id"
]
},
"indices": [
{
"name": "index_order_product_order_id",
"unique": false,
"columnNames": [
"order_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_order_id` ON `${TABLE_NAME}` (`order_id`)"
},
{
"name": "index_order_product_product_id",
"unique": false,
"columnNames": [
"product_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_product_id` ON `${TABLE_NAME}` (`product_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'fd664bd9d0a27511fb20675444548276')"
]
}
}

View File

@ -0,0 +1,208 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "1ce8ad5b9b5decfebb42bc2f3c33393d",
"entities": [
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_login` TEXT NOT NULL, `user_password` TEXT NOT NULL, `user_role` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "login",
"columnName": "user_login",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "user_password",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "role",
"columnName": "user_role",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "orders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `order_status` TEXT NOT NULL, `user_id` INTEGER, `date` TEXT NOT NULL, FOREIGN KEY(`user_id`) REFERENCES `users`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "status",
"columnName": "order_status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_orders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_orders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": [
{
"table": "users",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"user_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "products",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `product_title` TEXT NOT NULL, `product_price` INTEGER NOT NULL, `product_old_price` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "product_title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "price",
"columnName": "product_price",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "oldPrice",
"columnName": "product_old_price",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "order_product",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`order_id` INTEGER NOT NULL, `product_id` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `total_price` INTEGER NOT NULL, PRIMARY KEY(`order_id`, `product_id`))",
"fields": [
{
"fieldPath": "orderId",
"columnName": "order_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "productId",
"columnName": "product_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "quantity",
"columnName": "quantity",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "totalPrice",
"columnName": "total_price",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"order_id",
"product_id"
]
},
"indices": [
{
"name": "index_order_product_order_id",
"unique": false,
"columnNames": [
"order_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_order_id` ON `${TABLE_NAME}` (`order_id`)"
},
{
"name": "index_order_product_product_id",
"unique": false,
"columnNames": [
"product_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_product_id` ON `${TABLE_NAME}` (`product_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1ce8ad5b9b5decfebb42bc2f3c33393d')"
]
}
}

View File

@ -0,0 +1,196 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "12eb76256f54b2c513a3073a2e582c4c",
"entities": [
{
"tableName": "users",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_login` TEXT NOT NULL, `user_password` TEXT NOT NULL, `user_role` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "login",
"columnName": "user_login",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "user_password",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "role",
"columnName": "user_role",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "orders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `order_status` TEXT NOT NULL, `user_id` INTEGER, `date` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "status",
"columnName": "order_status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_orders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_orders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "products",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `product_title` TEXT NOT NULL, `product_price` INTEGER NOT NULL, `product_old_price` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "product_title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "price",
"columnName": "product_price",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "oldPrice",
"columnName": "product_old_price",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "order_product",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`order_id` INTEGER NOT NULL, `product_id` INTEGER NOT NULL, `quantity` INTEGER NOT NULL, `total_price` INTEGER NOT NULL, PRIMARY KEY(`order_id`, `product_id`))",
"fields": [
{
"fieldPath": "orderId",
"columnName": "order_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "productId",
"columnName": "product_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "quantity",
"columnName": "quantity",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "totalPrice",
"columnName": "total_price",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"order_id",
"product_id"
]
},
"indices": [
{
"name": "index_order_product_order_id",
"unique": false,
"columnNames": [
"order_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_order_id` ON `${TABLE_NAME}` (`order_id`)"
},
{
"name": "index_order_product_product_id",
"unique": false,
"columnNames": [
"product_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_order_product_product_id` ON `${TABLE_NAME}` (`product_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '12eb76256f54b2c513a3073a2e582c4c')"
]
}
}

View File

@ -3,6 +3,8 @@ package com.example.shawarma
import android.app.Application import android.app.Application
import androidx.room.Room import androidx.room.Room
import com.example.shawarma.data.api.MyServerService import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.repos.RestOrderProductRepository
import com.example.shawarma.data.api.repos.RestOrderRepository
import com.example.shawarma.data.api.repos.RestProductRepository import com.example.shawarma.data.api.repos.RestProductRepository
import com.example.shawarma.data.api.repos.RestUserRepository import com.example.shawarma.data.api.repos.RestUserRepository
import com.example.shawarma.data.db.AppDatabase import com.example.shawarma.data.db.AppDatabase
@ -49,8 +51,8 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideProductRepository(db: AppDatabase) : ProductRepository { fun provideProductRepository(db: AppDatabase, restProductRepository: RestProductRepository) : ProductRepository {
return ProductRepository(database = db, db.productDao(), db.orderProductDao()) return ProductRepository(database = db, db.productDao(), db.orderProductDao(), restProductRepository)
} }
@Provides @Provides
@ -61,14 +63,26 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideOrderRepository(db: AppDatabase) : OrderRepository { fun provideOrderRepository(db: AppDatabase, restOrderRepository: RestOrderRepository) : OrderRepository {
return OrderRepository(db.orderDao()) return OrderRepository(db.orderDao(), db.productDao(), db.orderProductDao(), restOrderRepository)
} }
@Provides @Provides
@Singleton @Singleton
fun provideOrderProductRepository(db: AppDatabase) : OrderProductRepository { fun provideRestOrderRepository(service: MyServerService) : RestOrderRepository {
return OrderProductRepository(db.orderProductDao()) return RestOrderRepository(service)
}
@Provides
@Singleton
fun provideOrderProductRepository(db: AppDatabase, restOrderProductRepository: RestOrderProductRepository) : OrderProductRepository {
return OrderProductRepository(db.orderProductDao(), restOrderProductRepository)
}
@Provides
@Singleton
fun provideRestOrderProductRepository(service: MyServerService) : RestOrderProductRepository {
return RestOrderProductRepository(service)
} }

View File

@ -1,6 +1,9 @@
package com.example.shawarma.data.api package com.example.shawarma.data.api
import com.example.shawarma.data.api.models.OrderModelRemote
import com.example.shawarma.data.api.models.OrderProductRemote
import com.example.shawarma.data.api.models.ProductListResponse import com.example.shawarma.data.api.models.ProductListResponse
import com.example.shawarma.data.api.models.ProductModelRemote
import com.example.shawarma.data.api.models.TokenModelRemote import com.example.shawarma.data.api.models.TokenModelRemote
import com.example.shawarma.data.api.models.UserModelRemote import com.example.shawarma.data.api.models.UserModelRemote
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
@ -9,13 +12,18 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header import retrofit2.http.Header
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path import retrofit2.http.Path
interface MyServerService { interface MyServerService {
//
// USER
//
@POST("register") @POST("register")
suspend fun createUser( suspend fun createUser(
@Body user: UserModelRemote, @Body user: UserModelRemote,
@ -31,6 +39,13 @@ interface MyServerService {
@Body user: UserModelRemote @Body user: UserModelRemote
) :UserModelRemote? ) :UserModelRemote?
@GET("user")
suspend fun getUser(@Header("Authorization") token: String) : UserModelRemote?
//
// PRODUCTS
//
@GET("user/products/{after}") @GET("user/products/{after}")
suspend fun getProductsList(@Path("after") after: Int, @Header("Authorization") token: String) : ProductListResponse suspend fun getProductsList(@Path("after") after: Int, @Header("Authorization") token: String) : ProductListResponse
@ -40,6 +55,40 @@ interface MyServerService {
@GET("user/items/{after}") @GET("user/items/{after}")
suspend fun getItemsList(@Path("after") after: Int, @Header("Authorization") token: String) : ProductListResponse suspend fun getItemsList(@Path("after") after: Int, @Header("Authorization") token: String) : ProductListResponse
@POST("product")
suspend fun insertProduct(
@Body product: ProductModelRemote,
@Header("Authorization") token: String
) : ProductModelRemote
@PUT("product")
suspend fun updateProduct(
@Body product: ProductModelRemote,
@Header("Authorization") token: String
): ProductModelRemote
@DELETE("product/{id}")
suspend fun deleteProduct(@Path("id") id: Int, @Header("Authorization") token: String)
//
// ORDERS
//
@GET("order/unpaid")
suspend fun getUnpaidOrder(@Header("Authorization") token: String) : OrderModelRemote
@POST("order")
suspend fun insertOrder(@Body order: OrderModelRemote, @Header("Authorization") token: String) : OrderModelRemote?
//
// ORDER PRODUCTS
//
@POST("order/product")
suspend fun insertOrderProduct(@Body orderProduct: OrderProductRemote, @Header("Authorization") token: String)
@PUT("order/product")
suspend fun updateOrderProduct(@Body orderProduct: OrderProductRemote, @Header("Authorization") token: String)
companion object { companion object {
private const val BASE_URL = "https://10.0.2.2:80/api/" private const val BASE_URL = "https://10.0.2.2:80/api/"

View File

@ -27,30 +27,16 @@ class ProductRemoteMediator (
state: PagingState<Int, ProductModel> state: PagingState<Int, ProductModel>
): MediatorResult { ): MediatorResult {
return try { return try {
// The network load method takes an optional `after=<user.id>` parameter. For every
// page after the first, we pass the last user ID to let it continue from where it
// left off. For REFRESH, pass `null` to load the first page.
var loadKey = when (loadType) { var loadKey = when (loadType) {
LoadType.REFRESH -> null LoadType.REFRESH -> null
// In this example, we never need to prepend, since REFRESH will always load the
// first page in the list. Immediately return, reporting end of pagination.
LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true) LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
LoadType.APPEND -> { LoadType.APPEND -> {
val lastItem = state.lastItemOrNull() val lastItem = state.lastItemOrNull()
?: return MediatorResult.Success(endOfPaginationReached = true) ?: return MediatorResult.Success(endOfPaginationReached = true)
// We must explicitly check if the last item is `null` when appending,
// since passing `null` to networkService is only valid for initial load.
// If lastItem is `null` it means no items were loaded after the initial
// REFRESH and there are no more items to load.
lastItem.id lastItem.id
} }
} }
// Suspending network load via Retrofit. This doesn't need to be wrapped in a
// withContext(Dispatcher.IO) { ... } block since Retrofit's Coroutine CallAdapter
// dispatches on a worker thread.
if (loadKey == null) { if (loadKey == null) {
loadKey = 0 loadKey = 0
} }
@ -74,8 +60,6 @@ class ProductRemoteMediator (
productDao.deleteByQuery(query) productDao.deleteByQuery(query)
} }
// Insert new users into database, which invalidates the current
// PagingData, allowing Paging to present the updates in the DB.
val products = mutableListOf<ProductModel>() val products = mutableListOf<ProductModel>()
for (prod in response.products) { for (prod in response.products) {
products.add(prod.toProductModel()) products.add(prod.toProductModel())

View File

@ -0,0 +1,42 @@
package com.example.shawarma.data.api.models
import com.example.shawarma.data.models.OrderModel
import com.example.shawarma.data.models.OrderProductModel
import kotlinx.serialization.Serializable
@Serializable
data class OrderModelRemote(
val id: Int? = null,
val status: String = "",
val user_id: Int? = -1,
val date: String = "",
val order_products: List<OrderProductRemote> = listOf()
)
fun OrderModelRemote.toOrderModel() : OrderModel = OrderModel(
id, status, user_id, date = date
)
fun OrderModel.toOrderModelRemote() : OrderModelRemote = OrderModelRemote(
id, status, userId, date.toString()
)
@Serializable
data class OrderProductRemote(
val id: Int? = null,
val order_id: Int = -1,
val product_id: Int = -1,
val quantity: Int = 0,
val total_price: Int = 0,
val order: OrderModelRemote? = null,
val product: ProductModelRemote? = null
)
fun OrderProductRemote.toOrderProductModel() : OrderProductModel = OrderProductModel(
order_id, product_id, quantity, total_price
)
fun OrderProductModel.toOrderProductRemote() : OrderProductRemote = OrderProductRemote(
order_id = orderId, product_id = productId, quantity = quantity, total_price = totalPrice
)

View File

@ -5,10 +5,12 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class ProductModelRemote( data class ProductModelRemote(
val id: Int = 0, val id: Int? = null,
val title: String = "", val title: String = "",
val price: Int = 0, val price: Int = 0,
val old_price: Int? = null val old_price: Int? = null,
val order_products: List<OrderProductRemote> = listOf()
) )
@Serializable @Serializable
@ -22,5 +24,5 @@ fun ProductModelRemote.toProductModel(): ProductModel = ProductModel(
) )
fun ProductModel.toProductModelRemote(): ProductModelRemote = ProductModelRemote( fun ProductModel.toProductModelRemote(): ProductModelRemote = ProductModelRemote(
title = title, price = price, old_price = oldPrice title = title, price = price, old_price = oldPrice, id = id
) )

View File

@ -0,0 +1,17 @@
package com.example.shawarma.data.api.repos
import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.models.OrderProductRemote
import javax.inject.Inject
class RestOrderProductRepository @Inject constructor(
private val service: MyServerService
) {
suspend fun insertOrderProduct(token: String, orderProduct: OrderProductRemote) {
service.insertOrderProduct(orderProduct, token)
}
suspend fun updateOrderProduct(token: String, orderProduct: OrderProductRemote) {
service.updateOrderProduct(orderProduct, token)
}
}

View File

@ -0,0 +1,17 @@
package com.example.shawarma.data.api.repos
import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.models.OrderModelRemote
import javax.inject.Inject
class RestOrderRepository@Inject constructor(
private val service: MyServerService
) {
suspend fun getUnpaidOrder(token:String) : OrderModelRemote {
return service.getUnpaidOrder(token)
}
suspend fun insertOrder(token: String, order: OrderModelRemote): OrderModelRemote? {
return service.insertOrder(order, token)
}
}

View File

@ -1,10 +1,22 @@
package com.example.shawarma.data.api.repos package com.example.shawarma.data.api.repos
import com.example.shawarma.data.api.MyServerService import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.models.toProductModelRemote
import com.example.shawarma.data.models.ProductModel
import javax.inject.Inject import javax.inject.Inject
class RestProductRepository @Inject constructor( class RestProductRepository @Inject constructor(
private val service: MyServerService private val service: MyServerService
) { ) {
suspend fun insert(product: ProductModel, token: String) {
service.insertProduct(product.toProductModelRemote(), token)
}
suspend fun update(product: ProductModel, token: String) {
service.updateProduct((product.toProductModelRemote()), token)
}
suspend fun delete(id: Int, token: String) {
service.deleteProduct(id, token)
}
} }

View File

@ -21,4 +21,8 @@ class RestUserRepository @Inject constructor(
suspend fun checkLogin(user: UserModel): UserModelRemote? { suspend fun checkLogin(user: UserModel): UserModelRemote? {
return service.checkLogin(user.toUserModelRemote()) return service.checkLogin(user.toUserModelRemote())
} }
suspend fun getUser(token: String) : UserModelRemote? {
return service.getUser(token)
}
} }

View File

@ -1,6 +1,7 @@
package com.example.shawarma.data.db package com.example.shawarma.data.db
import android.content.Context import android.content.Context
import androidx.room.AutoMigration
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
@ -26,8 +27,9 @@ import kotlinx.coroutines.launch
ProductModel::class, ProductModel::class,
OrderProductModel::class, OrderProductModel::class,
], ],
version = 1, version = 3,
exportSchema = false autoMigrations = [AutoMigration (from = 1, to = 2), AutoMigration (from = 2, to = 3)],
exportSchema = true
) )
@TypeConverters(Converter::class) @TypeConverters(Converter::class)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {

View File

@ -2,19 +2,10 @@ package com.example.shawarma.data.models
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.util.Date
@Entity( @Entity(
tableName = "orders", tableName = "orders"
foreignKeys = [
ForeignKey(
entity = UserModel::class,
parentColumns = ["id"],
childColumns = ["user_id"],
)
]
) )
data class OrderModel( data class OrderModel(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ -25,7 +16,7 @@ data class OrderModel(
@ColumnInfo(name = "user_id", index = true) @ColumnInfo(name = "user_id", index = true)
val userId: Int?, val userId: Int?,
@ColumnInfo(name = "date") @ColumnInfo(name = "date")
val date: Date val date: String
) )
fun getOrdersByUserId() : List<OrderModel> { fun getOrdersByUserId() : List<OrderModel> {

View File

@ -1,17 +1,22 @@
package com.example.shawarma.data.repos package com.example.shawarma.data.repos
import com.example.shawarma.data.api.models.toOrderProductRemote
import com.example.shawarma.data.api.repos.RestOrderProductRepository
import com.example.shawarma.data.interfaces.dao.OrderProductDao import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.models.OrderProductModel import com.example.shawarma.data.models.OrderProductModel
import javax.inject.Inject import javax.inject.Inject
class OrderProductRepository @Inject constructor( class OrderProductRepository @Inject constructor(
private val orderProductDao: OrderProductDao private val orderProductDao: OrderProductDao,
private val restOrderProductRepository: RestOrderProductRepository
) { ) {
suspend fun insert(order: OrderProductModel) { suspend fun insert(token: String, orderProduct: OrderProductModel) {
return orderProductDao.insert(order) orderProductDao.insert(orderProduct)
return restOrderProductRepository.insertOrderProduct(token, orderProduct.toOrderProductRemote())
} }
suspend fun update(order: OrderProductModel) { suspend fun update(token: String, orderProduct: OrderProductModel) {
return orderProductDao.update(order) orderProductDao.update(orderProduct)
return restOrderProductRepository.updateOrderProduct(token, orderProduct.toOrderProductRemote())
} }
suspend fun delete(order: OrderProductModel) { suspend fun delete(order: OrderProductModel) {
return orderProductDao.delete(order) return orderProductDao.delete(order)

View File

@ -1,16 +1,31 @@
package com.example.shawarma.data.repos package com.example.shawarma.data.repos
import com.example.shawarma.data.api.models.toOrderModel
import com.example.shawarma.data.api.models.toOrderModelRemote
import com.example.shawarma.data.api.models.toOrderProductModel
import com.example.shawarma.data.api.models.toProductModel
import com.example.shawarma.data.api.repos.RestOrderRepository
import com.example.shawarma.data.interfaces.dao.OrderDao import com.example.shawarma.data.interfaces.dao.OrderDao
import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.interfaces.dao.ProductDao
import com.example.shawarma.data.models.OrderModel import com.example.shawarma.data.models.OrderModel
import com.example.shawarma.data.models.OrderWithProducts import com.example.shawarma.data.models.OrderWithProducts
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import javax.inject.Inject import javax.inject.Inject
class OrderRepository @Inject constructor( class OrderRepository @Inject constructor(
private val orderDao: OrderDao private val orderDao: OrderDao,
private val productDao: ProductDao,
private val orderProductDao: OrderProductDao,
private val restRepository: RestOrderRepository
){ ){
suspend fun insert(order: OrderModel): Long { suspend fun insert(token: String, order: OrderModel): OrderModel? {
return orderDao.insert(order) val result = restRepository.insertOrder(token, order.toOrderModelRemote())
if (result == null) {
return result
}
return result.toOrderModel()
} }
suspend fun update(order:OrderModel) { suspend fun update(order:OrderModel) {
return orderDao.update(order) return orderDao.update(order)
@ -27,8 +42,20 @@ class OrderRepository @Inject constructor(
fun getByUserId(userId: Int): Flow<List<OrderWithProducts>> { fun getByUserId(userId: Int): Flow<List<OrderWithProducts>> {
return orderDao.getByUserId(userId) return orderDao.getByUserId(userId)
} }
fun getUnpaidByUser(userId: Int) : Flow<OrderWithProducts?> { suspend fun getUnpaidByUser(token: String) : OrderWithProducts? {
return orderDao.getUnpaidByUser(userId) val order = restRepository.getUnpaidOrder(token)
if (orderDao.getUnpaidByUser(order.user_id!!).first() != null) {
return orderDao.getUnpaidByUser(order.user_id!!).first()
}
if (order!!.id != null) {
orderDao.insert(order.toOrderModel())
for (product in order.order_products) {
orderProductDao.insert(product.toOrderProductModel())
productDao.insert(product.product!!.toProductModel())
}
return orderDao.getUnpaidByUser(order.user_id!!).first()
}
return null
} }
fun getPaidByUser(userId: Int) : Flow<List<OrderWithProducts>> { fun getPaidByUser(userId: Int) : Flow<List<OrderWithProducts>> {
return orderDao.getPaidByUser(userId) return orderDao.getPaidByUser(userId)

View File

@ -6,6 +6,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData import androidx.paging.PagingData
import com.example.shawarma.data.api.MyServerService import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.mediators.ProductRemoteMediator import com.example.shawarma.data.api.mediators.ProductRemoteMediator
import com.example.shawarma.data.api.repos.RestProductRepository
import com.example.shawarma.data.db.AppDatabase import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.interfaces.dao.OrderProductDao import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.interfaces.dao.ProductDao import com.example.shawarma.data.interfaces.dao.ProductDao
@ -16,17 +17,19 @@ import javax.inject.Inject
class ProductRepository @Inject constructor( class ProductRepository @Inject constructor(
private val database: AppDatabase, private val database: AppDatabase,
private val productDao: ProductDao, private val productDao: ProductDao,
private val orderProductDao: OrderProductDao private val orderProductDao: OrderProductDao,
private val restRepository: RestProductRepository
) { ) {
suspend fun insert(product: ProductModel) { suspend fun insert(product: ProductModel, token: String) {
return productDao.insert(product) return restRepository.insert(product, token)
} }
suspend fun update(product: ProductModel) { suspend fun update(product: ProductModel, token: String) {
return productDao.update(product) return restRepository.update(product, token)
} }
suspend fun delete(product: ProductModel) { suspend fun delete(product: ProductModel, token: String) {
orderProductDao.deleteByProductId(product.id!!) //orderProductDao.deleteByProductId(product.id!!)
return productDao.delete(product) productDao.delete(product)
return restRepository.delete(product.id!!, token)
} }
fun getById(id: Int): Flow<ProductModel> { fun getById(id: Int): Flow<ProductModel> {
return productDao.getById(id) return productDao.getById(id)
@ -51,12 +54,14 @@ class ProductRepository @Inject constructor(
remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "discounts", token = token) remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "discounts", token = token)
).flow ).flow
fun getAllItemsPaged(): Flow<PagingData<ProductModel>> = Pager( @OptIn(ExperimentalPagingApi::class)
fun getAllItemsPaged(token: String): Flow<PagingData<ProductModel>> = Pager(
config = PagingConfig( config = PagingConfig(
pageSize = 6, pageSize = 6,
enablePlaceholders = false enablePlaceholders = false
), ),
pagingSourceFactory = productDao::getPagedItems pagingSourceFactory = productDao::getPagedItems,
remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "items", token = token)
).flow ).flow
} }

View File

@ -167,7 +167,7 @@ fun ProductCard(product: ProductModel){
) )
Button( Button(
onClick = { onClick = {
product.id?.let { homeViewModel.addProductToCart(it, preferencesManager.getData("user_id", "null")) } product.id?.let { homeViewModel.addProductToCart(it, preferencesManager.getData("token", "null")) }
}, },
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow, backgroundColor = MyLightYellow,

View File

@ -20,6 +20,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -27,6 +28,7 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
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.MyLightYellow import com.example.shawarma.ui.theme.MyLightYellow
import com.example.shawarma.ui.theme.MyMainBackground import com.example.shawarma.ui.theme.MyMainBackground
@ -49,6 +51,9 @@ fun ProductScreen(navHostController: NavHostController, productId: Int?) {
@Composable @Composable
fun ProductWidget(navHostController: NavHostController, productId: Int?) { fun ProductWidget(navHostController: NavHostController, productId: Int?) {
val preferencesManager = PreferencesManager(LocalContext.current)
val searchToken = preferencesManager.getData("token", "")
val title = remember { mutableStateOf(TextFieldValue(""))} val title = remember { mutableStateOf(TextFieldValue(""))}
val price = remember { mutableStateOf(TextFieldValue(""))} val price = remember { mutableStateOf(TextFieldValue(""))}
val oldPrice = remember { mutableStateOf(TextFieldValue(""))} val oldPrice = remember { mutableStateOf(TextFieldValue(""))}
@ -71,8 +76,10 @@ fun ProductWidget(navHostController: NavHostController, productId: Int?) {
if (product != null) { if (product != null) {
title.value = TextFieldValue(text = product.title) title.value = TextFieldValue(text = product.title)
price.value = TextFieldValue(text = product.price.toString()) price.value = TextFieldValue(text = product.price.toString())
if (product.oldPrice != null) {
oldPrice.value = TextFieldValue(text = product.oldPrice.toString()) oldPrice.value = TextFieldValue(text = product.oldPrice.toString())
} }
}
Box( Box(
modifier = Modifier modifier = Modifier
@ -140,9 +147,9 @@ fun ProductWidget(navHostController: NavHostController, productId: Int?) {
shape = RoundedCornerShape(20.dp), shape = RoundedCornerShape(20.dp),
onClick = { onClick = {
if (product == null) if (product == null)
productViewModel.addProduct(title.value.text, price.value.text.toInt(), if (!oldPrice.value.text.isNullOrEmpty()) oldPrice.value.text.toInt() else null) productViewModel.addProduct(title.value.text, price.value.text.toInt(), if (!oldPrice.value.text.isNullOrEmpty()) oldPrice.value.text.toInt() else null, searchToken)
else else
productViewModel.updateProduct(title.value.text, price.value.text.toInt(), if (!oldPrice.value.text.isNullOrEmpty()) oldPrice.value.text.toInt() else null) productViewModel.updateProduct(title.value.text, price.value.text.toInt(), if (!oldPrice.value.text.isNullOrEmpty()) oldPrice.value.text.toInt() else null, searchToken)
} }
) { ) {
Text( Text(

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.res.painterResource 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
@ -35,6 +36,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey import androidx.paging.compose.itemKey
import com.example.shawarma.R import com.example.shawarma.R
import com.example.shawarma.data.models.ProductModel 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.MarckFamily
import com.example.shawarma.ui.theme.MyLightRed import com.example.shawarma.ui.theme.MyLightRed
import com.example.shawarma.ui.theme.MyLightYellow import com.example.shawarma.ui.theme.MyLightYellow
@ -59,9 +61,12 @@ fun ProductsScreen(navHostController: NavHostController) {
@Composable @Composable
fun ProductsList(navHostController: NavHostController){ fun ProductsList(navHostController: NavHostController){
val preferencesManager = PreferencesManager(LocalContext.current)
val searchToken = preferencesManager.getData("token", "")
val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>() val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>()
val products = productsViewModel.productListUiState.collectAsLazyPagingItems() val products = productsViewModel.getItemsList(searchToken).collectAsLazyPagingItems()
Box( Box(
modifier = Modifier modifier = Modifier
@ -108,7 +113,7 @@ fun ProductsList(navHostController: NavHostController){
products.itemCount, products.itemCount,
key = products.itemKey() key = products.itemKey()
) { index -> ) { index ->
ProductItem(products[index]!!, navHostController) ProductItem(products[index]!!, navHostController, productsViewModel, searchToken)
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
if (index == products.itemCount - 1) { if (index == products.itemCount - 1) {
Spacer(modifier = Modifier.height(70.dp)) Spacer(modifier = Modifier.height(70.dp))
@ -120,9 +125,7 @@ fun ProductsList(navHostController: NavHostController){
} }
@Composable @Composable
fun ProductItem(product: ProductModel, navHostController: NavHostController){ fun ProductItem(product: ProductModel, navHostController: NavHostController, productsViewModel: ProductsViewModel, token: String){
val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>()
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),
@ -189,7 +192,7 @@ fun ProductItem(product: ProductModel, navHostController: NavHostController){
backgroundColor = MyLightRed backgroundColor = MyLightRed
), ),
onClick = { onClick = {
productsViewModel.deleteProduct(product) productsViewModel.deleteProduct(product, token)
} }
) { ) {
Icon( Icon(

View File

@ -25,17 +25,17 @@ class CartViewModel @Inject constructor(
get() = _paidOrders get() = _paidOrders
fun getOrders(userId: String) { fun getOrders(userId: String) {
if (userId == "null") return // if (userId == "null") return
viewModelScope.launch { // viewModelScope.launch {
orderRepository.getUnpaidByUser(userId.toInt()).collect { // orderRepository.getUnpaidByUser(userId.toInt()).collect {
_unpaidOrder.postValue(it) // _unpaidOrder.postValue(it)
} // }
} // }
viewModelScope.launch { // viewModelScope.launch {
orderRepository.getPaidByUser(userId.toInt()).collect { // orderRepository.getPaidByUser(userId.toInt()).collect {
_paidOrders.postValue(it) // _paidOrders.postValue(it)
} // }
} // }
} }
fun payForOrder(order: OrderWithProducts) { fun payForOrder(order: OrderWithProducts) {
val model = order.order val model = order.order
@ -46,28 +46,28 @@ class CartViewModel @Inject constructor(
} }
fun removeProductFromOrder(order: OrderWithProducts, productId: Int) { fun removeProductFromOrder(order: OrderWithProducts, productId: Int) {
val model = order.orderWithProducts[productId].orderProductModel // val model = order.orderWithProducts[productId].orderProductModel
if(model.quantity == 1) { // if(model.quantity == 1) {
// delete // // delete
viewModelScope.launch { // viewModelScope.launch {
orderProductRepository.delete(model) // orderProductRepository.delete(model)
} // }
} // }
else{ // else{
// update // // update
model.quantity -= 1 // model.quantity -= 1
viewModelScope.launch { // viewModelScope.launch {
orderProductRepository.update(model) // orderProductRepository.update(model)
} // }
} // }
} }
fun addProductToOrder(order: OrderWithProducts, productId: Int) { fun addProductToOrder(order: OrderWithProducts, productId: Int) {
val model = order.orderWithProducts[productId].orderProductModel // val model = order.orderWithProducts[productId].orderProductModel
// update // // update
model.quantity += 1 // model.quantity += 1
viewModelScope.launch { // viewModelScope.launch {
orderProductRepository.update(model) // orderProductRepository.update(model)
} // }
} }
} }

View File

@ -34,18 +34,18 @@ class HomeViewModel @Inject constructor(
} }
fun addProductToCart(productId: Int, userId: String) { fun addProductToCart(productId: Int, token: String) {
if (userId == "null") return
viewModelScope.launch { viewModelScope.launch {
val product = productRepository.getById(productId).first() val product = productRepository.getById(productId).first()
val order = orderRepository.getUnpaidByUser(userId.toInt()).first() val order = orderRepository.getUnpaidByUser(token)
if (order == null) { if (order == null) {
val calendar: Calendar = Calendar.getInstance() val calendar: Calendar = Calendar.getInstance()
calendar.time = Date() calendar.time = Date()
calendar.add(Calendar.HOUR_OF_DAY, 4) calendar.add(Calendar.HOUR_OF_DAY, 4)
val newOrderId = orderRepository.insert(OrderModel(null, OrderStatus.Неоплачено.name, userId.toInt(),calendar.time)) val newOrder = orderRepository.insert(token, OrderModel(null, OrderStatus.Неоплачено.name, null, calendar.time.toString()))
orderProductRepository.insert(OrderProductModel(newOrderId.toInt(), productId, 1, product.price)) if (newOrder != null) {
orderProductRepository.insert(token, OrderProductModel(newOrder.id!!, productId, 1, product.price))
}
} }
else { else {
var isAlreadyAdded = false var isAlreadyAdded = false
@ -54,12 +54,12 @@ class HomeViewModel @Inject constructor(
val model = prod.orderProductModel val model = prod.orderProductModel
model.quantity += 1 model.quantity += 1
model.totalPrice += prod.product.price model.totalPrice += prod.product.price
orderProductRepository.update(model) orderProductRepository.update(token, model)
isAlreadyAdded = true isAlreadyAdded = true
} }
} }
if (!isAlreadyAdded) { if (!isAlreadyAdded) {
orderProductRepository.insert(OrderProductModel(order.order.id!!, productId, 1, product.price)) orderProductRepository.insert(token, OrderProductModel(order.order.id!!, productId, 1, product.price))
} }
} }
} }

View File

@ -22,9 +22,9 @@ class ProductViewModel @Inject constructor(
val product: LiveData<ProductModel> val product: LiveData<ProductModel>
get() = _product get() = _product
fun addProduct(name: String, price: Int, oldPrice: Int? = null) { fun addProduct(name: String, price: Int, oldPrice: Int? = null, token: String) {
viewModelScope.launch { viewModelScope.launch {
productRepository.insert(ProductModel(null, name, price, oldPrice)) productRepository.insert(ProductModel(null, name, price, oldPrice), token)
_addingProductState.postValue(true) _addingProductState.postValue(true)
} }
} }
@ -37,9 +37,9 @@ class ProductViewModel @Inject constructor(
} }
} }
fun updateProduct(name: String, price: Int, oldPrice: Int? = null) { fun updateProduct(name: String, price: Int, oldPrice: Int? = null, token: String) {
viewModelScope.launch { viewModelScope.launch {
productRepository.update(ProductModel(product.value?.id, name, price, oldPrice)) productRepository.update(ProductModel(product.value?.id, name, price, oldPrice), token)
_addingProductState.postValue(true) _addingProductState.postValue(true)
} }
} }

View File

@ -1,7 +1,5 @@
package com.example.shawarma.viewmodels package com.example.shawarma.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData import androidx.paging.PagingData
@ -16,15 +14,14 @@ import javax.inject.Inject
class ProductsViewModel @Inject constructor( class ProductsViewModel @Inject constructor(
private val productRepository: ProductRepository private val productRepository: ProductRepository
) : ViewModel() { ) : ViewModel() {
private val _products = MutableLiveData<List<ProductModel>>()
val products: LiveData<List<ProductModel>>
get() = _products
val productListUiState: Flow<PagingData<ProductModel>> = productRepository.getAllItemsPaged() fun getItemsList(token:String): Flow<PagingData<ProductModel>> {
return productRepository.getAllItemsPaged(token)
}
fun deleteProduct(product: ProductModel) { fun deleteProduct(product: ProductModel, token: String) {
viewModelScope.launch { viewModelScope.launch {
productRepository.delete(product) productRepository.delete(product, token)
} }
} }