Purchase is working!

This commit is contained in:
ElEgEv 2023-12-25 01:04:38 +04:00
parent dd05c256d9
commit 201db3401f
22 changed files with 206 additions and 37 deletions

9
.idea/TanksApp.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/TanksApp.iml" filepath="$PROJECT_DIR$/.idea/TanksApp.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

58
.idea/workspace.xml Normal file
View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="fb78b956-3834-46c2-9adb-5184c664a069" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/compose/.gradle/8.0/executionHistory/executionHistory.bin" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/8.0/executionHistory/executionHistory.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/.gradle/8.0/executionHistory/executionHistory.lock" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/8.0/executionHistory/executionHistory.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/fileHashes.bin" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/fileHashes.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/fileHashes.lock" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/fileHashes.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock" beforeDir="false" afterPath="$PROJECT_DIR$/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/ServerService.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/model/UserTankCrossRefRemote.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/api/repository/RestTankRepository.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/TankList.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/BuyTankViewModel.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/composeui/edit/PurchaseTankViewModel.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt" beforeDir="false" afterPath="$PROJECT_DIR$/compose/app/src/main/java/ru/ulstu/is/pmu/ui/AppViewModelProvider.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/compose/server/data.json" beforeDir="false" afterPath="$PROJECT_DIR$/compose/server/data.json" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectId" id="2a0MeoYvDLG6t8MsKUe7MRh0mGa" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"cidr.known.project.marker": "true",
"last_opened_file_path": "C:/Users/egore/Desktop/MyProjects/ULSTU/TankAppMobile/TanksApp/compose"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="fb78b956-3834-46c2-9adb-5184c664a069" name="Changes" comment="" />
<created>1703451140424</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1703451140424</updated>
</task>
<servers />
</component>
</project>

Binary file not shown.

View File

