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

View File

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

View File

@ -115,7 +115,7 @@ class RestTankRepository (
} }
override suspend fun buyTank(tankId: Long, userId: Long, date: Date) { 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>) { 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.composeui.navigation.Screen
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel 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.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.TankEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.UsersTanksEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.list.TankListUiState import ru.ulstu.`is`.pmu.tank.composeui.list.TankListUiState
@ -77,6 +78,7 @@ import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme
fun TankList( fun TankList(
navController: NavController?, navController: NavController?,
userTankEditViewModel: UsersTanksEditViewModel = viewModel(factory = AppViewModelProvider.Factory), userTankEditViewModel: UsersTanksEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
purchaseTankViewModel: PurchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory), viewModel: TankListViewModel = viewModel(factory = AppViewModelProvider.Factory),
listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory) listNations: NationDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
@ -87,6 +89,7 @@ fun TankList(
// Lazy Column, Pass the numbers array // Lazy Column, Pass the numbers array
if (navController != null) { if (navController != null) {
TankList( TankList(
purchaseTankViewModel = purchaseTankViewModel,
nations = listNations.nationsListUiState, nations = listNations.nationsListUiState,
listTanks = viewModel.tankListUiState.tankList, listTanks = viewModel.tankListUiState.tankList,
viewModel = userTankEditViewModel viewModel = userTankEditViewModel
@ -99,6 +102,7 @@ fun TankList(
@Composable @Composable
fun ColumnItem( fun ColumnItem(
purchaseTankViewModel: PurchaseTankViewModel,
nation: Nation, nation: Nation,
tanks: List<Tank>?, tanks: List<Tank>?,
onClick: (uid: Long) -> Unit, onClick: (uid: Long) -> Unit,
@ -106,14 +110,9 @@ fun ColumnItem(
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val tank = viewModel.usersTanksUiState val tank = viewModel.usersTanksUiState
val userId = 100L
fun handleTankButtonClick() { val coroutineScope = rememberCoroutineScope()
scope.launch {
if (tank.userTankCrossRef.tankId == 0L) {
viewModel.saveUserTank()
}
}
}
Column( Column(
modifier = Modifier.padding(0.dp, 10.dp) modifier = Modifier.padding(0.dp, 10.dp)
@ -177,11 +176,12 @@ fun ColumnItem(
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = CustomRed, containerColor = CustomRed,
contentColor = CustomDark), 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)) Text(text = stringResource(id = R.string.purchase_button))
} }
} }
@ -212,6 +212,7 @@ fun ColumnItem(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TankList( private fun TankList(
purchaseTankViewModel: PurchaseTankViewModel,
nations: NationsListUiState, nations: NationsListUiState,
listTanks: List<Tank>, listTanks: List<Tank>,
viewModel: UsersTanksEditViewModel, viewModel: UsersTanksEditViewModel,
@ -257,7 +258,7 @@ private fun TankList(
} }
items(nations.nationList) {nation -> 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 // items(list/array) places number of
@ -279,6 +280,7 @@ fun TankListPreview() {
color = CustomDark color = CustomDark
) { ) {
TankList( TankList(
purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
nations = NationsListUiState(listOf()), nations = NationsListUiState(listOf()),
viewModel = viewModel(factory = AppViewModelProvider.Factory), viewModel = viewModel(factory = AppViewModelProvider.Factory),
listTanks = (1..20).map { i -> Tank.getTank(i.toLong()) } listTanks = (1..20).map { i -> Tank.getTank(i.toLong()) }
@ -296,6 +298,7 @@ fun TankEmptyListPreview() {
color = CustomDark color = CustomDark
) { ) {
TankList( TankList(
purchaseTankViewModel = viewModel(factory = AppViewModelProvider.Factory),
nations = NationsListUiState(listOf()), nations = NationsListUiState(listOf()),
viewModel = viewModel(factory = AppViewModelProvider.Factory), viewModel = viewModel(factory = AppViewModelProvider.Factory),
listTanks = listOf() 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 abstract fun remoteKeysDao(): RemoteKeysDao
companion object { companion object {
private const val DB_NAME: String = "25-db" private const val DB_NAME: String = "27-db"
@Volatile @Volatile
private var INSTANCE: AppDatabase? = null private var INSTANCE: AppDatabase? = null

View File

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

View File

@ -87,7 +87,7 @@ private fun Hangar(
) { ) {
var supportSizeRow = 1 var supportSizeRow = 1
if(n == supportCountRow && supportSizeRow % 2 != 0 && tankList.size != 2){ if(n == supportCountRow && index + supportSizeRow == tankList.size){
supportSizeRow = 0 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.LevelDropDownViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.NationDropDownViewModel 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.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.ReportViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.TankEditViewModel
import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel import ru.ulstu.`is`.pmu.tank.composeui.edit.UserEditViewModel
@ -30,6 +31,12 @@ object AppViewModelProvider {
tankApplication().container.tankRestRepository tankApplication().container.tankRestRepository
) )
} }
initializer {
PurchaseTankViewModel(
this.createSavedStateHandle(),
tankApplication().container.tankRestRepository
)
}
initializer { initializer {
UserEditViewModel( UserEditViewModel(
this.createSavedStateHandle(), this.createSavedStateHandle(),

View File

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