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

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 = override suspend fun getTicketById(ticketId: Int): Ticket =
ticketId.let { service.getTicket(it).toTicket() } ticketId.let { service.getTicket(it).toTicket() }
override suspend fun insertTicket(ticket: Ticket) { override suspend fun insertTicket(ticket: Ticket) : Long {
service.createTicket(ticket.toTicketRemote()).toTicket() val createdTicket = service.createTicket(ticket.toTicketRemote()).toTicket()
return createdTicket.id.toLong()
} }
override suspend fun updateTicket(ticket: Ticket) { override suspend fun updateTicket(ticket: Ticket) {

View File

@ -26,7 +26,7 @@ interface TicketDao {
fun getFlightsTickets(flightId: Int): List<Ticket> fun getFlightsTickets(flightId: Int): List<Ticket>
@Insert @Insert
suspend fun insert(vararg ticket: Ticket) suspend fun insert(vararg ticket: Ticket) : List<Long>
@Update @Update
suspend fun update(ticket: Ticket) 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 import ru.ulstu.`is`.airticketrentservice.database.models.Ticket
class OfflineTicketRepository(private val ticketDao: TicketDao) : TicketRepository { 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 updateTicket(ticket: Ticket) = ticketDao.update(ticket)
override suspend fun deleteTicket(ticket: Ticket) = ticketDao.delete(ticket) override suspend fun deleteTicket(ticket: Ticket) = ticketDao.delete(ticket)
override suspend fun getAllTickets(): List<Ticket> = ticketDao.getAll() 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) override suspend fun getFlightsTickets(flightId: Int): List<Ticket> = ticketDao.getFlightsTickets(flightId)
suspend fun clearTickets() = ticketDao.deleteAll() suspend fun clearTickets() = ticketDao.deleteAll()
suspend fun insertTickets(tickets: List<Ticket>) = 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 import ru.ulstu.`is`.airticketrentservice.database.models.Ticket
interface TicketRepository { interface TicketRepository {
suspend fun insertTicket(ticket: Ticket) suspend fun insertTicket(ticket: Ticket) : Long
suspend fun updateTicket(ticket: Ticket) suspend fun updateTicket(ticket: Ticket)
suspend fun deleteTicket(ticket: Ticket) suspend fun deleteTicket(ticket: Ticket)
suspend fun getAllTickets(): List<Ticket> suspend fun getAllTickets(): List<Ticket>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,71 +1,174 @@
package ru.ulstu.`is`.airticketrentservice.screen 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.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableDoubleStateOf import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.ulstu.`is`.airticketrentservice.R 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.navigation.BottomBarScreen
import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider 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.FlightEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightUiState 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.TicketDetails
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketUiState import ru.ulstu.`is`.airticketrentservice.viewModel.TicketUiState
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketViewViewModel import ru.ulstu.`is`.airticketrentservice.viewModel.TicketViewViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.toTicket
@Composable @Composable
fun TicketView( fun TicketView(
navController: NavController, navController: NavController,
currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
viewModel: TicketViewViewModel = 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() val coroutineScope = rememberCoroutineScope()
//flightViewModel.setCurrentFlight(viewModel.ticketUiState.ticketDetails.flightId) flightViewModel.setCurrentDropDownFlight(viewModel.flightId)
val totalCost by remember { mutableDoubleStateOf(flightViewModel.flightUiState.flightDetails.one_ticket_cost * viewModel.ticketUiState.ticketDetails.passengers_count.toDouble()) } val currentUser by remember { mutableStateOf(currentUserViewModel.user) }
TicketEdit( TicketEdit(
ticketUiState = viewModel.ticketUiState, ticketUiState = viewModel.ticketUiState,
flightUiState = flightViewModel.flightUiState, flightUiState = flightViewModel.flightDropDownUiState,
onClick = { onClick = {
coroutineScope.launch { coroutineScope.launch {
viewModel.saveTicket() Log.d("TicketView", "Текущий пользователь: $currentUser")
navController.navigate(BottomBarScreen.RentEdit.passId(0.toString())) 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, onUpdate = viewModel::updateUiState
totalCost = totalCost
) )
} }
@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) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TicketEdit( private fun TicketEdit(
ticketUiState: TicketUiState, ticketUiState: TicketUiState,
flightUiState: FlightUiState, flightUiState: FlightDropDownUiState,
onClick: () -> Unit, onClick: () -> Unit,
onUpdate: (TicketDetails) -> Unit, onUpdate: (TicketDetails) -> Unit
totalCost: Double
) { ) {
//ticketUiState.ticketDetails.ticket_cost = totalCost
Column( Column(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
@ -74,92 +177,32 @@ private fun TicketEdit(
.padding(vertical = 32.dp), .padding(vertical = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
TextField(
modifier = Modifier FlightView(flightUiState = flightUiState)
.fillMaxWidth() val passengersCount by derivedStateOf {
.padding(10.dp), ticketUiState.ticketDetails.passengers_count
value = flightUiState.flightDetails.direction_from, }
onValueChange = {}, val oneTicketCost by derivedStateOf {
colors = TextFieldDefaults.textFieldColors( flightUiState.flight?.one_ticket_cost ?: 0
containerColor = Color.LightGray.copy(.2f), }
unfocusedIndicatorColor = Color.Transparent, val totalCost by derivedStateOf {
focusedIndicatorColor = Color.Transparent passengersCount * oneTicketCost.toDouble()
), }
shape = RoundedCornerShape(15.dp), val ticketCost = remember { mutableDoubleStateOf(totalCost) }
label = { Text(stringResource(id = R.string.ticket_from)) },
singleLine = true, Log.d("TicketView", "Текущий рейс: ${flightUiState.flight}")
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
)
TextField( TextField(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(10.dp), .padding(10.dp),
value = ticketUiState.ticketDetails.passengers_count.toString(), 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( colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f), containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent,
@ -167,27 +210,33 @@ private fun TicketEdit(
), ),
shape = RoundedCornerShape(15.dp), shape = RoundedCornerShape(15.dp),
label = { Text("Количество пассажиров") }, 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( TextField(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(10.dp), .padding(10.dp),
value = totalCost.toString(), value = ticketCost.doubleValue.toString(),
onValueChange = {}, onValueChange = {
onUpdate(ticketUiState.ticketDetails.copy(ticket_cost = it.toDouble()))
},
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.textFieldColors(
containerColor = Color.LightGray.copy(.2f), containerColor = Color.LightGray.copy(.2f),
unfocusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent focusedIndicatorColor = Color.Transparent
), ),
shape = RoundedCornerShape(15.dp), shape = RoundedCornerShape(15.dp),
label = { Text("Стоимость за всех пассажиров") }, label = { Text("Стоимость билета за всех пассажиров") },
singleLine = true, singleLine = true,
readOnly = true readOnly = true
) )
Button( Button(
onClick = onClick, onClick = onClick,
enabled = ticketUiState.isEntryValid,
elevation = ButtonDefaults.buttonElevation( elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp, defaultElevation = 10.dp,
pressedElevation = 6.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.CurrentUserViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.RegistrationViewModel import ru.ulstu.`is`.airticketrentservice.viewModel.RegistrationViewModel
import ru.ulstu.`is`.airticketrentservice.R 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.elements.ValidateEmail
import ru.ulstu.`is`.airticketrentservice.graphs.AuthScreen import ru.ulstu.`is`.airticketrentservice.graphs.AuthScreen
import ru.ulstu.`is`.airticketrentservice.graphs.Graph import ru.ulstu.`is`.airticketrentservice.graphs.Graph
@ -222,20 +223,6 @@ fun Registration(navController: NavController, modifier: Modifier = Modifier, re
} }
) )
ValidateEmail(emailValue) { emailValue = it } 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 TextField(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(all = 10.dp), .padding(all = 10.dp),
@ -286,7 +273,7 @@ fun Registration(navController: NavController, modifier: Modifier = Modifier, re
} }
} }
if (!isExist) { 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 { coroutineScope.launch {
val insertResult = async { val insertResult = async {
registrationViewModel.insertUser(newUser) registrationViewModel.insertUser(newUser)

View File

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

View File

@ -24,15 +24,15 @@ class RentEditViewModel(
init { init {
viewModelScope.launch { viewModelScope.launch {
val rent = if (rentUid > 0) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val rent = rentRepository.getRentById(rentUid) rentRepository.getRentById(rentUid).toUiState(true)
.toUiState(true) }
launch(Dispatchers.Main) { } else {
if (rentUid > 0) { null
}
if (rent != null) {
rentUiState = rent 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 { private fun validateInput(uiState: RentDetails = rentUiState.rentDetails): Boolean {
return with(uiState) { 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) { fun setCurrentTicket(ticketId: Int) {
val ticket: Ticket? = val ticket: Ticket? =
ticketsListUiState.ticketList.firstOrNull { ticket -> ticket.id == ticketId } ticketsListUiState.ticketList.firstOrNull { ticket -> ticket.id == ticketId }
@ -129,6 +102,13 @@ fun TicketDetails.toTicket(uid: Int = 0): Ticket = Ticket(
flightId = flightId 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( fun Ticket.toDetails(): TicketDetails = TicketDetails(
passengers_count = passengers_count, passengers_count = passengers_count,
ticket_cost = ticket_cost, ticket_cost = ticket_cost,

View File

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

View File

@ -8,9 +8,129 @@
}, },
{ {
"id": 2, "id": 2,
"passengers_count": 3, "passengers_count": 2,
"ticket_cost": 2435, "ticket_cost": 4870,
"flightId": 5 "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": [ "flights": [
@ -87,7 +207,7 @@
"date_of_birth": "7-11-2003", "date_of_birth": "7-11-2003",
"email": "usertt@mail.ru", "email": "usertt@mail.ru",
"password": "usertt", "password": "usertt",
"role": "user" "role": "User"
}, },
{ {
"surname": "а", "surname": "а",
@ -96,7 +216,7 @@
"date_of_birth": "17-5-2000", "date_of_birth": "17-5-2000",
"email": "user@mail.ru", "email": "user@mail.ru",
"password": "user", "password": "user",
"role": "user", "role": "User",
"id": 3 "id": 3
}, },
{ {
@ -106,7 +226,7 @@
"date_of_birth": "10-12-2015", "date_of_birth": "10-12-2015",
"email": "aaa@mail.ru", "email": "aaa@mail.ru",
"password": "aaa", "password": "aaa",
"role": "user", "role": "User",
"id": 4 "id": 4
}, },
{ {
@ -116,7 +236,7 @@
"date_of_birth": "10-12-2015", "date_of_birth": "10-12-2015",
"email": "aa@mail.ru", "email": "aa@mail.ru",
"password": "aaa", "password": "aaa",
"role": "user", "role": "User",
"id": 5 "id": 5
}, },
{ {
@ -126,7 +246,7 @@
"date_of_birth": "7-5-2005", "date_of_birth": "7-5-2005",
"email": "userff@mail.ru", "email": "userff@mail.ru",
"password": "password", "password": "password",
"role": "user", "role": "User",
"id": 6 "id": 6
}, },
{ {
@ -136,8 +256,18 @@
"date_of_birth": "23-12-2011", "date_of_birth": "23-12-2011",
"email": "kkk@mail.ru", "email": "kkk@mail.ru",
"password": "kkk", "password": "kkk",
"role": "user", "role": "User",
"id": 7 "id": 7
},
{
"id": 8,
"surname": "Артамонова",
"name": "Татьяна",
"patronymic": "Валерьевна",
"date_of_birth": "7-11-2003",
"email": "admin@mail.ru",
"password": "admin",
"role": "Admin"
} }
], ],
"rents": [ "rents": [
@ -152,6 +282,18 @@
"status": "Подтверждено", "status": "Подтверждено",
"userId": 2, "userId": 2,
"ticketId": 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, "id": 2,
"passengers_count": 1, "passengers_count": 2,
"ticket_cost": 2435, "ticket_cost": 4870,
"flightId": 5 "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": [ "flights": [
@ -42,13 +156,13 @@
"one_ticket_cost": 2680 "one_ticket_cost": 2680
}, },
{ {
"id": 7,
"direction_from": "Хабаровск", "direction_from": "Хабаровск",
"direction_to": "Кострома", "direction_to": "Кострома",
"departure_date": "5-1-2024", "departure_date": "5-1-2024",
"arrival_date": "5-1-2024", "arrival_date": "5-1-2024",
"tickets_count": 200, "tickets_count": 200,
"one_ticket_cost": 6870, "one_ticket_cost": 6870
"id": 7
}, },
{ {
"direction_from": "Астрахань", "direction_from": "Астрахань",
@ -87,7 +201,7 @@
"date_of_birth": "7-11-2003", "date_of_birth": "7-11-2003",
"email": "usertt@mail.ru", "email": "usertt@mail.ru",
"password": "usertt", "password": "usertt",
"role": "user" "role": "Admin"
}, },
{ {
"surname": "а", "surname": "а",
@ -96,7 +210,7 @@
"date_of_birth": "17-5-2000", "date_of_birth": "17-5-2000",
"email": "user@mail.ru", "email": "user@mail.ru",
"password": "user", "password": "user",
"role": "user", "role": "User",
"id": 3 "id": 3
}, },
{ {
@ -106,7 +220,7 @@
"date_of_birth": "10-12-2015", "date_of_birth": "10-12-2015",
"email": "aaa@mail.ru", "email": "aaa@mail.ru",
"password": "aaa", "password": "aaa",
"role": "user", "role": "User",
"id": 4 "id": 4
}, },
{ {
@ -116,7 +230,7 @@
"date_of_birth": "10-12-2015", "date_of_birth": "10-12-2015",
"email": "aa@mail.ru", "email": "aa@mail.ru",
"password": "aaa", "password": "aaa",
"role": "user", "role": "User",
"id": 5 "id": 5
}, },
{ {
@ -126,7 +240,7 @@
"date_of_birth": "7-5-2005", "date_of_birth": "7-5-2005",
"email": "userff@mail.ru", "email": "userff@mail.ru",
"password": "password", "password": "password",
"role": "user", "role": "User",
"id": 6 "id": 6
}, },
{ {
@ -136,7 +250,7 @@
"date_of_birth": "23-12-2011", "date_of_birth": "23-12-2011",
"email": "kkk@mail.ru", "email": "kkk@mail.ru",
"password": "kkk", "password": "kkk",
"role": "user", "role": "User",
"id": 7 "id": 7
} }
], ],
@ -152,6 +266,12 @@
"status": "Подтверждено", "status": "Подтверждено",
"userId": 2, "userId": 2,
"ticketId": 2 "ticketId": 2
},
{
"status": "Ожидает подтверждения",
"userId": 2,
"ticketId": 21,
"id": 3
} }
] ]
} }