Complete curse work

This commit is contained in:
andrew 2023-12-29 16:50:45 +04:00
parent 702cf2d259
commit 2b390ed578
18 changed files with 220 additions and 138 deletions

View File

@ -75,6 +75,14 @@ interface DealRequests {
@Query("sellerId")sellerId: Int,
@Query("buyerId") buyerId: Int,
): Boolean
@GET("deals")
suspend fun report(
@Query("date_gte") startDate: Long,
@Query("date_lte") endDate: Long,
@Query("buyerId_or") buyerId: Int,
@Query("sellerId_or") sellerId: Int
) : List<DealRemote>
}
interface CoinRequests {
@ -110,7 +118,8 @@ interface WalletItemRequests {
interface CryptoDealService : UserRequests, DealRequests, CoinRequests, WalletItemRequests {
companion object {
private const val BASE_URL = "http://172.20.10.13:8079/"
private const val IP = "10.3.3.78"
private const val BASE_URL = "http://${IP}:8079/"
@Volatile
private var INSTANCE: CryptoDealService? = null

View File

@ -73,6 +73,10 @@ class DealRestRepository(
TODO("Not yet implemented")
}
override suspend fun getReportData(startData: Long, endDate: Long, id: Int): List<Deal> {
return service.report(startData, endDate, id, id).map { x -> x.toDeal() }.toList()
}
override suspend fun insert(vararg x: Deal) {
x.forEach {y -> service.insert(y.toRemote()) }
}

View File

@ -28,4 +28,9 @@ interface DealDao : IDao<Deal> {
@Query("DELETE FROM deal")
suspend fun deleteAll()
@Query("SELECT * FROM deal " +
"WHERE (sellerId = :idUser OR buyerId = :idUser) " +
"AND date IS NOT NULL AND date >= :startDate AND date <= :endDate")
fun getReport(startDate: Long, endDate: Long, idUser: Int): List<Deal>
}

View File

@ -27,67 +27,10 @@ abstract class CryptoDealDb: RoomDatabase() {
abstract fun remoteKeysDao(): RemoteKeysDao;
companion object {
private const val DB_NAME: String = "crypto-deal13"
private const val DB_NAME: String = "crypto-deal16"
@Volatile
private var INSTANCE: CryptoDealDb? = null
private suspend fun populateDatabase() {
INSTANCE?.let { database ->
val userDao = database.userDao();
val user1 = User(0, "u11@gmail.com","12345")
val user2 = User(1, "u22@gmail.com","12345")
val user3 = User(2, "u33@gmail.com","12345")
userDao.insert(user1)
userDao.insert(user2)
userDao.insert(user3)
val coinDao = database.coinDao();
val c1 = Coin(0, "BidCoin");
val c2 = Coin(1, "Edhereum");
val c3 = Coin(2, "CatCoin");
val c4 = Coin(3, "BuzCoin");
val c5 = Coin(4, "LunaCoin");
val c6 = Coin(5, "HopeCoin");
val c7 = Coin(6, "DyrovCoin")
coinDao.insert(c1);
coinDao.insert(c2)
coinDao.insert(c3)
coinDao.insert(c4)
coinDao.insert(c5)
coinDao.insert(c6)
coinDao.insert(c7)
// val walletItemDao = database.walletItemDao();
// val wi1 = WalletItem(0, 0, 0.5f);
// val wi2 = WalletItem(1, 0, 0.6f);
// val wi3 = WalletItem(3, 0, 0.7f);
// val wi4 = WalletItem(0, 1, 1000f);
// val wi5 = WalletItem(3, 1, 10f);
// val wi6 = WalletItem(2, 1, 1f);
// val wi7 = WalletItem(4, 0, 1.1f);
// val wi8 = WalletItem(5, 0, 1.1f);
// val wi9 = WalletItem(6, 0, 1.1f);
// walletItemDao.insert(wi1);
// walletItemDao.insert(wi2);
// walletItemDao.insert(wi3);
// walletItemDao.insert(wi4);
// walletItemDao.insert(wi5);
// walletItemDao.insert(wi6);
// walletItemDao.insert(wi7);
// walletItemDao.insert(wi8);
// walletItemDao.insert(wi9);
val dealDao = database.dealDao();
val d1 = Deal(0, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST1")
val d2 = Deal(1, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST2")
val d3 = Deal(2, null, 0, 2, 0, 0.1f, 0.2f, "Buy", null, "TEST3")
val d4 = Deal(3, null, 0, 0, 2, 0.1f, 0.2f, "Buy", null, "TEST4")
dealDao.insert(d1);
dealDao.insert(d2);
dealDao.insert(d3);
dealDao.insert(d4);
}
}
fun getInstance(appContext: Context): CryptoDealDb {
return INSTANCE ?: synchronized(this) {
@ -96,14 +39,6 @@ abstract class CryptoDealDb: RoomDatabase() {
CryptoDealDb::class.java,
DB_NAME
)
// .addCallback(object : Callback() {
// override fun onCreate(db: SupportSQLiteDatabase) {
// super.onCreate(db)
// CoroutineScope(Dispatchers.IO).launch {
// populateDatabase()
// }
// }
// })
.allowMainThreadQueries()
.build()
.also { INSTANCE = it }

View File

@ -1,17 +1,9 @@
package com.example.testapp.data.room.models
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(
foreignKeys = [
ForeignKey(entity = User::class, parentColumns = ["id"], childColumns = ["userId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE),
ForeignKey(entity = Coin::class, parentColumns = ["id"], childColumns = ["coinId"], onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)
],
indices = [Index(value = ["coinId", "userId"])]
)
@Entity()
class WalletItem (
@PrimaryKey(autoGenerate = true) val id: Int?,
val coinId: Int,
@ -26,4 +18,6 @@ class WalletItem (
override fun hashCode(): Int {
return id!!
}
fun copy(): WalletItem = WalletItem(id, coinId, userId, count)
}

View File

@ -11,4 +11,5 @@ interface DealRepository : IRepository<Deal> {
suspend fun clearData()
fun pagingData(): Flow<PagingData<Deal>>
fun getAllPagingData(): PagingSource<Int, Deal>
suspend fun getReportData(startData: Long, endDate: Long, id: Int): List<Deal>
}

View File

@ -28,6 +28,8 @@ class OfflineDealRepository(
), pagingSourceFactory = { DealPagination(dealDao) }, initialKey = 1).flow
override fun getAllPagingData() = dealDao.getDeals()
override suspend fun getReportData(startData: Long, endDate: Long, id: Int): List<Deal> =
dealDao.getReport(startData, endDate, id)
suspend fun insert(list: List<Deal>) = dealDao.insert(*list.toTypedArray())
}

View File

@ -261,16 +261,16 @@ fun Property1Clear(modifier: Modifier = Modifier, navController: NavController)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Log Out",
color = Color(0xffee3f58),
lineHeight = 1.25.em,
style = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Medium,
letterSpacing = 0.1.sp
)
)
// Text(
// text = "Log Out",
// color = Color(0xffee3f58),
// lineHeight = 1.25.em,
// style = TextStyle(
// fontSize = 16.sp,
// fontWeight = FontWeight.Medium,
// letterSpacing = 0.1.sp
// )
// )
}
}
}

View File

@ -44,6 +44,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.example.testapp.data.room.models.Coin
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.navigate.BottomBarScreen
import com.example.testapp.viewModels.AppViewModelProvider
import com.example.testapp.viewModels.CurrentUserViewModel
@ -72,6 +73,9 @@ fun ReportScreen(
val user by currentUserViewModel.user.collectAsState()
val deals by reportViewModel.deals.collectAsState()
val coins by reportViewModel.coins.collectAsState()
val wallet by reportViewModel.wallet.collectAsState()
var walletCopy = wallet.map { it.copy() }
val dateStateFrom = rememberDatePickerState()
val showDialogFrom = rememberSaveable { mutableStateOf(false) }
@ -206,6 +210,7 @@ fun ReportScreen(
longToDate(dateStateFrom.selectedDateMillis!!),
longToDate(dateStateTo.selectedDateMillis!!)
)
walletCopy = wallet.map { it.copy() }
}
},
shape = RoundedCornerShape(10.dp),
@ -218,7 +223,7 @@ fun ReportScreen(
}
if (deals.isNotEmpty()) {
items(items = deals) {
ReportItem(deal = it, coins = coins)
ReportItemMod(deal = it, coins = coins, wallet=walletCopy)
}
}
else {
@ -229,9 +234,17 @@ fun ReportScreen(
}
}
fun subtractWallet(wallet: List<WalletItem>, coinId: Int, count: Float): Float {
val item = wallet.first{ x -> x.coinId == coinId }
item.count += count
return item.count
}
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>, wallet: List<WalletItem>) {
val coinsById = coins.associateBy { x -> x.id }.toMap()
Column(
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically),
horizontalAlignment = Alignment.CenterHorizontally,
@ -252,9 +265,20 @@ fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
.fillMaxWidth()
.padding(all = 2.dp)
) {
Text(
text = "#${deal.id}",
color = Color(0xfff96161),
lineHeight = 1.25.em,
style = TextStyle(
fontSize = 16.sp,
letterSpacing = 0.1.sp
),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically)
)
Text(
text = "-${deal.countSell} ${
coins.first { x -> x.id == deal.sellerCoinId }.shortName()
coinsById[deal.sellerCoinId]?.shortName()
}",
color = Color(0xfff96161),
lineHeight = 1.25.em,
@ -265,20 +289,9 @@ fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically)
)
Text(
text = "->",
color = Color(0xFF009688),
lineHeight = 1.25.em,
style = TextStyle(
fontSize = 16.sp,
letterSpacing = 0.1.sp
),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically)
)
Text(
text = "+${deal.countBuy} ${
coins.first { x -> x.id == deal.buyerCoinId }.shortName()
coinsById[deal.buyerCoinId]?.shortName()
}",
color = Color(0xff5acb48),
lineHeight = 1.25.em,
@ -292,3 +305,136 @@ fun ReportItem(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>) {
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun ReportItemMod(modifier: Modifier = Modifier, deal: Deal, coins: List<Coin>, wallet: List<WalletItem>) {
val coinsById = coins.associateBy { x -> x.id }.toMap()
val date = LocalDateTime
.ofInstant(deal.date?.let { Instant.ofEpochMilli(it) }, ZoneOffset.UTC).toLocalDate().toString()
val afterSell = subtractWallet(wallet, deal.buyerCoinId, 0f)
val beforeSell = subtractWallet(wallet, deal.sellerCoinId, -deal.countSell)
val beforeBuy = subtractWallet(wallet, deal.buyerCoinId, deal.countBuy)
val afterBuy = subtractWallet(wallet, deal.sellerCoinId, deal.countSell)
Column(
verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.Top),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.fillMaxWidth()
.clip(shape = RoundedCornerShape(10.dp))
.background(color = Color(0xffeeeeee))
.padding(
end = 10.dp,
bottom = 10.dp)
) {
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clip(shape = RoundedCornerShape(10.dp))
.background(color = Color.White)
.padding(horizontal = 22.dp)
) {
Text(
text = "Deal #${deal.id}",
color = Color.Black,
lineHeight = 1.em,
style = TextStyle(
fontSize = 18.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.weight(weight = 0.5f)
.fillMaxWidth()
.wrapContentHeight(align = Alignment.CenterVertically))
Text(
text = "Date: $date",
color = Color.Black,
textAlign = TextAlign.End,
lineHeight = 1.em,
style = TextStyle(
fontSize = 18.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.weight(weight = 0.5f)
.wrapContentHeight(align = Alignment.CenterVertically))
}
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
.background(color = Color.White)
.padding(vertical = 10.dp)
) {
Text(
text = "Before:",
color = Color.Black,
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
Text(
text = "${coinsById[deal.sellerCoinId]?.shortName()} $beforeSell",
color = Color(0xfffe4545),
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
Text(
text = "${coinsById[deal.buyerCoinId]?.shortName()} $beforeBuy",
color = Color(0xff5acb48),
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
}
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
.background(color = Color.White)
.padding(vertical = 10.dp)
) {
Text(
text = "After:",
color = Color.Black,
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
Text(
text = "${coinsById[deal.sellerCoinId]?.shortName()} $afterBuy",
color = Color(0xff5acb48),
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
Text(
text = "${coinsById[deal.buyerCoinId]?.shortName()} $afterSell",
color = Color(0xfffe4545),
lineHeight = 1.em,
style = TextStyle(
fontSize = 13.sp,
letterSpacing = 0.1.sp),
modifier = Modifier
.wrapContentHeight(align = Alignment.CenterVertically))
}
}
}

View File

@ -79,16 +79,6 @@ fun Wallet(
}
wallet.apply {
when{
// loadState.refresh is LoadState.Loading -> {
// item { CircularProgressIndicator(
// modifier = Modifier.fillParentMaxSize(0.5f),
// color = Color(0xff423a99)) }
// }
// loadState.append is LoadState.Loading -> {
// item { CircularProgressIndicator(
// modifier = Modifier.fillParentMaxSize(0.5f),
// color = Color(0xff423a99)) }
// }
loadState.refresh is LoadState.Error -> {
val err = wallet.loadState.refresh as LoadState.Error
item { Text(err.error.localizedMessage) }

View File

@ -36,9 +36,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.testapp.data.room.models.User
import com.example.testapp.graphs.AuthScreen
import com.example.testapp.graphs.Graph
import com.example.testapp.data.room.models.User
import com.example.testapp.viewModels.CurrentUserViewModel
import com.example.testapp.viewModels.RegistrationScreenViewModel
import kotlinx.coroutines.async

View File

@ -44,12 +44,16 @@ object AppViewModelProvider {
)
}
initializer {
RegistrationScreenViewModel(application().container.userRestRepository)
RegistrationScreenViewModel(
application().container.userRestRepository,
application().container.walletItemRestRepository
)
}
initializer {
ReportViewModel(
application().container.dealRestRepository,
application().container.coinRepository
application().container.coinRepository,
application().container.walletItemRestRepository
)
}
}

View File

@ -20,8 +20,6 @@ class DealCreateViewModel(
private val walletItemRepository: WalletItemRepository
) : ViewModel() {
private val dealId = MutableStateFlow<Int?>(null)
var id = 0
private var _deal = MutableStateFlow<Deal?>(null)
private var _coins = MutableStateFlow<List<Coin>>(emptyList())
private var _wallet = MutableStateFlow<List<WalletItem>>(emptyList())
@ -39,13 +37,4 @@ class DealCreateViewModel(
_wallet.emit(walletItemRepository.getAll())
}
}
fun isEdit(): Boolean {
return deal.value != null;
}
fun setupEdit(deal: Deal) {
dealId.value = deal.id
_deal.value = deal
}
}

View File

@ -44,7 +44,7 @@ class DealListViewModel(
val walletBuyer: List<WalletItem> = walletItemRepository.getUserWallet(buyerId)
val seller: WalletItem? = walletSeller.firstOrNull { x -> x.coinId == deal.sellerCoinId }
val buyer: WalletItem? = walletBuyer.firstOrNull { x -> x.coinId == deal.buyerId }
val buyer: WalletItem? = walletBuyer.firstOrNull { x -> x.coinId == deal.buyerCoinId }
if (seller == null || buyer == null) return@launch
// Check what seller have buyer COIN or we need to insert new value to database:

View File

@ -18,7 +18,7 @@ class HistoryViewModel(
private val dealRepository: DealRepository,
private val coinRepository: CoinRepository
) : ViewModel() {
val argument = MutableStateFlow<String?>(null)
private val argument = MutableStateFlow<String?>(null)
private val id = MutableStateFlow<Int?>(null)
var deals = MutableStateFlow<PagingData<Deal>>(PagingData.empty())
var coins = MutableStateFlow<List<Coin>>(emptyList())

View File

@ -6,9 +6,13 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.testapp.data.room.models.User
import com.example.testapp.data.room.repository.basic.UserRepository
import com.example.testapp.data.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.launch
class RegistrationScreenViewModel(private val userRepository: UserRepository) : ViewModel() {
class RegistrationScreenViewModel(
private val userRepository: UserRepository,
private val walletItemRepository: WalletItemRepository
) : ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> get() = _users

View File

@ -6,8 +6,10 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.testapp.data.room.models.Coin
import com.example.testapp.data.room.models.Deal
import com.example.testapp.data.room.models.WalletItem
import com.example.testapp.data.room.repository.basic.CoinRepository
import com.example.testapp.data.room.repository.basic.DealRepository
import com.example.testapp.data.room.repository.basic.WalletItemRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
@ -17,12 +19,14 @@ import java.time.ZoneOffset
@RequiresApi(Build.VERSION_CODES.O)
class ReportViewModel(
private val dealRepository: DealRepository,
private val coinRepository: CoinRepository
private val coinRepository: CoinRepository,
private val walletItemRepository: WalletItemRepository
) : ViewModel() {
private var startDate = MutableStateFlow<LocalDateTime>(LocalDateTime.now().minusDays(1))
private var endDate = MutableStateFlow<LocalDateTime>(LocalDateTime.now())
var deals = MutableStateFlow<List<Deal>>(emptyList())
var coins = MutableStateFlow<List<Coin>>(emptyList())
var wallet = MutableStateFlow<List<WalletItem>>(emptyList())
fun clearLists() {
deals = MutableStateFlow(emptyList())
@ -36,13 +40,8 @@ class ReportViewModel(
val eptf = from.toEpochSecond(ZoneOffset.UTC) * 1000
val eptt = to.toEpochSecond(ZoneOffset.UTC) * 1000
deals.emit(
dealRepository.getUserDeals(userId).filter {
it.date != null &&
it.date!! >= eptf &&
it.date!! <= eptt
}
)
wallet.emit(walletItemRepository.getUserWallet(userId))
deals.emit(dealRepository.getReportData(eptf, eptt, userId).sortedBy { x -> x.date })
coins.emit(coinRepository.getAll())
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">172.20.10.13</domain>
<domain includeSubdomains="true">10.3.3.78</domain>
</domain-config>
</network-security-config>