@ -90,13 +90,13 @@ interface ServerService {
@POST(ApiRoutes.NATION)
suspend fun insertNation(
@Body product: NationRemote
@Body nation: NationRemote
): NationRemote
@PUT("${ApiRoutes.NATION}/{id}")
suspend fun updateNation(
@Path("id") id: Long,
@Body product: NationRemote
@Body nation: NationRemote
): NationRemote
@DELETE("${ApiRoutes.NATION}/{id}")
@ -159,12 +159,12 @@ interface ServerService {
@GET("${ApiRoutes.USER_TANK}")
suspend fun getUserTankCrossRef(
@Query("id") id: Long
@Query("userId") userId: Long
): List<UserTankCrossRefRemote>
@POST(ApiRoutes.USER_TANK)
@POST("${ApiRoutes.USER_TANK}")
suspend fun insertUserTankCrossRef(
@Body tank: UserTankCrossRefRemote
@Body users_tank: UserTankCrossRefRemote
) : UserTankCrossRefRemote
@DELETE("${ApiRoutes.USER_TANK}/deleteMyTank")

View File

@ -8,20 +8,22 @@ import java.util.Date
@Serializable
data class UserTankCrossRefRemote (
val id: Long = 0,
val id: Long? = 0,
val userId: Long = 0,
val tankId: Long = 0,
@Serializable(with = DateSerializer::class)
val date: Date = Date()
val date: Date = Date(0)
)
fun UserTankCrossRefRemote.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef(
userId = id,
id = id,
userId = userId,
tankId = tankId,
date = date
)
fun UserTankCrossRef.toRemote(): UserTankCrossRefRemote = UserTankCrossRefRemote(
id = userId,
userId = userId,
tankId = tankId,
date = date
)

View File

@ -115,7 +115,7 @@ class RestTankRepository (
}
override suspend fun buyTank(tankId: Long, userId: Long, date: Date) {
service.insertUserTankCrossRef(UserTankCrossRefRemote(userId, tankId, date))
service.insertUserTankCrossRef(UserTankCrossRef(userId, tankId, date).toRemote())
}
override suspend fun insertMany(tankList: List<Tank>) {

View File

@ -59,6 +59,7 @@ import ru.ulstu.`is`.pmu.R
import ru.ulstu.`is`.pmu.composeui.navigation.Screen
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
import ru.ulstu.`is`.pmu.tank.composeui.edit.PurchaseTankViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListUiState
@ -77,6 +78,7 @@ import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
fun TankList(
navController: NavController?,
userTankEditViewModel: UsersTanksEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
purchaseTankViewModel: PurchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory),
listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
@ -87,6 +89,7 @@ fun TankList(
// Lazy Column, Pass the numbers array
if (navController != null) {
TankList(
purchaseTankViewModel = purchaseTankViewModel,
nations = listNations.nationsListUiState,
listTanks = viewModel.tankListUiState.tankList,
viewModel = userTankEditViewModel
@ -99,6 +102,7 @@ fun TankList(
@Composable
fun ColumnItem(
purchaseTankViewModel: PurchaseTankViewModel,
nation: Nation,
tanks: List<Tank>?,
onClick: (uid: Long) -> Unit,
@ -106,14 +110,9 @@ fun ColumnItem(
) {
val scope = rememberCoroutineScope()
val tank = viewModel.usersTanksUiState
val userId = 100L
fun handleTankButtonClick() {
scope.launch {
if (tank.userTankCrossRef.tankId == 0L) {
viewModel.saveUserTank()
}
}
}
val coroutineScope = rememberCoroutineScope()
Column(
modifier = Modifier.padding(0.dp, 10.dp)
@ -177,11 +176,12 @@ fun ColumnItem(
colors = ButtonDefaults.buttonColors(
containerColor = CustomRed,
contentColor = CustomDark),
onClick = { handleTankButtonClick() }
onClick = {
coroutineScope.launch {
purchaseTankViewModel.savePurchase(tank.tankId, userId)
}
}
) {
//navController?.navigate(Screen.Hangar.route)
//navController?.navigate(studentId)
//"${student.firstName} ${student.lastName}"
Text(text = stringResource(id = R.string.purchase_button))
}
}
@ -212,6 +212,7 @@ fun ColumnItem(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TankList(
purchaseTankViewModel: PurchaseTankViewModel,
nations: NationsListUiState,
listTanks: List<Tank>,
viewModel: UsersTanksEditViewModel,
@ -257,7 +258,7 @@ private fun TankList(
}
items(nations.nationList) {nation ->
ColumnItem(nation = nation, tanks = totalDictionary[nation], onClick = onClick, viewModel = viewModel)
ColumnItem(purchaseTankViewModel = purchaseTankViewModel, nation = nation, tanks = totalDictionary[nation], onClick = onClick, viewModel = viewModel)
}
// items(list/array) places number of
@ -279,6 +280,7 @@ fun TankListPreview() {
color = CustomDark
) {
TankList(
purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
nations = NationsListUiState(listOf()),
viewModel = viewModel(factory = AppViewModelProvider.Factory),
listTanks = (1..20).map { i -> Tank.getTank(i.toLong()) }
@ -296,6 +298,7 @@ fun TankEmptyListPreview() {
color = CustomDark
) {
TankList(
purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
nations = NationsListUiState(listOf()),
viewModel = viewModel(factory = AppViewModelProvider.Factory),
listTanks = listOf()

View File

@ -1,4 +0,0 @@
package ru.ulstu.`is`.pmu.tank.composeui.edit
class BuyTankViewModel {
}

View File

@ -0,0 +1,61 @@
package ru.ulstu.`is`.pmu.tank.composeui.edit
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import ru.ulstu.`is`.pmu.tank.model.UserTankCrossRef
import ru.ulstu.`is`.pmu.tank.repository.TankRepository
import java.util.Calendar
import java.util.Date
class PurchaseTankViewModel (
savedStateHandle: SavedStateHandle,
private val tankRepository: TankRepository
) : ViewModel() {
/*var purchaseUiState by mutableStateOf(PurchaseUiState())
private set*/
suspend fun savePurchase(tankId: Long, userId: Long){
if(tankId > 0 && userId > 0){
tankRepository.buyTank(tankId, userId, Calendar.getInstance().time)
}
}
/*private fun validateInput(uiState: PurchaseDetails = purchaseUiState.purchaseDetails): Boolean {
return with(uiState) {
userId > 0
&& tankId > 0
}
}*/
}
/*
data class PurchaseUiState(
val purchaseDetails: PurchaseDetails = PurchaseDetails(),
val isEntryValid: Boolean = false
)
data class PurchaseDetails(
val userId: Long = 0,
val tankId: Long = 0,
val date: Date = Calendar.getInstance().time,
)
fun PurchaseDetails.toUserTankCrossRef(): UserTankCrossRef = UserTankCrossRef(
userId = userId,
tankId = tankId,
date = date
)
fun UserTankCrossRef.toDetails(): PurchaseDetails = PurchaseDetails(
userId = userId,
tankId = tankId,
date = date
)
fun UserTankCrossRef.toUiState(isEntryValid: Boolean = false) : PurchaseUiState = PurchaseUiState(
purchaseDetails = this.toDetails(),
isEntryValid = isEntryValid
)*/

View File

@ -52,7 +52,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun remoteKeysDao(): RemoteKeysDao
companion object {
private const val DB_NAME: String = "25-db"
private const val DB_NAME: String = "27-db"
@Volatile
private var INSTANCE: AppDatabase? = null

View File

@ -1,5 +1,6 @@
package ru.ulstu.`is`.pmu.tank.model
import android.graphics.Bitmap
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
@ -12,17 +13,26 @@ import java.util.Date
//many to many for user and tank
@Entity(
tableName = "users_tanks",
primaryKeys = ["userId", "tankId"]
)
data class UserTankCrossRef(
@PrimaryKey(autoGenerate = true)
val id: Long?,
val userId: Long,
val tankId: Long,
@ColumnInfo(name = "date")
val date: Date,
){
@Ignore
constructor(
userId: Long,
tankId: Long,
date: Date,
) : this(null, userId, tankId, date)
companion object {
fun getEmpty(): UserTankCrossRef {
return UserTankCrossRef(
id = 0,
userId = 0,
tankId = 0,
date = Date()
@ -36,6 +46,7 @@ data class UserTankCrossRef(
other as UserTankCrossRef
if (id != other.id) return false
if (userId != other.userId) return false
if (tankId != other.tankId) return false
if (date != other.date) return false
@ -44,7 +55,8 @@ data class UserTankCrossRef(
}
override fun hashCode(): Int {
var result = userId.hashCode()
var result = id.hashCode()
result = 31 * result + userId.hashCode()
result = 31 * result + tankId.hashCode()
result = 31 * result + date.hashCode()
return result

View File

@ -87,7 +87,7 @@ private fun Hangar(
) {
var supportSizeRow = 1
if(n == supportCountRow && supportSizeRow % 2 != 0 && tankList.size != 2){
if(n == supportCountRow && index + supportSizeRow == tankList.size){
supportSizeRow = 0
}

View File

@ -9,6 +9,7 @@ import ru.ulstu.`is`.pmu.TankApplication
import ru.ulstu.`is`.pmu.tank.composeui.edit.LevelDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationsListUiState
import ru.ulstu.`is`.pmu.tank.composeui.edit.PurchaseTankViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.ReportViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel
@ -30,6 +31,12 @@ object AppViewModelProvider {
tankApplication().container.tankRestRepository
)
}
initializer {
PurchaseTankViewModel(
this.createSavedStateHandle(),
tankApplication().container.tankRestRepository
)
}
initializer {
UserEditViewModel(
this.createSavedStateHandle(),

View File

@ -209,37 +209,44 @@
],
"users_tanks": [
{
"id": 100,
"id": 1,
"userId": 100,
"tankId": 1,
"date": "2023-12-12T12:06:14.720+0000"
},
{
"id": 100,
"id": 2,
"userId": 100,
"tankId": 5,
"date": "2023-12-13T12:06:14.720+0000"
},
{
"id": 100,
"id": 3,
"userId": 100,
"tankId": 6,
"date": "2023-12-14T12:06:14.720+0000"
},
{
"id": 101,
"id": 4,
"userId": 101,
"tankId": 6,
"date": "2023-12-15T12:06:14.720+0000"
},
{
"id": 101,
"id": 5,
"userId": 101,
"tankId": 11,
"date": "2023-12-16T12:06:14.720+0000"
},
{
"id": 102,
"id": 6,
"userId": 102,
"tankId": 6,
"date": "2023-12-17T12:06:14.720+0000"
},
{
"id": 102,
"id": 7,
"userId": 102,
"tankId": 1,
"date": "2023-12-18T12:06:14.720+0000"
}