бронирование, роли, надо сделать вход с учетом роли

This commit is contained in:
Татьяна Артамонова 2023-12-26 23:46:16 +04:00
parent f2597c6d61
commit 5dde1465e2
19 changed files with 522 additions and 249 deletions

View File

@ -67,8 +67,9 @@ class RestTicketRepository(
override suspend fun getTicketById(ticketId: Int): Ticket =
ticketId.let { service.getTicket(it).toTicket() }
override suspend fun insertTicket(ticket: Ticket) {
service.createTicket(ticket.toTicketRemote()).toTicket()
override suspend fun insertTicket(ticket: Ticket) : Long {
val createdTicket = service.createTicket(ticket.toTicketRemote()).toTicket()
return createdTicket.id.toLong()
}
override suspend fun updateTicket(ticket: Ticket) {

View File

@ -26,7 +26,7 @@ interface TicketDao {
fun getFlightsTickets(flightId: Int): List<Ticket>
@Insert
suspend fun insert(vararg ticket: Ticket)
suspend fun insert(vararg ticket: Ticket) : List<Long>
@Update
suspend fun update(ticket: Ticket)

View File

@ -11,7 +11,7 @@ import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.database.models.Ticket
class OfflineTicketRepository(private val ticketDao: TicketDao) : TicketRepository {
override suspend fun insertTicket(ticket: Ticket) = ticketDao.insert(ticket)
override suspend fun insertTicket(ticket: Ticket) : Long = ticketDao.insert(ticket)[0]
override suspend fun updateTicket(ticket: Ticket) = ticketDao.update(ticket)
override suspend fun deleteTicket(ticket: Ticket) = ticketDao.delete(ticket)
override suspend fun getAllTickets(): List<Ticket> = ticketDao.getAll()
@ -27,5 +27,5 @@ class OfflineTicketRepository(private val ticketDao: TicketDao) : TicketReposito
override suspend fun getFlightsTickets(flightId: Int): List<Ticket> = ticketDao.getFlightsTickets(flightId)
suspend fun clearTickets() = ticketDao.deleteAll()
suspend fun insertTickets(tickets: List<Ticket>) =
ticketDao.insert(*tickets.toTypedArray())
ticketDao.insert(*tickets.toTypedArray())[0]
}

View File

@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.Flow
import ru.ulstu.`is`.airticketrentservice.database.models.Ticket
interface TicketRepository {
suspend fun insertTicket(ticket: Ticket)
suspend fun insertTicket(ticket: Ticket) : Long
suspend fun updateTicket(ticket: Ticket)
suspend fun deleteTicket(ticket: Ticket)
suspend fun getAllTickets(): List<Ticket>

View File

@ -156,7 +156,7 @@ fun HomeNavGraph(
navArgument("flightId") { type = NavType.IntType }
)
) {
TicketView(navController)
TicketView(navController, currentUserViewModel)
}
}
}

View File

@ -15,17 +15,17 @@ sealed class BottomBarScreen(
){
object MainPage: BottomBarScreen(
route = "main",
title ="",
title = "Поиск",
icon = Icons.Filled.AirplanemodeActive
)
object Profile: BottomBarScreen(
route = "profile",
title ="",
title = "Профиль",
icon = Icons.Filled.AccountCircle
)
object Admin: BottomBarScreen(
route = "admin",
title ="",
title ="Админ",
icon = Icons.Filled.AdminPanelSettings
)
object FlightList: BottomBarScreen(
@ -50,7 +50,7 @@ sealed class BottomBarScreen(
)
object MyRents: BottomBarScreen(
route = "my-rents/{userId}",
title ="",
title = "Мои бронирования",
icon = Icons.Filled.Payments
) {
fun passId(userId: String): String{

View File

@ -34,9 +34,9 @@ fun FlightInfo(
) {
FlightInfo(
flightUiState = flightViewModel.flightUiState,
onClick = { uid: Int ->
Log.d("FlightInfo", "Текущий рейс: $uid")
val route = BottomBarScreen.TicketView.passIdAndFlightId(0.toString(), uid.toString())
onClick = {
Log.d("FlightInfo", "Текущий рейс для передачи в билет: ${flightViewModel.flightId}")
val route = BottomBarScreen.TicketView.passIdAndFlightId(0.toString(), flightViewModel.flightId.toString())
navController.navigate(route)
}
)
@ -46,7 +46,7 @@ fun FlightInfo(
@Composable
private fun FlightInfo(
flightUiState: FlightUiState,
onClick: (Int) -> Unit
onClick: () -> Unit
) {
Column(
Modifier
@ -157,7 +157,7 @@ private fun FlightInfo(
readOnly = true
)
Button(
onClick = { onClick(flightUiState.flightDetails.toFlight().id) },
onClick = onClick,
enabled = flightUiState.isEntryValid,
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp,

View File

@ -1,5 +1,6 @@
package ru.ulstu.`is`.airticketrentservice.screen
import android.util.Log
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@ -41,6 +42,7 @@ fun FoundFlights(
.fillMaxSize(),
flightList = foundFlightsUiState.flightList,
onClick = { uid: Int ->
Log.d("FoundFlights", "Текущий рейс: $uid")
val route = BottomBarScreen.FlightInfo.passId(uid.toString())
navController.navigate(route)
}

View File

@ -53,8 +53,8 @@ fun Profile(
navController: NavController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val getUser by remember { mutableStateOf(currentUserViewModel.user) }
Log.d("CurrentUserViewModel1", "Текущий пользователь: $getUser")
val currentUser by remember { mutableStateOf(currentUserViewModel.user) }
Log.d("CurrentUserViewModel1", "Текущий пользователь: $currentUser")
val state = rememberScrollState()
LaunchedEffect(Unit) { state.animateScrollTo(100) }
Column(
@ -87,7 +87,7 @@ fun Profile(
TextField(modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
value = "${getUser?.surname} ${getUser?.name} ${getUser?.patronymic}", onValueChange = {}, readOnly = true,
value = "${currentUser?.surname} ${currentUser?.name} ${currentUser?.patronymic}", onValueChange = {}, readOnly = true,
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.LightGray.copy(.2f),
unfocusedContainerColor = Color.LightGray.copy(.2f),
@ -103,7 +103,7 @@ fun Profile(
TextField(modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
value = "${getUser?.email}", onValueChange = {}, readOnly = true,
value = "${currentUser?.email}", onValueChange = {}, readOnly = true,
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.LightGray.copy(.2f),
unfocusedContainerColor = Color.LightGray.copy(.2f),
@ -119,7 +119,7 @@ fun Profile(
TextField(modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
value = "${getUser?.date_of_birth}", onValueChange = {}, readOnly = true,
value = "${currentUser?.date_of_birth}", onValueChange = {}, readOnly = true,
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.LightGray.copy(.2f),
unfocusedContainerColor = Color.LightGray.copy(.2f),
@ -137,7 +137,7 @@ fun Profile(
.fillMaxWidth()
.padding(5.dp),
onClick = {
navController.navigate(BottomBarScreen.UserEdit.passId(getUser?.id.toString()))
navController.navigate(BottomBarScreen.UserEdit.passId(currentUser?.id.toString()))
},
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp,
@ -154,7 +154,7 @@ fun Profile(
.fillMaxWidth()
.padding(5.dp),
onClick = {
val route = BottomBarScreen.MyRents.passId(getUser?.id.toString())
val route = BottomBarScreen.MyRents.passId(currentUser?.id.toString())
navController.navigate(route)
},
elevation = ButtonDefaults.buttonElevation(

View File

@ -18,6 +18,8 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableDoubleStateOf
@ -53,7 +55,7 @@ import ru.ulstu.`is`.airticketrentservice.viewModel.toUiState
fun TicketEdit(
navController: NavController,
viewModel: TicketEditViewModel = viewModel(factory = AppViewModelProvider.Factory),
flightViewModel: FlightDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory),
flightViewModel: FlightDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val coroutineScope = rememberCoroutineScope()
flightViewModel.setCurrentDropDownFlight(viewModel.ticketUiState.ticketDetails.flightId)
@ -140,7 +142,7 @@ private fun TicketEdit(
flightsListUiState: FlightsDropDownListUiState,
onClick: () -> Unit,
onUpdate: (TicketDetails) -> Unit,
onFlightUpdate: (Flight) -> Unit,
onFlightUpdate: (Flight) -> Unit
) {
Column(
Modifier
@ -157,7 +159,6 @@ private fun TicketEdit(
onUpdate(ticketUiState.ticketDetails.copy(flightId = it.id))
onFlightUpdate(it)
}
val passengersCount by derivedStateOf {
ticketUiState.ticketDetails.passengers_count
}
@ -167,7 +168,6 @@ private fun TicketEdit(
val totalCost by derivedStateOf {
passengersCount * oneTicketCost.toDouble()
}
Log.d("TicketEdit", "Текущий рейс: ${flightUiState.flight}")
TextField(
modifier = Modifier
.fillMaxWidth()
@ -183,12 +183,14 @@ private fun TicketEdit(
label = { Text("Стоимость одного билета") },
singleLine = true
)
val ticketCost = remember { mutableDoubleStateOf(totalCost) }
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = ticketUiState.ticketDetails.passengers_count.toString(),
onValueChange = { if (it.isNotEmpty()) {
onValueChange = {
if (it.isNotEmpty()) {
onUpdate(ticketUiState.ticketDetails.copy(passengers_count = it.toInt()))
} else {
onUpdate(ticketUiState.ticketDetails.copy(passengers_count = 0))
@ -202,25 +204,18 @@ private fun TicketEdit(
label = { Text("Количество пассажиров") },
singleLine = true
)
// Button(
// onClick = { totalCost = passengersCount * oneTicketCost.toDouble() },
// enabled = ticketUiState.isEntryValid,
// elevation = ButtonDefaults.buttonElevation(
// defaultElevation = 10.dp,
// pressedElevation = 6.dp
// ),
// shape = RoundedCornerShape(15.dp),
// colors = ButtonDefaults.buttonColors(containerColor = colorResource(R.color.lightBlue)),
// modifier = Modifier.fillMaxWidth()
// ) {
// Text(text = "Рассчитать стоимость билета")
// }
LaunchedEffect(totalCost) {
ticketCost.doubleValue = totalCost
onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = ticketCost.doubleValue))
}
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = totalCost.toString(),
onValueChange = { onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = it.toDouble())) },
value = ticketCost.doubleValue.toString(),
onValueChange = {
onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = it.toDouble()))
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
@ -231,22 +226,6 @@ private fun TicketEdit(
singleLine = true,
readOnly = true
)
// TextField(
// modifier = Modifier
// .fillMaxWidth()
// .padding(10.dp),
// value = totalCost.toString(),
// onValueChange = {},
// colors = TextFieldDefaults.textFieldColors(
// containerColor = Color.LightGray.copy(.2f),
// unfocusedIndicatorColor = Color.Transparent,
// focusedIndicatorColor = Color.Transparent
// ),
// shape = RoundedCornerShape(15.dp),
// label = { Text("Стоимость за всех пассажиров") },
// singleLine = true,
// readOnly = true
// )
Button(
onClick = onClick,
enabled = ticketUiState.isEntryValid,

View File

@ -238,7 +238,7 @@ private fun TicketListItem(
modifier = modifier.padding(all = 10.dp)
) {
Text(
text = "Билет ${ticket.id}"
text = "Билет ${ticket.id}. Стоимость ${ticket.ticket_cost}"
)
}
}

View File

@ -1,71 +1,174 @@
package ru.ulstu.`is`.airticketrentservice.screen
import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import kotlinx.coroutines.launch
import ru.ulstu.`is`.airticketrentservice.R
import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen
import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider
import ru.ulstu.`is`.airticketrentservice.viewModel.CurrentUserViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightDropDownUiState
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightDropDownViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightUiState
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightsDropDownListUiState
import ru.ulstu.`is`.airticketrentservice.viewModel.RentEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketDetails
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketUiState
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketViewViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.toTicket
@Composable
fun TicketView(
navController: NavController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
viewModel: TicketViewViewModel = viewModel(factory = AppViewModelProvider.Factory),
flightViewModel: FlightEditViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
flightViewModel: FlightDropDownViewModel = viewModel(factory = AppViewModelProvider.Factory),
rentEditViewModel: RentEditViewModel = viewModel(factory = AppViewModelProvider.Factory)
) {
val coroutineScope = rememberCoroutineScope()
//flightViewModel.setCurrentFlight(viewModel.ticketUiState.ticketDetails.flightId)
val totalCost by remember { mutableDoubleStateOf(flightViewModel.flightUiState.flightDetails.one_ticket_cost * viewModel.ticketUiState.ticketDetails.passengers_count.toDouble()) }
flightViewModel.setCurrentDropDownFlight(viewModel.flightId)
val currentUser by remember { mutableStateOf(currentUserViewModel.user) }
TicketEdit(
ticketUiState = viewModel.ticketUiState,
flightUiState = flightViewModel.flightUiState,
flightUiState = flightViewModel.flightDropDownUiState,
onClick = {
coroutineScope.launch {
viewModel.saveTicket()
navController.navigate(BottomBarScreen.RentEdit.passId(0.toString()))
Log.d("TicketView", "Текущий пользователь: $currentUser")
Log.d("TicketView", "Стоимость билета: ${viewModel.ticketUiState.ticketDetails.ticket_cost}")
Log.d("TicketView", "Текущий рейс для билета: ${viewModel.flightId}")
viewModel.saveNewTicket(viewModel.flightId)
viewModel.savedTicket.collect { id ->
Log.d("TicketView", "Текущий билет: $id")
currentUser?.let { id?.toInt()
?.let { it1 -> rentEditViewModel.saveNewRent(it.id, it1) } }}
}
navController.navigate(BottomBarScreen.Profile.route)
},
onUpdate = viewModel::updateUiState,
totalCost = totalCost
onUpdate = viewModel::updateUiState
)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun FlightView(
flightUiState: FlightDropDownUiState
) {
flightUiState.flight?.direction_from?.let {
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = it,
onValueChange = {},
readOnly = true,
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_from)) }
)
}
flightUiState.flight?.direction_to?.let {
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = it,
onValueChange = {},
readOnly = true,
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_to)) }
)
}
flightUiState.flight?.departure_date?.let {
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = it,
onValueChange = {},
readOnly = true,
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_arrivalDate)) }
)
}
flightUiState.flight?.arrival_date?.let {
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = it,
onValueChange = {},
readOnly = true,
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_departureDate)) }
)
}
}
@SuppressLint("UnrememberedMutableState")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TicketEdit(
ticketUiState: TicketUiState,
flightUiState: FlightUiState,
flightUiState: FlightDropDownUiState,
onClick: () -> Unit,
onUpdate: (TicketDetails) -> Unit,
totalCost: Double
onUpdate: (TicketDetails) -> Unit
) {
//ticketUiState.ticketDetails.ticket_cost = totalCost
Column(
Modifier
.fillMaxWidth()
@ -74,92 +177,32 @@ private fun TicketEdit(
.padding(vertical = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = flightUiState.flightDetails.direction_from,
onValueChange = {},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_from)) },
singleLine = true,
readOnly = true
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = flightUiState.flightDetails.direction_to,
onValueChange = {},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_to)) },
singleLine = true,
readOnly = true
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = flightUiState.flightDetails.departure_date,
onValueChange = {},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_arrivalDate)) },
singleLine = true,
readOnly = true
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = flightUiState.flightDetails.arrival_date,
onValueChange = {},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text(stringResource(id = R.string.ticket_departureDate)) },
singleLine = true,
readOnly = true
)
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = totalCost.toString(),
onValueChange = { onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = it.toDouble())) },
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text("Стоимость билета") },
singleLine = true,
readOnly = true
)
FlightView(flightUiState = flightUiState)
val passengersCount by derivedStateOf {
ticketUiState.ticketDetails.passengers_count
}
val oneTicketCost by derivedStateOf {
flightUiState.flight?.one_ticket_cost ?: 0
}
val totalCost by derivedStateOf {
passengersCount * oneTicketCost.toDouble()
}
val ticketCost = remember { mutableDoubleStateOf(totalCost) }
Log.d("TicketView", "Текущий рейс: ${flightUiState.flight}")
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = ticketUiState.ticketDetails.passengers_count.toString(),
onValueChange = { onUpdate(ticketUiState.ticketDetails.copy(passengers_count = it.toInt())) },
onValueChange = {
if (it.isNotEmpty()) {
onUpdate(ticketUiState.ticketDetails.copy(passengers_count = it.toInt()))
} else {
onUpdate(ticketUiState.ticketDetails.copy(passengers_count = 1))
}},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
@ -167,27 +210,33 @@ private fun TicketEdit(
),
shape = RoundedCornerShape(15.dp),
label = { Text("Количество пассажиров") },
singleLine = true
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)
LaunchedEffect(totalCost) {
ticketCost.doubleValue = totalCost
onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = ticketCost.doubleValue))
}
TextField(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
value = totalCost.toString(),
onValueChange = {},
value = ticketCost.doubleValue.toString(),
onValueChange = {
onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = it.toDouble()))
},
colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(15.dp),
label = { Text("Стоимость за всех пассажиров") },
label = { Text("Стоимость билета за всех пассажиров") },
singleLine = true,
readOnly = true
)
Button(
onClick = onClick,
enabled = ticketUiState.isEntryValid,
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp,
pressedElevation = 6.dp

View File

@ -64,6 +64,7 @@ import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider
import ru.ulstu.`is`.airticketrentservice.viewModel.CurrentUserViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.RegistrationViewModel
import ru.ulstu.`is`.airticketrentservice.R
import ru.ulstu.`is`.airticketrentservice.database.models.RoleEnum
import ru.ulstu.`is`.airticketrentservice.elements.ValidateEmail
import ru.ulstu.`is`.airticketrentservice.graphs.AuthScreen
import ru.ulstu.`is`.airticketrentservice.graphs.Graph
@ -222,20 +223,6 @@ fun Registration(navController: NavController, modifier: Modifier = Modifier, re
}
)
ValidateEmail(emailValue) { emailValue = it }
// TextField(modifier = Modifier
// .fillMaxWidth()
// .padding(all = 10.dp),
// value = emailValue, onValueChange = { emailValue = it },
// colors = TextFieldDefaults.textFieldColors(
// containerColor = Color.LightGray.copy(.2f),
// unfocusedIndicatorColor = Color.Transparent,
// focusedIndicatorColor = Color.Transparent
// ),
// shape = RoundedCornerShape(15.dp),
// label = {
// Text("Электронная почта")
// }
// )
TextField(modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
@ -286,7 +273,7 @@ fun Registration(navController: NavController, modifier: Modifier = Modifier, re
}
}
if (!isExist) {
val newUser = User(0, surnameValue, nameValue, patronymicValue, dateOfBirthValue, emailValue, passwordValue, "user")
val newUser = User(0, surnameValue, nameValue, patronymicValue, dateOfBirthValue, emailValue, passwordValue, RoleEnum.User.name)
coroutineScope.launch {
val insertResult = async {
registrationViewModel.insertUser(newUser)

View File

@ -20,6 +20,7 @@ class FlightEditViewModel(
private set
private val flightUid: Int = checkNotNull(savedStateHandle["id"])
val flightId = flightUid
init {
viewModelScope.launch {

View File

@ -24,15 +24,15 @@ class RentEditViewModel(
init {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val rent = rentRepository.getRentById(rentUid)
.toUiState(true)
launch(Dispatchers.Main) {
if (rentUid > 0) {
rentUiState = rent
}
val rent = if (rentUid > 0) {
withContext(Dispatchers.IO) {
rentRepository.getRentById(rentUid).toUiState(true)
}
} else {
null
}
if (rent != null) {
rentUiState = rent
}
}
}
@ -52,6 +52,17 @@ class RentEditViewModel(
}
}
}
suspend fun saveNewRent(userId: Int = 0, ticketId: Int = 0) {
val newRent = rentUiState.rentDetails.toNewRent(0, userId, ticketId)
rentRepository.insertRent(newRent)
}
private fun RentDetails.toNewRent(id: Int = 0, userId: Int = 0, ticketId: Int = 0): Rent = Rent(
id = id,
status = status,
userId = userId,
ticketId = ticketId
)
private fun validateInput(uiState: RentDetails = rentUiState.rentDetails): Boolean {
return with(uiState) {

View File

@ -46,33 +46,6 @@ class TicketEditViewModel(
}
}
// init {
// viewModelScope.launch {
// withContext(Dispatchers.IO) {
// val tickets = ticketRepository.getAllTickets()
// val ticket = ticketRepository.getTicketById(ticketUid)
// .toUiState(true)
// launch(Dispatchers.Main) {
// if (ticketUid > 0) {
// ticketsListUiState = TicketsListUiState(tickets)
// ticketUiState = ticket
// }
// }
// }
// }
// }
// init {
// viewModelScope.launch {
// if (ticketUid > 0) {
// ticketsListUiState = TicketsListUiState(ticketRepository.getAllTickets())
// ticketUiState = ticketRepository.getTicketById(ticketUid)
// .toUiState(true)
// }
// }
// }
fun setCurrentTicket(ticketId: Int) {
val ticket: Ticket? =
ticketsListUiState.ticketList.firstOrNull { ticket -> ticket.id == ticketId }
@ -129,6 +102,13 @@ fun TicketDetails.toTicket(uid: Int = 0): Ticket = Ticket(
flightId = flightId
)
fun TicketDetails.toNewTicket(uid: Int = 0, flightId: Int = 0): Ticket = Ticket(
id = uid,
passengers_count = passengers_count,
ticket_cost = ticket_cost,
flightId = flightId
)
fun Ticket.toDetails(): TicketDetails = TicketDetails(
passengers_count = passengers_count,
ticket_cost = ticket_cost,

View File

@ -1,14 +1,19 @@
package ru.ulstu.`is`.airticketrentservice.viewModel
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.database.models.Ticket
import ru.ulstu.`is`.airticketrentservice.database.repository.TicketRepository
class TicketViewViewModel(
@ -21,22 +26,25 @@ class TicketViewViewModel(
private val ticketUid: Int = checkNotNull(savedStateHandle["id"])
private val flightUid: Int = checkNotNull(savedStateHandle["flightId"])
val flightId = flightUid
val id = ticketUid
init {
viewModelScope.launch {
withContext(Dispatchers.IO) {
val ticket = ticketRepository.getTicketById(ticketUid)
.toUiState(true)
launch(Dispatchers.Main) {
if (ticketUid > 0) {
ticketUiState = ticket
ticketUiState.ticketDetails.flightId = flightUid
}
val ticket = if (ticketUid > 0) {
withContext(Dispatchers.IO) {
ticketRepository.getTicketById(ticketUid).toUiState(true)
}
} else {
null
}
if (ticket != null) {
ticketUiState = ticket
}
}
}
fun updateUiState(ticketDetails: TicketDetails) {
ticketUiState = TicketUiState(
ticketDetails = ticketDetails,
@ -45,18 +53,11 @@ class TicketViewViewModel(
)
}
suspend fun saveTicket() {
if (validateInput()) {
if (ticketUid > 0) {
ticketRepository.updateTicket(
ticketUiState.ticketDetails.toTicket(ticketUid)
)
} else {
ticketRepository.insertTicket(
ticketUiState.ticketDetails.toTicket()
)
}
}
val savedTicket: MutableStateFlow<Long?> = MutableStateFlow(null)
suspend fun saveNewTicket(flightId: Int) {
val newTicket = ticketUiState.ticketDetails.toNewTicket(0, flightId)
savedTicket.value = ticketRepository.insertTicket(newTicket)
}
private fun validateInput(uiState: TicketDetails = ticketUiState.ticketDetails): Boolean {

View File

@ -8,9 +8,129 @@
},
{
"id": 2,
"passengers_count": 3,
"ticket_cost": 2435,
"passengers_count": 2,
"ticket_cost": 4870,
"flightId": 5
},
{
"passengers_count": 5,
"ticket_cost": 54000,
"flightId": 10,
"id": 3
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 4
},
{
"passengers_count": 3,
"ticket_cost": 26160,
"flightId": 8,
"id": 5
},
{
"passengers_count": 5,
"ticket_cost": 54000,
"flightId": 10,
"id": 6
},
{
"passengers_count": 4,
"ticket_cost": 71200,
"flightId": 9,
"id": 7
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 8
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 9
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 10
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 11
},
{
"passengers_count": 11,
"ticket_cost": 29480,
"flightId": 6,
"id": 12
},
{
"passengers_count": 3,
"ticket_cost": 8040,
"flightId": 6,
"id": 13
},
{
"passengers_count": 8,
"ticket_cost": 142400,
"flightId": 9,
"id": 14
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 15
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 16
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 17
},
{
"passengers_count": 1,
"ticket_cost": 17800,
"flightId": 9,
"id": 18
},
{
"passengers_count": 5,
"ticket_cost": 5000,
"flightId": 2,
"id": 19
},
{
"passengers_count": 6,
"ticket_cost": 6000,
"flightId": 2,
"id": 20
},
{
"passengers_count": 3,
"ticket_cost": 3000,
"flightId": 2,
"id": 21
},
{
"passengers_count": 10,
"ticket_cost": 10000,
"flightId": 2,
"id": 22
}
],
"flights": [
@ -87,7 +207,7 @@
"date_of_birth": "7-11-2003",
"email": "usertt@mail.ru",
"password": "usertt",
"role": "user"
"role": "User"
},
{
"surname": "а",
@ -96,7 +216,7 @@
"date_of_birth": "17-5-2000",
"email": "user@mail.ru",
"password": "user",
"role": "user",
"role": "User",
"id": 3
},
{
@ -106,7 +226,7 @@
"date_of_birth": "10-12-2015",
"email": "aaa@mail.ru",
"password": "aaa",
"role": "user",
"role": "User",
"id": 4
},
{
@ -116,7 +236,7 @@
"date_of_birth": "10-12-2015",
"email": "aa@mail.ru",
"password": "aaa",
"role": "user",
"role": "User",
"id": 5
},
{
@ -126,7 +246,7 @@
"date_of_birth": "7-5-2005",
"email": "userff@mail.ru",
"password": "password",
"role": "user",
"role": "User",
"id": 6
},
{
@ -136,8 +256,18 @@
"date_of_birth": "23-12-2011",
"email": "kkk@mail.ru",
"password": "kkk",
"role": "user",
"role": "User",
"id": 7
},
{
"id": 8,
"surname": "Артамонова",
"name": "Татьяна",
"patronymic": "Валерьевна",
"date_of_birth": "7-11-2003",
"email": "admin@mail.ru",
"password": "admin",
"role": "Admin"
}
],
"rents": [
@ -152,6 +282,18 @@
"status": "Подтверждено",
"userId": 2,
"ticketId": 2
},
{
"status": "Ожидает подтверждения",
"userId": 2,
"ticketId": 21,
"id": 3
},
{
"status": "Ожидает подтверждения",
"userId": 2,
"ticketId": 22,
"id": 4
}
]
}

View File

@ -8,9 +8,123 @@
},
{
"id": 2,
"passengers_count": 1,
"ticket_cost": 2435,
"passengers_count": 2,
"ticket_cost": 4870,
"flightId": 5
},
{
"passengers_count": 5,
"ticket_cost": 54000,
"flightId": 10,
"id": 3
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 4
},
{
"passengers_count": 3,
"ticket_cost": 26160,
"flightId": 8,
"id": 5
},
{
"passengers_count": 5,
"ticket_cost": 54000,
"flightId": 10,
"id": 6
},
{
"passengers_count": 4,
"ticket_cost": 71200,
"flightId": 9,
"id": 7
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 8
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 9
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 10
},
{
"passengers_count": 6,
"ticket_cost": 106800,
"flightId": 9,
"id": 11
},
{
"passengers_count": 11,
"ticket_cost": 29480,
"flightId": 6,
"id": 12
},
{
"passengers_count": 3,
"ticket_cost": 8040,
"flightId": 6,
"id": 13
},
{
"passengers_count": 8,
"ticket_cost": 142400,
"flightId": 9,
"id": 14
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 15
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 16
},
{
"passengers_count": 1,
"ticket_cost": 2680,
"flightId": 6,
"id": 17
},
{
"passengers_count": 1,
"ticket_cost": 17800,
"flightId": 9,
"id": 18
},
{
"passengers_count": 5,
"ticket_cost": 5000,
"flightId": 2,
"id": 19
},
{
"passengers_count": 6,
"ticket_cost": 6000,
"flightId": 2,
"id": 20
},
{
"passengers_count": 3,
"ticket_cost": 3000,
"flightId": 2,
"id": 21
}
],
"flights": [
@ -42,13 +156,13 @@
"one_ticket_cost": 2680
},
{
"id": 7,
"direction_from": "Хабаровск",
"direction_to": "Кострома",
"departure_date": "5-1-2024",
"arrival_date": "5-1-2024",
"tickets_count": 200,
"one_ticket_cost": 6870,
"id": 7
"one_ticket_cost": 6870
},
{
"direction_from": "Астрахань",
@ -87,7 +201,7 @@
"date_of_birth": "7-11-2003",
"email": "usertt@mail.ru",
"password": "usertt",
"role": "user"
"role": "Admin"
},
{
"surname": "а",
@ -96,7 +210,7 @@
"date_of_birth": "17-5-2000",
"email": "user@mail.ru",
"password": "user",
"role": "user",
"role": "User",
"id": 3
},
{
@ -106,7 +220,7 @@
"date_of_birth": "10-12-2015",
"email": "aaa@mail.ru",
"password": "aaa",
"role": "user",
"role": "User",
"id": 4
},
{
@ -116,7 +230,7 @@
"date_of_birth": "10-12-2015",
"email": "aa@mail.ru",
"password": "aaa",
"role": "user",
"role": "User",
"id": 5
},
{
@ -126,7 +240,7 @@
"date_of_birth": "7-5-2005",
"email": "userff@mail.ru",
"password": "password",
"role": "user",
"role": "User",
"id": 6
},
{
@ -136,7 +250,7 @@
"date_of_birth": "23-12-2011",
"email": "kkk@mail.ru",
"password": "kkk",
"role": "user",
"role": "User",
"id": 7
}
],
@ -152,6 +266,12 @@
"status": "Подтверждено",
"userId": 2,
"ticketId": 2
},
{
"status": "Ожидает подтверждения",
"userId": 2,
"ticketId": 21,
"id": 3
}
]
}