Compare commits

...

2 Commits
main ... laba4

Author SHA1 Message Date
d15611e909 lab 4 end 2023-12-09 13:03:28 +03:00
afe79f3b4b lab 4 start 2023-11-29 11:04:31 +03:00
42 changed files with 1232 additions and 224 deletions

View File

@ -51,6 +51,8 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5")
implementation("com.google.android.material:material:1.9.0") implementation("com.google.android.material:material:1.9.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.6.0") implementation("androidx.navigation:navigation-fragment-ktx:2.6.0")
implementation("androidx.navigation:navigation-ui-ktx:2.6.0") implementation("androidx.navigation:navigation-ui-ktx:2.6.0")

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application <application
android:name=".PizzaApplication"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"

View File

@ -1,6 +1,7 @@
package com.example.pizza package com.example.pizza
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -11,26 +12,44 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.ViewModelStoreOwner
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.paging.PagingData
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.runBlocking
class Auth : Fragment() { class Auth : Fragment() {
private var userDao: UserDao? = null private var userViewModel : UserViewModel? = null
val viewModel: myViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel : UserViewModel by viewModels(
factoryProducer = {AppViewModelProvider.Factory}
)
userViewModel = viewModel
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
// Inflate the layout for this fragment // Inflate the layout for this fragment
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
val view = inflater.inflate(R.layout.fragment_auth, container, false) val view = inflater.inflate(R.layout.fragment_auth, container, false)
view.findViewById<Button>(R.id.button_auth).setOnClickListener {buttonClick(view)} view.findViewById<Button>(R.id.button_auth).setOnClickListener {buttonClick(view)}
view.findViewById<TextView>(R.id.link_to_reg).setOnClickListener{TextViewClick(view)} view.findViewById<TextView>(R.id.link_to_reg).setOnClickListener{TextViewClick(view)}
@ -42,31 +61,34 @@ class Auth : Fragment() {
private fun buttonClick(view: View) { private fun buttonClick(view: View) {
val login = view.findViewById<TextView>(R.id.auth_user_login)?.text.toString().trim() val login = view.findViewById<TextView>(R.id.auth_user_login)?.text.toString().trim()
val pass = view.findViewById<TextView>(R.id.auth_user_pass)?.text.toString().trim() val pass = view.findViewById<TextView>(R.id.auth_user_pass)?.text.toString().trim()
val viewModel: myViewModel by activityViewModels()
if(login.length == 0 || pass.length ==0){ if(login.length == 0 || pass.length ==0){
Toast.makeText(view.context, "Укажите логин или пароль", Toast.LENGTH_SHORT).show() Toast.makeText(view.context, "Укажите логин или пароль", Toast.LENGTH_SHORT).show()
return return
} }
userViewModel!!.getUserByLP(login,pass,
userDao?.getByLoginAndPassword(login, pass)?.subscribeOn(Schedulers.io()) onLoad =
?.observeOn(AndroidSchedulers.mainThread()) {data: User -> viewModel.setId(data.uid!!)
?.doOnError { Toast.makeText(view.context, "Неверный логин или пароль", Toast.LENGTH_SHORT).show() } if (data.role == "admin")
?.doOnSuccess { Toast.makeText(view.context, "Добро пожаловать", Toast.LENGTH_SHORT).show() }
?.onErrorComplete()
?.subscribe{user ->
viewModel.setId(user.uid!!)
if(user.role.equals("admin"))
viewModel.setRole(true) viewModel.setRole(true)
Toast.makeText(view.context, "Добро пожаловать", Toast.LENGTH_SHORT).show()
val action = AuthDirections val action = AuthDirections
.actionNavigationAuthToNavigationPizzaList() .actionNavigationAuthToNavigationPizzaList()
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
} },
onError = { Toast.makeText(view.context, "Неверно указаны дынные", Toast.LENGTH_SHORT).show() }
)
}
override fun onStart() {
super.onStart()
} }
private fun TextViewClick(view: View) { private fun TextViewClick(view: View) {
val action = AuthDirections val action = AuthDirections
.actionNavigationAuthToNavigationReg() .actionNavigationAuthToNavigationReg(-1)
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
} }
} }

View File

@ -15,7 +15,9 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
@ -23,6 +25,9 @@ import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.PizzaAdapter import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
@ -30,12 +35,29 @@ import io.reactivex.rxjava3.schedulers.Schedulers
class ListPizza : Fragment() { class ListPizza : Fragment() {
private var pizzaDao: PizzaDao? = null private var pizzaDao: PizzaDao? = null
private var userDao: UserDao? = null private var userDao: UserDao? = null
private var currentUser: User? = null private var pizzaViewModel: PizzaListViewModel? = null
private var pizzaAdapter: PizzaAdapter? = null
private var basketViewModel : BasketEditViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val viewModel: PizzaListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
pizzaViewModel = viewModel
val viewModel2: BasketEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
basketViewModel = viewModel2
}
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<Pizza>>? = pizzaViewModel?.getPizzas()
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
pizzaAdapter?.submitData(lifecycle, it)
}
}
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
override fun onCreateView( override fun onCreateView(
@ -50,18 +72,25 @@ class ListPizza : Fragment() {
val view = inflater.inflate(R.layout.fragment_list_pizza, container, false) val view = inflater.inflate(R.layout.fragment_list_pizza, container, false)
val itemsList : RecyclerView = view.findViewById(R.id.pizzasList) val itemsList : RecyclerView = view.findViewById(R.id.pizzasList)
if(!viewModel.getRole()) if(!viewModel.getRole()) {
view.findViewById<Button>(R.id.button_add).visibility = View.GONE view.findViewById<Button>(R.id.button_add).visibility = View.GONE
var items = pizzaDao?.getAll() pizzaAdapter = PizzaAdapter(view.context, viewModel.getId()!!, basketViewModel!!,
if (items != null) { onSave = {Toast.makeText(view.context, "Пицца добавлена в корзину ", Toast.LENGTH_SHORT).show()},
items.subscribeOn(Schedulers.io()) onClick = {})
.observeOn(AndroidSchedulers.mainThread())
.subscribe { pizzas ->
itemsList.adapter = PizzaAdapter(pizzas,view.context, viewModel.getId()!!) }
} }
else{
pizzaAdapter = PizzaAdapter(view.context, viewModel.getId()!!, basketViewModel!!,
onSave = {Toast.makeText(view.context, "Пицца добавлена в корзину ", Toast.LENGTH_SHORT).show()},
onClick = {data : Int -> val action = ListPizzaDirections
.actionNavigationListToNavigationCreatePizza(data)
Navigation.findNavController(view).navigate(action)})
}
itemsList.adapter = pizzaAdapter
view.findViewById<Button>(R.id.button_add).setOnClickListener{ view.findViewById<Button>(R.id.button_add).setOnClickListener{
val action = ListPizzaDirections val action = ListPizzaDirections
.actionNavigationListToNavigationCreatePizza() .actionNavigationListToNavigationCreatePizza(-1)
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
} }
itemsList.layoutManager = LinearLayoutManager(view.context) itemsList.layoutManager = LinearLayoutManager(view.context)

View File

@ -1,17 +1,21 @@
package com.example.pizza.Model.Basket package com.example.pizza.Model.Basket
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete 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
import com.example.pizza.Model.Pizza.Pizza
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
@Dao @Dao
interface BasketDao { interface BasketDao {
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid") @Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>> fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket>
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
@Insert @Insert
fun insert(group: Basket): Completable fun insert(group: Basket): Completable

View File

@ -5,32 +5,50 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.R import com.example.pizza.R
import java.text.SimpleDateFormat
import java.util.Objects
class HistoryAdapter(var orders: List<PizzaOrder>, var context: Context) : RecyclerView.Adapter<HistoryAdapter.MyViewHolder>() { class HistoryAdapter(var context: Context,
diffUtil: DiffUtil.ItemCallback<PizzaOrder> = HistoryAdapter.OrderComparator()
) : PagingDataAdapter<PizzaOrder, HistoryAdapter.MyViewHolder>(diffUtil) {
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){ class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){
val date: TextView = view.findViewById(R.id.date_order) val date: TextView = view.findViewById(R.id.date_order)
val pizzas: TextView = view.findViewById(R.id.pizza_order) val pizzas: TextView = view.findViewById(R.id.pizza_order)
val price: TextView = view.findViewById(R.id.price_order) val price: TextView = view.findViewById(R.id.price_order)
} }
class OrderComparator : DiffUtil.ItemCallback<PizzaOrder>() {
override fun areItemsTheSame(oldItem: PizzaOrder, newItem: PizzaOrder): Boolean {
return Objects.equals(oldItem.date.toString()+ oldItem.pizzas, newItem.date.toString() + newItem.pizzas)
}
override fun areContentsTheSame(oldItem: PizzaOrder, newItem: PizzaOrder): Boolean {
return Objects.equals(oldItem.date.toString() + oldItem.pizzas, newItem.date.toString() + newItem.pizzas)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.history_list,parent,false) val view = LayoutInflater.from(parent.context).inflate(R.layout.history_list,parent,false)
return MyViewHolder(view) return MyViewHolder(view)
} }
override fun getItemCount(): Int {
return orders.count()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.date.text = orders[position].date val pizza = getItem(position)
holder.pizzas.text = orders[position].pizzas pizza?.let{
holder.price.text = orders[position].price.toString() val sdf = SimpleDateFormat("dd.M.yyyy")
holder.date.text = sdf.format(it.date)
holder.pizzas.text = it.pizzas
holder.price.text = it.price.toString()
}
} }
} }

View File

@ -0,0 +1,18 @@
package com.example.pizza.Model.Order
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.room.TypeConverter
import java.io.ByteArrayOutputStream
import java.util.Date
class DateConverter {
@TypeConverter
fun getLongFromDate(time: Date): Long {
return time.time
}
@TypeConverter
fun getDateFromLong(data: Long): Date {
return Date(data)
}
}

View File

@ -5,6 +5,8 @@ import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.example.pizza.Model.Pizza.ImageConverter
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User import com.example.pizza.Model.User.User
import java.util.Date import java.util.Date
@ -24,11 +26,12 @@ import java.util.Date
onDelete = ForeignKey.RESTRICT, onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT), onUpdate = ForeignKey.RESTRICT),
]) ])
@TypeConverters(DateConverter::class)
class Order( class Order(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
val uid : Int?, val uid : Int?,
@ColumnInfo(name = "date") @ColumnInfo(name = "date")
val date: String, val date: Date,
@ColumnInfo(name = "pizza_id", index = true) @ColumnInfo(name = "pizza_id", index = true)
val pizza: Int? , val pizza: Int? ,
@ColumnInfo(name = "user_id", index = true) @ColumnInfo(name = "user_id", index = true)
@ -40,7 +43,7 @@ class Order(
Pizza : Pizza, Pizza : Pizza,
User : User, User : User,
Price : Int Price : Int
) : this(null , Date.toString(), Pizza.uid, User.uid, Price) ) : this(null , Date, Pizza.uid, User.uid, Price)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false

View File

@ -1,5 +1,6 @@
package com.example.pizza.Model.Order package com.example.pizza.Model.Order
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
@ -12,19 +13,13 @@ import io.reactivex.rxjava3.core.Flowable
@Dao @Dao
interface OrderDao { interface OrderDao {
@Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" + @Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" +
" join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date ") " join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date order by orders.date desc")
fun getUserHistory(uid: Int): Flowable<List<PizzaOrder>> fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder>
@Query("select * from orders")
fun getAll(): Flowable<List<Order>>
@Insert @Insert
fun insert(group: Order): Completable fun insert(group: Order): Completable
@Insert @Insert
fun insertMany(group: List<Order>): Completable fun insertMany(group: List<Order>): Completable
@Update
fun update(group: Order): Completable
@Delete
fun delete(group: Order): Completable
} }

View File

@ -1,4 +1,6 @@
package com.example.pizza.Model.Order package com.example.pizza.Model.Order
class PizzaOrder(val date: String, val pizzas : String, val price : Int) { import java.util.Date
class PizzaOrder(val date: Date, val pizzas : String, val price : Int) {
} }

View File

@ -7,20 +7,18 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.TextView import android.widget.TextView
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Basket.PizzaBasket import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.R import com.example.pizza.R
import com.example.pizza.database.AppDatabase import com.example.pizza.ViewModels.BasketListViewModel
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import java.util.Objects
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.combineTransform class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : BasketListViewModel,
import java.util.function.ToIntFunction diffUtil: DiffUtil.ItemCallback<PizzaBasket> = OrderAdapter.PizzaComparator()
) : PagingDataAdapter<PizzaBasket, OrderAdapter.MyViewHolder>(diffUtil) {
class OrderAdapter(var orders: List<PizzaBasket>, var context: Context, val resSum: TextView ) : RecyclerView.Adapter<OrderAdapter.MyViewHolder>() {
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.findViewById(R.id.order_title) val title: TextView = view.findViewById(R.id.order_title)
val btnP: TextView = view.findViewById(R.id.plus) val btnP: TextView = view.findViewById(R.id.plus)
@ -29,51 +27,73 @@ class OrderAdapter(var orders: List<PizzaBasket>, var context: Context, val resS
val sum: TextView = view.findViewById(R.id.order_sum) val sum: TextView = view.findViewById(R.id.order_sum)
val btnTrash : Button = view.findViewById(R.id.button_trash) val btnTrash : Button = view.findViewById(R.id.button_trash)
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.table_order, parent, false) val view = LayoutInflater.from(parent.context).inflate(R.layout.table_order, parent, false)
return MyViewHolder(view) return MyViewHolder(view)
} }
class PizzaComparator : DiffUtil.ItemCallback<PizzaBasket>() {
override fun getItemCount(): Int { override fun areItemsTheSame(oldItem: PizzaBasket, newItem: PizzaBasket): Boolean {
return orders.count() return Objects.equals(oldItem.pizza_id, newItem.pizza_id)
} }
override fun areContentsTheSame(oldItem: PizzaBasket, newItem: PizzaBasket): Boolean {
return Objects.equals(oldItem.pizza_id, newItem.pizza_id)
}
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val pizza = getItem(position)
pizza?.let{
holder.btnM.setOnClickListener{btnMinus(holder,position)} holder.btnM.setOnClickListener{btnMinus(holder,position)}
holder.btnP.setOnClickListener{btnPlus(holder,position)} holder.btnP.setOnClickListener{btnPlus(holder,position)}
holder.title.text = orders[position].pizza_title holder.title.text = it.pizza_title
holder.count.text = orders[position].count_pizza.toString() holder.count.text = it.count_pizza.toString()
holder.sum.text = orders[position].pizza_price.toString() holder.sum.text = it.pizza_price.toString()
resSum.text = (resSum.text.toString().toInt() + orders[position].pizza_price).toString() resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString()
holder.btnTrash.setOnClickListener{deleteFromBasket(holder,position)} holder.btnTrash.setOnClickListener{deleteFromBasket(holder,position)}
}
} }
public fun getItemFromPosition(position: Int): PizzaBasket? {
return getItem(position)
}
fun btnPlus(holder:MyViewHolder,position: Int){ fun btnPlus(holder:MyViewHolder,position: Int){
val pizza = getItem(position)
pizza?.let {
var count = holder.count.text.toString().toInt() var count = holder.count.text.toString().toInt()
count++ count++
holder.count.text = count.toString() holder.count.text = count.toString()
holder.sum.text = (count * orders[position].pizza_price).toString() holder.sum.text = (count * it.pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() + orders[position].pizza_price).toString() resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString() }
} }
fun btnMinus(holder:MyViewHolder,position: Int){ fun btnMinus(holder:MyViewHolder,position: Int){
val pizza = getItem(position)
pizza?.let {
var count = holder.count.text.toString().toInt() var count = holder.count.text.toString().toInt()
if(count == 0) if(count == 0)
return return
count-- count--
holder.count.text = count.toString() holder.count.text = count.toString()
holder.sum.text = (count * orders[position].pizza_price).toString() holder.sum.text = (count * it.pizza_price).toString()
resSum.text = (resSum.text.toString().toInt() - orders[position].pizza_price).toString() resSum.text = (resSum.text.toString().toInt() - it.pizza_price).toString()
}
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, position: Int){ fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, position: Int){
val basketDao : BasketDao? = context?.let { AppDatabase.getInstance(it).basketDao() } val pizza = getItem(position)
basketDao?.deleteByUserAndPizza(orders[position].user_id,orders[position].pizza_id)?.subscribeOn(Schedulers.io()) val price = pizza!!.pizza_price
?.observeOn(AndroidSchedulers.mainThread()) val count = holder.count.text.toString().toInt()
?.doOnComplete({}) val sum = price*count
?.doOnError({}) basketVm.deletePizza(pizza!!.user_id,pizza!!.pizza_id)
?.onErrorComplete() { val oldSum = resSum.text.toString().toInt()
?.subscribe({resSum.text = "0"} ) val newSum = oldSum - sum
resSum.text = newSum.toString()}
} }
} }

View File

@ -12,7 +12,7 @@ class ImageConverter {
@TypeConverter @TypeConverter
fun getByteArrayFromBitmap(bitmap: Bitmap): ByteArray { fun getByteArrayFromBitmap(bitmap: Bitmap): ByteArray {
val outputStream = ByteArrayOutputStream() val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 70, outputStream) bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray() return outputStream.toByteArray()
} }
@TypeConverter @TypeConverter

View File

@ -13,13 +13,13 @@ class Pizza(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
val uid: Int?, val uid: Int?,
@ColumnInfo(name = "pizza_title") @ColumnInfo(name = "pizza_title")
val title:String, var title:String,
val image : Bitmap?, var image : Bitmap?,
@ColumnInfo(name = "pizza_ingredients") @ColumnInfo(name = "pizza_ingredients")
val ingredients: String, var ingredients: String,
@ColumnInfo(name = "pizza_price") @ColumnInfo(name = "pizza_price")
val price: Int var price: Int
){ ){
@Ignore @Ignore
constructor( constructor(

View File

@ -1,5 +1,6 @@
package com.example.pizza.Model.Pizza package com.example.pizza.Model.Pizza
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
@ -14,7 +15,9 @@ import io.reactivex.rxjava3.core.Single
@Dao @Dao
interface PizzaDao { interface PizzaDao {
@Query("select * from pizzas") @Query("select * from pizzas")
fun getAll(): Flowable<List<Pizza>> fun getAll(): RxPagingSource<Int, Pizza>
@Query("select * from pizzas where pizzas.uid = :uid")
fun getById(uid : Int): Single<Pizza>
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(group: Pizza): Completable fun insert(group: Pizza): Completable

View File

@ -10,20 +10,28 @@ import android.widget.Button
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.navigation.Navigation
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.ListPizzaDirections
import com.example.pizza.Model.Basket.Basket import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User import com.example.pizza.Model.User.User
import com.example.pizza.R import com.example.pizza.R
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import java.util.Objects
class PizzaAdapter(var pizzas: List<Pizza>, var context: Context, var user : Int) : RecyclerView.Adapter<PizzaAdapter.MyViewHolder>() { class PizzaAdapter(var context: Context,
val basketDao : BasketDao? = context?.let { AppDatabase.getInstance(it).basketDao() } var user : Int, val basketVm : BasketEditViewModel, var onClick: (id : Int) -> Unit,
diffUtil: DiffUtil.ItemCallback<Pizza> = PizzaComparator(), var onSave: () -> Unit) : PagingDataAdapter<Pizza, PizzaAdapter.MyViewHolder>(diffUtil) {
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){ class MyViewHolder(view: View) : RecyclerView.ViewHolder(view){
val image: ImageView = view.findViewById(R.id.pizza_list_image) val image: ImageView = view.findViewById(R.id.pizza_list_image)
val title: TextView = view.findViewById(R.id.pizza_list_title) val title: TextView = view.findViewById(R.id.pizza_list_title)
@ -32,30 +40,36 @@ class PizzaAdapter(var pizzas: List<Pizza>, var context: Context, var user : Int
val btn : Button = view.findViewById(R.id.item_list_botton) val btn : Button = view.findViewById(R.id.item_list_botton)
} }
class PizzaComparator : DiffUtil.ItemCallback<Pizza>() {
override fun areItemsTheSame(oldItem: Pizza, newItem: Pizza): Boolean {
return Objects.equals(oldItem.uid, newItem.uid)
}
override fun areContentsTheSame(oldItem: Pizza, newItem: Pizza): Boolean {
return Objects.equals(oldItem, newItem)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.pizza_in_list,parent,false) val view = LayoutInflater.from(parent.context).inflate(R.layout.pizza_in_list,parent,false)
return MyViewHolder(view) return MyViewHolder(view)
} }
override fun getItemCount(): Int {
return pizzas.count()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.title.text = pizzas[position].title val pizza = getItem(position)
holder.ingredients.text = pizzas[position].ingredients.toString() pizza?.let { currentPizza ->
holder.price.text = pizzas[position].price.toString() holder.title.text = currentPizza.title
holder.image.setImageBitmap(pizzas[position].image) holder.ingredients.text = currentPizza.ingredients.toString()
holder.price.text = currentPizza.price.toString()
holder.image.setImageBitmap(currentPizza.image)
holder.btn.setOnClickListener { addToBasket(holder, position) } holder.btn.setOnClickListener { addToBasket(holder, position) }
holder.image.setOnClickListener{ onClick(position+1) }
}
} }
fun addToBasket(holder: PizzaAdapter.MyViewHolder, position: Int){ fun addToBasket(holder: PizzaAdapter.MyViewHolder, position: Int){
val pizza : Basket = Basket(user,pizzas[position].uid!!,1) val currentPizza = getItem(position)
basketDao?.insert(pizza)?.subscribeOn(Schedulers.io()) val pizza = Basket(user,currentPizza?.uid!!,1)
?.observeOn(AndroidSchedulers.mainThread()) basketVm.savePizza(pizza){onSave}
?.doOnComplete({})
?.doOnError({})
?.onErrorComplete()
?.subscribe()
} }
} }

View File

@ -0,0 +1,19 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
interface BasketRepository {
fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket>
fun insert(group: Basket): Completable
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
fun update(group: Basket): Completable
fun delete(group: Basket): Completable
fun deleteByUser(uid : Int): Completable
fun deleteByUserAndPizza(uid : Int, pid:Int): Completable
}

View File

@ -0,0 +1,24 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.PizzaDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
class OfflineBasketRepository(private val basketDao : BasketDao) : BasketRepository {
override fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> = basketDao.getUserBasket(uid)
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserAllBasket(uid)
override fun insert(group: Basket): Completable = basketDao.insert(group)
override fun update(group: Basket): Completable = basketDao.update(group)
override fun delete(group: Basket): Completable = basketDao.delete(group)
override fun deleteByUser(uid: Int): Completable = basketDao.deleteByUser(uid)
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable = basketDao.deleteByUserAndPizza(uid,pid)
}

View File

@ -0,0 +1,16 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.Order.PizzaOrder
import io.reactivex.rxjava3.core.Completable
class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> = orderDao.getUserHistory(uid)
override fun insert(group: Order): Completable = orderDao.insert(group)
override fun insertMany(group: List<Order>): Completable = orderDao.insertMany(group)
}

View File

@ -0,0 +1,18 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
class OfflinePizzaRepository(private val pizzaDao : PizzaDao) : PizzaRepository {
override fun getAll(): RxPagingSource<Int, Pizza> = pizzaDao.getAll()
override fun getById(uid: Int): Single<Pizza> = pizzaDao.getById(uid)
override fun insert(group: Pizza): Completable = pizzaDao.insert(group)
override fun update(group: Pizza): Completable = pizzaDao.update(group)
override fun delete(group: Pizza): Completable = pizzaDao.delete(group)
}

View File

@ -0,0 +1,23 @@
package com.example.pizza.Model.Repository
import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
class OfflineUserRepository(private val userDao : UserDao) : UserRepository {
override fun getById(uid: Int): Single<User> = userDao.getById(uid)
override fun getAll(): Flowable<List<User>> = userDao.getAll()
override fun getByLoginAndPassword(login: String, pass: String): Single<User> = userDao.getByLoginAndPassword(login,pass)
override fun insert(group: User): Completable = userDao.insert(group)
override fun update(group: User): Completable = userDao.update(group)
override fun delete(group: User): Completable = userDao.delete(group)
}

View File

@ -0,0 +1,15 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import io.reactivex.rxjava3.core.Completable
interface OrderRepository {
fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder>
fun insert(group: Order): Completable
fun insertMany(group: List<Order>): Completable
}

View File

@ -0,0 +1,14 @@
package com.example.pizza.Model.Repository
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Pizza.Pizza
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
interface PizzaRepository {
fun getAll(): RxPagingSource<Int, Pizza>
fun getById(uid : Int): Single<Pizza>
fun insert(group: Pizza): Completable
fun update(group: Pizza): Completable
fun delete(group: Pizza): Completable
}

View File

@ -0,0 +1,23 @@
package com.example.pizza.Model.Repository
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.pizza.Model.User.User
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
interface UserRepository {
fun getById(uid : Int): Single<User>
fun getAll(): Flowable<List<User>>
fun getByLoginAndPassword(login : String, pass : String): Single<User>
fun insert(group: User): Completable
fun update(group: User): Completable
fun delete(group: User): Completable
}

View File

@ -12,11 +12,11 @@ data class User(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
public val uid: Int?, public val uid: Int?,
@ColumnInfo(name = "login") @ColumnInfo(name = "login")
val login:String , var login:String ,
@ColumnInfo(name = "email") @ColumnInfo(name = "email")
val email : String , var email : String ,
@ColumnInfo(name = "password") @ColumnInfo(name = "password")
val password: String , var password: String ,
@ColumnInfo(name = "role") @ColumnInfo(name = "role")
val role : String ) { val role : String ) {
@Ignore @Ignore

View File

@ -7,6 +7,7 @@ import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
@Dao @Dao

View File

@ -0,0 +1,21 @@
package com.example.pizza
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.example.pizza.database.AppContainer
import com.example.pizza.database.AppDataContainer
class PizzaApplication : Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}
operator fun <T> MutableLiveData<ArrayList<T>>.plusAssign(values: List<T>) {
val value = this.value ?: arrayListOf()
value.addAll(values)
this.value = value
}

View File

@ -12,10 +12,13 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.constraintlayout.widget.StateSet.TAG import androidx.constraintlayout.widget.StateSet.TAG
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.example.pizza.Model.PizzaAdapter import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
@ -23,14 +26,39 @@ import io.reactivex.rxjava3.schedulers.Schedulers
class Reg : Fragment() { class Reg : Fragment() {
private var userDao: UserDao? = null private var userViewModel : UserViewModel? = null
private var editing = false
private var editUser : User? = null
val viewModel: myViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewUserModel : UserViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory}
)
userViewModel = viewUserModel
}
override fun onStart() {
super.onStart()
}
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
val view = inflater.inflate(R.layout.fragment_reg, container, false) val view = inflater.inflate(R.layout.fragment_reg, container, false)
val args = RegArgs.fromBundle(requireArguments())
if(args.id != -1) {
editing = true
userViewModel?.getUserById(viewModel.getId()!!,{data: User ->
editUser = data
view.findViewById<TextView>(R.id.reg_user_login).text = editUser?.login
view.findViewById<TextView>(R.id.reg_user_email).text = editUser?.email
view.findViewById<TextView>(R.id.reg_user_pass).text = editUser?.password
},{})
}
view.findViewById<Button>(R.id.button_reg).setOnClickListener {buttonClick(view)} view.findViewById<Button>(R.id.button_reg).setOnClickListener {buttonClick(view)}
view.findViewById<TextView>(R.id.link_to_auth).setOnClickListener{TextViewClick(view)} view.findViewById<TextView>(R.id.link_to_auth).setOnClickListener{TextViewClick(view)}
@ -43,34 +71,59 @@ class Reg : Fragment() {
val login = view.findViewById<TextView>(R.id.reg_user_login)?.text.toString().trim() val login = view.findViewById<TextView>(R.id.reg_user_login)?.text.toString().trim()
val email = view.findViewById<TextView>(R.id.reg_user_email)?.text.toString().trim() val email = view.findViewById<TextView>(R.id.reg_user_email)?.text.toString().trim()
val pass = view.findViewById<TextView>(R.id.reg_user_pass)?.text.toString().trim() val pass = view.findViewById<TextView>(R.id.reg_user_pass)?.text.toString().trim()
val viewModel: myViewModel by activityViewModels()
if(login.length == 0 || pass.length ==0 || email.length == 0){ if(login.length == 0 || pass.length ==0 || email.length == 0){
Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show() Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show()
return return
} }
if(!editing) {
val user1 = User(login, email,pass, "user") val user1 = User(login, email, pass, "user")
userDao?.insert(user1)?.subscribeOn(Schedulers.io()) userViewModel?.saveUser(user1,
?.observeOn(AndroidSchedulers.mainThread()) onSave = {
userViewModel?.getUserByLP(login, pass,
?.subscribe( onLoad = { user: User ->
{Toast.makeText(view.context, "Регистрация прошла успешно", Toast.LENGTH_SHORT).show()
userDao?.getByLoginAndPassword(login, pass)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnSuccess({})
?.onErrorComplete()
?.subscribe { user ->
viewModel.setId(user.uid!!) viewModel.setId(user.uid!!)
if (user.role.equals("admin")) if (user.role == ("admin"))
viewModel.setRole(true) viewModel.setRole(true)
Toast.makeText(
view.context,
"Регистрация прошла успешно",
Toast.LENGTH_SHORT
).show()
val action = RegDirections val action = RegDirections
.actionNavigationRegToNavigationPizzaList() .actionNavigationRegToNavigationPizzaList()
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
}}, },
{Toast.makeText(view.context, "Данный логин уже занят", Toast.LENGTH_SHORT).show()} onError = {
) Toast.makeText(
view.context,
"Сбой Системы!!!",
Toast.LENGTH_SHORT
).show()
})
},
onError = {
Toast.makeText(view.context, "Данный логин уже занят -_-", Toast.LENGTH_SHORT)
.show()
})
}else
{
editUser?.login = login
editUser?.password = pass
editUser?.email = email
userViewModel?.updateUser(editUser!!,
onSave = {Toast.makeText(
view.context,
"Изменения успешно приняты",
Toast.LENGTH_SHORT
).show()
val action = RegDirections
.actionNavigationRegToNavigationUser()
Navigation.findNavController(view).navigate(action)},
onError = {Toast.makeText(view.context, "Данный логин уже занят -_-", Toast.LENGTH_SHORT)
.show()})
}
} }
private fun TextViewClick(view: View) { private fun TextViewClick(view: View) {

View File

@ -0,0 +1,36 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.example.pizza.PizzaApplication
object AppViewModelProvider {
val Factory = viewModelFactory {
initializer {
PizzaListViewModel(studentApplication().container.pizzaRepository)
}
initializer {
PizzaEditViewModel(studentApplication().container.pizzaRepository)
}
initializer {
UserViewModel(studentApplication().container.userRepository)
}
initializer {
BasketEditViewModel(studentApplication().container.basketRepository)
}
initializer {
BasketListViewModel(studentApplication().container.basketRepository)
}
initializer {
OrderEditViewModel(studentApplication().container.orderRepository)
}
initializer {
OrderListViewModel(studentApplication().container.orderRepository)
}
}
}
fun CreationExtras.studentApplication(): PizzaApplication =
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as PizzaApplication)

View File

@ -0,0 +1,38 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class BasketEditViewModel(
private val basketRepository: BasketRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
fun savePizza(pizza: Basket, onSave: () -> Unit) {
val completable: Completable = basketRepository.insert(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete({})
.onErrorComplete()
.subscribe(onSave)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,93 @@
package com.example.pizza.ViewModels
import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.RxPagingSource
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class BasketListViewModel(private val basketRepository: BasketRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<PizzaBasket>?> = MutableLiveData()
fun getPizzas(uid: Int ): LiveData<PagingData<PizzaBasket>?> {
if (pizzas.value == null) {
loadPizzas(uid)
}
return pizzas
}
@SuppressLint("CheckResult")
fun getAllBaskets(uid : Int, onLoad: (data : List<PizzaBasket>) -> Unit, onError: () -> Unit){
basketRepository.getUserAllBasket(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe( { data ->
onLoad(data)
},{onError()})
}
private fun createPagingConfig(): PagingConfig {
val pageSize = 5
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
)
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun loadPizzas(uid: Int) {
val disposable = Pager(
config = createPagingConfig(),
pagingSourceFactory = {basketRepository.getUserBasket(uid)}
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null})
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
}
fun deletePizza(uid:Int, pid: Int, onDelete: () -> Unit) {
val disposable = basketRepository.deleteByUserAndPizza(uid,pid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onDelete)
mDisposable.add(disposable)
}
fun deleteAllPizza(uid:Int) {
val disposable = basketRepository.deleteByUser(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,35 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class OrderEditViewModel(
private val orderRepository: OrderRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
fun savePizza(pizzas: List<Order>, onSave: () -> Unit) {
val completable: Completable = orderRepository.insertMany(pizzas)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete({})
.onErrorComplete()
.subscribe(onSave)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,65 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class OrderListViewModel(private val orderRepository: OrderRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<PizzaOrder>?> = MutableLiveData()
fun getPizzas(uid: Int): LiveData<PagingData<PizzaOrder>?> {
if (pizzas.value == null) {
loadPizzas(uid)
}
return pizzas
}
private fun createPagingConfig(): PagingConfig {
val pageSize = 3
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
)
}
private fun loadPizzas(uid: Int) {
val disposable = Pager(
config = createPagingConfig(),
pagingSourceFactory = {orderRepository.getUserHistory(uid)}
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null})
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,63 @@
package com.example.pizza.ViewModels
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class PizzaEditViewModel(
private val pizzaRepository: PizzaRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizza: MutableLiveData<Pizza> = MutableLiveData()
fun getPizza(uid: Int, onSave: (data : Pizza) -> Unit): LiveData<Pizza> {
if (pizza.value == null) {
loadPizza(uid,onSave)
}
return pizza
}
private fun loadPizza(uid: Int,onSave: (data : Pizza) -> Unit) {
val disposable = pizzaRepository.getById(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { data ->
pizza.postValue(data)
onSave(data)
}
mDisposable.add(disposable)
}
fun savePizza(pizza: Pizza, onSave: () -> Unit) {
val completable: Completable = pizzaRepository.insert(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ onSave() })
mDisposable.add(disposable)
}
fun updatePizza(pizza: Pizza, onSave: () -> Unit, onError: () -> Unit) {
val completable: Completable = pizzaRepository.update(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ onSave() },{onError()})
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,70 @@
package com.example.pizza.ViewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.ExperimentalCoroutinesApi
class PizzaListViewModel(private val pizzaRepository: PizzaRepository): ViewModel() {
private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<Pizza>> = MutableLiveData()
fun getPizzas(): LiveData<PagingData<Pizza>> {
if (pizzas.value == null) {
loadPizzas()
}
return pizzas
}
private fun createPagingConfig(): PagingConfig {
val pageSize = 3
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
)
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun loadPizzas() {
val disposable = Pager(
config = createPagingConfig(),
pagingSourceFactory = pizzaRepository::getAll
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
}
fun deletePizza(pizza: Pizza, onDelete: () -> Unit) {
val disposable = pizzaRepository.delete(pizza)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onDelete)
mDisposable.add(disposable)
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -0,0 +1,95 @@
package com.example.pizza.ViewModels
import android.annotation.SuppressLint
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.User.User
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
class UserViewModel(
private val userRepository: UserRepository
) : ViewModel() {
private val mDisposable = CompositeDisposable()
private val user: MutableLiveData<User?> = MutableLiveData()
fun getUserById(uid: Int, onLoad: (data : User)-> Unit, onError: () -> Unit): LiveData<User?> {
if (user.value == null) {
loadUserById(uid,onLoad, onError)
}
return user
}
fun getUserByLP(login : String, pass : String,onLoad: (data : User) -> Unit,onError: () -> Unit): LiveData<User?> {
if (user.value == null) {
loadUserByLP(login, pass,onLoad, onError)
}
return user
}
private fun loadUserById(uid: Int,onLoad: (data : User) -> Unit, onError: () -> Unit) {
val disposable = userRepository.getById(uid)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({ data ->
user.postValue(data)
onLoad(data)
},{onError()})
mDisposable.add(disposable)
}
@SuppressLint("SuspiciousIndentation", "CheckResult")
private fun loadUserByLP(login : String, pass : String,onLoad: (data : User) -> Unit,onError: () -> Unit) {
val disposable = userRepository.getByLoginAndPassword(login, pass)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({ data ->
user.postValue(data)
onLoad(data)
},{onError()})
mDisposable.add(disposable)
}
@SuppressLint("CheckResult")
fun saveUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.insert(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
@SuppressLint("CheckResult")
fun updateUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.update(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
@SuppressLint("CheckResult")
fun deleteUser(user: User, onSave: () -> Unit, onError: () -> Unit) {
userRepository.delete(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe ({onSave() },{ onError()})
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()
}
}

View File

@ -11,7 +11,9 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder import androidx.recyclerview.widget.RecyclerView.ViewHolder
@ -23,6 +25,11 @@ import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.OrderAdapter import com.example.pizza.Model.OrderAdapter
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.PizzaAdapter import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketEditViewModel
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.ViewModels.OrderEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
@ -31,30 +38,48 @@ import java.util.Date
class crate : Fragment() { class crate : Fragment() {
private var basketDao: BasketDao? = null
lateinit var itemsList : RecyclerView lateinit var itemsList : RecyclerView
lateinit var listPizzas : List<PizzaBasket> private var orderAdapter : OrderAdapter? = null
val viewModel: myViewModel by activityViewModels() val viewModel: myViewModel by activityViewModels()
private var orderDao : OrderDao? = null private var orderDao : OrderDao? = null
private var basketVM : BasketListViewModel? = null
private var orderViewModel : OrderEditViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: BasketListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
basketVM = viewModel
val viewModel2: OrderEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
orderViewModel = viewModel2
}
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<PizzaBasket>?>? = basketVM?.getPizzas(viewModel.getId()!!)
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
orderAdapter?.submitData(lifecycle, it)
}
}
}
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
basketDao = context?.let { AppDatabase.getInstance(it).basketDao() }
orderDao = context?.let { AppDatabase.getInstance(it).orderDao() } orderDao = context?.let { AppDatabase.getInstance(it).orderDao() }
val view = inflater.inflate(R.layout.fragment_crate, container, false) val view = inflater.inflate(R.layout.fragment_crate, container, false)
itemsList = view.findViewById(R.id.inOrderList) itemsList = view.findViewById(R.id.inOrderList)
var resSum = view.findViewById<TextView>(R.id.sum_pizzas) var resSum = view.findViewById<TextView>(R.id.sum_pizzas)
val button : Button = view.findViewById<Button>(R.id.button_buy) val button : Button = view.findViewById<Button>(R.id.button_buy)
basketDao?.getUserBasket(viewModel.getId()!!)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe { pizzas ->
listPizzas = pizzas
itemsList.layoutManager = LinearLayoutManager(view.context) itemsList.layoutManager = LinearLayoutManager(view.context)
itemsList.adapter = OrderAdapter(pizzas,view.context, resSum) orderAdapter = OrderAdapter(view.context, resSum, basketVM!!)
} itemsList.adapter = orderAdapter
button.setOnClickListener{buttonClick(view)} button.setOnClickListener{buttonClick(view)}
@ -64,35 +89,30 @@ class crate : Fragment() {
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private fun buttonClick(view : View){ private fun buttonClick(view : View){
var list = arrayListOf<Order>() var list = arrayListOf<Order>()
val sdf = SimpleDateFormat("dd.M.yyyy") val currentDate =Date()
val currentDate = sdf.format(Date())
val x = itemsList.childCount val x = itemsList.childCount
if(x == 0){ if(x == 0){
return return
} }
basketVM?.getAllBaskets(viewModel.getId()!!,
onLoad = {listPizzas: List<PizzaBasket> ->
for(i in 0..<x){ for(i in 0..<x){
var child = itemsList.getChildAt(i) val child = itemsList.getChildAt(i)
var price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt() val price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt()
list.add(Order(null, currentDate, listPizzas[i].pizza_id, list.add(Order(null, currentDate, listPizzas.get(i).pizza_id,
viewModel.getId(), price)) viewModel.getId(), price))
} }
basketDao?.deleteByUser(viewModel.getId()!!)?.subscribeOn(Schedulers.io()) basketVM!!.deleteAllPizza(viewModel.getId()!!)
?.observeOn(AndroidSchedulers.mainThread()) orderViewModel!!.savePizza(list){
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.doOnComplete({})
?.onErrorComplete()
?.subscribe {}
orderDao?.insertMany(list)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.doOnComplete({})
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.onErrorComplete()
?.subscribe {
Toast.makeText(view.context, "Заказ прошел успешно ", Toast.LENGTH_SHORT).show() Toast.makeText(view.context, "Заказ прошел успешно ", Toast.LENGTH_SHORT).show()
val action = crateDirections val action = crateDirections
.actionNavigationCretePizzaToListNavigation() .actionNavigationCretePizzaToListNavigation()
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
} }
},
onError = {})
} }
} }

View File

@ -13,15 +13,21 @@ import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Pizza.PizzaDao import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.PizzaEditViewModel
import com.example.pizza.ViewModels.PizzaListViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
@ -29,12 +35,20 @@ import io.reactivex.rxjava3.schedulers.Schedulers
private lateinit var selectedImage: AppCompatImageView private lateinit var selectedImage: AppCompatImageView
class create_pizza : Fragment() { class create_pizza : Fragment() {
private var pizzaDao: PizzaDao? = null private var pizzaViewModel: PizzaEditViewModel? = null
private var editing = false
private var editPizza : Pizza? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: PizzaEditViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
pizzaViewModel = viewModel
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
pizzaDao = context?.let { AppDatabase.getInstance(it).pizzaDao() }
val view = inflater.inflate(R.layout.fragment_create_pizza, container, false) val view = inflater.inflate(R.layout.fragment_create_pizza, container, false)
val button = view.findViewById<Button>(R.id.button_save) val button = view.findViewById<Button>(R.id.button_save)
button.setOnClickListener {buttonClick(view)} button.setOnClickListener {buttonClick(view)}
@ -43,7 +57,17 @@ class create_pizza : Fragment() {
val pickImg = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI) val pickImg = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
changeImage.launch(pickImg) changeImage.launch(pickImg)
} }
//TODO добавление в бд val args = RegArgs.fromBundle(requireArguments())
if(args.id != -1) {
editing = true
pizzaViewModel?.getPizza(args.id) { data: Pizza ->
editPizza = data
view.findViewById<TextView>(R.id.pizza_title).text = editPizza?.title
view.findViewById<TextView>(R.id.pizza_price).text = editPizza?.price.toString()
view.findViewById<TextView>(R.id.pizza_ingredients).text = editPizza?.ingredients
view.findViewById<ImageView>(R.id.pizza_image).setImageBitmap(editPizza?.image)
}
}
return view return view
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
@ -58,16 +82,28 @@ class create_pizza : Fragment() {
Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show() Toast.makeText(view.context, "Укажите данные", Toast.LENGTH_SHORT).show()
return return
} }
pizzaDao?.insert(pizza1)?.subscribeOn(Schedulers.io()) if(!editing) {
?.observeOn(AndroidSchedulers.mainThread()) pizzaViewModel!!.savePizza(pizza1) {
?.doOnComplete({})
?.doOnError({ Toast.makeText(view.context, "Error", Toast.LENGTH_SHORT).show()})
?.onErrorComplete()
?.subscribe {
Toast.makeText(view.context, "Пицца успешно добавлена", Toast.LENGTH_SHORT).show() Toast.makeText(view.context, "Пицца успешно добавлена", Toast.LENGTH_SHORT).show()
val action = create_pizzaDirections val action = create_pizzaDirections
.actionNavigationCreatePizzaToListNavigation() .actionNavigationCreatePizzaToListNavigation()
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
}
}
else
{
editPizza?.title = title
editPizza?.ingredients = ingredients
editPizza?.price = price
editPizza?.image = bitmap
pizzaViewModel?.updatePizza(editPizza!!,
onSave = {
Toast.makeText(view.context, "Пицца успешно обновлена", Toast.LENGTH_SHORT).show()
val action = create_pizzaDirections
.actionNavigationCreatePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
},
onError = {Toast.makeText(view.context, "Такая пицца уже есть", Toast.LENGTH_SHORT).show()})
} }

View File

@ -0,0 +1,36 @@
package com.example.pizza.database
import android.content.Context
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OfflineBasketRepository
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.UserRepository
interface AppContainer {
val pizzaRepository: PizzaRepository
val userRepository: UserRepository
val basketRepository: BasketRepository
val orderRepository : OrderRepository
}
class AppDataContainer(private val context: Context) : AppContainer {
override val pizzaRepository: PizzaRepository by lazy {
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao())
}
override val userRepository: UserRepository by lazy {
OfflineUserRepository(AppDatabase.getInstance(context).userDao())
}
override val basketRepository: BasketRepository by lazy {
OfflineBasketRepository(AppDatabase.getInstance(context).basketDao())
}
override val orderRepository: OrderRepository by lazy {
OfflineOrderRepository(AppDatabase.getInstance(context).orderDao())
}
}

View File

@ -17,6 +17,7 @@ import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.pizza.Model.Basket.Basket import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.BasketDao import com.example.pizza.Model.Basket.BasketDao
import com.example.pizza.Model.Order.DateConverter
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.OrderDao import com.example.pizza.Model.Order.OrderDao
import com.example.pizza.Model.Pizza.ImageConverter import com.example.pizza.Model.Pizza.ImageConverter
@ -32,7 +33,7 @@ import java.util.concurrent.Executors
@Database(entities = [User::class, Pizza::class,Basket::class,Order::class], version = 1, exportSchema = false) @Database(entities = [User::class, Pizza::class,Basket::class,Order::class], version = 1, exportSchema = false)
@TypeConverters(ImageConverter::class) @TypeConverters(ImageConverter::class, DateConverter::class)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao abstract fun userDao(): UserDao
abstract fun pizzaDao(): PizzaDao abstract fun pizzaDao(): PizzaDao
@ -40,7 +41,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun orderDao(): OrderDao abstract fun orderDao(): OrderDao
companion object { companion object {
private const val DB_NAME: String = "dp7" private const val DB_NAME: String = "dp8"
@Volatile @Volatile
private var INSTANCE: AppDatabase? = null private var INSTANCE: AppDatabase? = null
@ -80,11 +81,11 @@ abstract class AppDatabase : RoomDatabase() {
val orderDao = database.orderDao() val orderDao = database.orderDao()
val sdf = SimpleDateFormat("dd.M.yyyy") val sdf = SimpleDateFormat("dd.M.yyyy")
val currentDate = sdf.format(Date()) val currentDate = Date()
val order1 = Order(1,currentDate.toString(),pizza1.uid,user1.uid,300) val order1 = Order(1,currentDate,pizza1.uid,user1.uid,300)
val order2 = Order(2,currentDate.toString(),pizza2.uid,user1.uid,300) val order2 = Order(2,currentDate,pizza2.uid,user1.uid,300)
val order3 = Order(3,currentDate.toString(),pizza1.uid,user2.uid,300) val order3 = Order(3,currentDate,pizza1.uid,user2.uid,300)
orderDao.insert(order1).subscribe().dispose() orderDao.insert(order1).subscribe().dispose()
orderDao.insert(order2).subscribe().dispose() orderDao.insert(order2).subscribe().dispose()
orderDao.insert(order3).subscribe().dispose() orderDao.insert(order3).subscribe().dispose()

View File

@ -8,10 +8,15 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.paging.PagingData
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.HistoryAdapter import com.example.pizza.Model.HistoryAdapter
import com.example.pizza.Model.Order.OrderDao import com.example.pizza.Model.Order.OrderDao
@ -19,15 +24,44 @@ import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.OrderAdapter import com.example.pizza.Model.OrderAdapter
import com.example.pizza.Model.Pizza.PizzaDao import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.PizzaAdapter import com.example.pizza.Model.PizzaAdapter
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao import com.example.pizza.Model.User.UserDao
import com.example.pizza.ViewModels.AppViewModelProvider
import com.example.pizza.ViewModels.BasketListViewModel
import com.example.pizza.ViewModels.OrderEditViewModel
import com.example.pizza.ViewModels.OrderListViewModel
import com.example.pizza.ViewModels.UserViewModel
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
class user : Fragment() { class user : Fragment() {
private var orderDao: OrderDao? = null private var orderViewModel : OrderListViewModel? = null
private var userDao: UserDao? = null private var userViewModel : UserViewModel? = null
private val viewModel: myViewModel by activityViewModels() private val viewModel: myViewModel by activityViewModels()
private var historyAdapter : HistoryAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: UserViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
userViewModel = viewModel
val viewModel2: OrderListViewModel by viewModels(
factoryProducer = { AppViewModelProvider.Factory }
)
orderViewModel = viewModel2
}
override fun onStart() {
super.onStart()
val pizzas: LiveData<PagingData<PizzaOrder>?>? = orderViewModel?.getPizzas(viewModel.getId()!!)
pizzas?.observe(viewLifecycleOwner) { data ->
data?.let {
historyAdapter?.submitData(lifecycle, it)
}
}
}
@SuppressLint("CheckResult", "SetTextI18n") @SuppressLint("CheckResult", "SetTextI18n")
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@ -35,32 +69,19 @@ class user : Fragment() {
): View? { ): View? {
userDao = context?.let { AppDatabase.getInstance(it).userDao() }
orderDao = context?.let { AppDatabase.getInstance(it).orderDao() }
val view = inflater.inflate(R.layout.fragment_user, container, false) val view = inflater.inflate(R.layout.fragment_user, container, false)
val itemsList : RecyclerView = view.findViewById(R.id.historyList) val itemsList : RecyclerView = view.findViewById(R.id.historyList)
userViewModel?.getUserById(viewModel.getId()!!,
userDao?.getById(viewModel.getId()!!) onLoad = {data: User ->
?.subscribeOn(Schedulers.io()) view.findViewById<TextView>(R.id.user_login).text = "Логин: "+ data?.login
?.observeOn(AndroidSchedulers.mainThread()) view.findViewById<TextView>(R.id.user_email).text = "Почта: " + data?.email },
?.doOnError { } onError = { Toast.makeText(view.context, "Сбой Системы!!!", Toast.LENGTH_SHORT).show()}
?.doOnSuccess { } )
?.onErrorComplete() historyAdapter = HistoryAdapter(view.context)
?.subscribe { user -> itemsList.adapter = historyAdapter
view.findViewById<TextView>(R.id.user_login).text = "Логин: "+ user.login
view.findViewById<TextView>(R.id.user_email).text = "Почта: " + user.email
}
orderDao?.getUserHistory(viewModel.getId()!!)?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe { pizzas ->
itemsList.adapter = HistoryAdapter(pizzas,view.context)
}
itemsList.layoutManager = LinearLayoutManager(view.context) itemsList.layoutManager = LinearLayoutManager(view.context)
view.findViewById<Button>(R.id.button_exit).setOnClickListener {buttonClick(view)} view.findViewById<Button>(R.id.button_exit).setOnClickListener {buttonClick(view)}
view.findViewById<Button>(R.id.button_edit).setOnClickListener {buttonEdit(view)}
return view return view
@ -73,5 +94,13 @@ class user : Fragment() {
.actionNavigationUserToNavigationAuth() .actionNavigationUserToNavigationAuth()
Navigation.findNavController(view).navigate(action) Navigation.findNavController(view).navigate(action)
} }
@SuppressLint("ResourceType")
private fun buttonEdit(view: View) {
val action = userDirections
.actionNavigationUserToNavigationReg(viewModel.getId()!!)
Navigation.findNavController(view).navigate(action)
}
} }

View File

@ -36,6 +36,9 @@
android:layout_gravity="left" android:layout_gravity="left"
android:text="Почта: " android:text="Почта: "
/> />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button <Button
android:id="@+id/button_exit" android:id="@+id/button_exit"
android:layout_width="150dp" android:layout_width="150dp"
@ -43,9 +46,22 @@
android:layout_marginRight="15dp" android:layout_marginRight="15dp"
android:fontFamily="@font/inter_bold" android:fontFamily="@font/inter_bold"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right" android:layout_gravity="center"
android:backgroundTint="#BD350A" android:backgroundTint="#BD350A"
android:text="Выход" /> android:text="Выход" />
<Button
android:id="@+id/button_edit"
android:layout_width="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:fontFamily="@font/inter_bold"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:backgroundTint="#BD350A"
android:text="Редактировать" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/historyList" android:id="@+id/historyList"

View File

@ -19,6 +19,7 @@
app:destination="@id/navigation_reg" app:destination="@id/navigation_reg"
app:popUpTo="@id/nav_graph" app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" /> app:popUpToInclusive="true" />
</fragment> </fragment>
<fragment <fragment
@ -36,6 +37,14 @@
app:destination="@id/navigation_auth" app:destination="@id/navigation_auth"
app:popUpTo="@id/nav_graph" app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" /> app:popUpToInclusive="true" />
<action
android:id="@+id/action_navigation_reg_to_navigation_user"
app:destination="@id/navigation_user"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<argument
android:name="id"
app:argType="integer" />
</fragment> </fragment>
<fragment <fragment
@ -70,6 +79,9 @@
app:destination="@id/navigation_pizza_list" app:destination="@id/navigation_pizza_list"
app:popUpTo="@id/nav_graph" app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" /> app:popUpToInclusive="true" />
<argument
android:name="id"
app:argType="integer" />
</fragment> </fragment>
<fragment <fragment
@ -82,6 +94,11 @@
app:destination="@id/navigation_auth" app:destination="@id/navigation_auth"
app:popUpTo="@id/nav_graph" app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" /> app:popUpToInclusive="true" />
<action
android:id="@+id/action_navigation_user_to_navigation_reg"
app:destination="@id/navigation_reg"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
</fragment> </fragment>
</navigation> </navigation>