Скачиваний:
1
Добавлен:
12.04.2025
Размер:
8.45 Mб
Скачать

Фильтрация данных

Разработана страница поиска туров с фильтрацией по типу тура, стране, по типу и стране (Рисунок 25-27).

Рисунок 25- Разметка страницы Поиск туров

Рисунок 26- Настройка источника данных для GridView

Листинг 5- Функции для обработки нажатий на кнопки

protected void Button1_Click(object sender, EventArgs e)

{

string type = DropDownList1.SelectedValue;

SqlDataSource1.SelectCommand = GetSqlCommand(type, null);

GridView1.DataBind();

}

protected void Button2_Click(object sender, EventArgs e)

{

string country = DropDownList2.SelectedValue;

SqlDataSource1.SelectCommand = GetSqlCommand(null, country);

GridView1.DataBind();

}

protected void Button3_Click(object sender, EventArgs e)

{

string type = DropDownList1.SelectedValue;

string country = DropDownList2.SelectedValue;

SqlDataSource1.SelectCommand = GetSqlCommand(type, country);

GridView1.DataBind();

}

Листинг 6- Генерация SQL-запрос для фильтрации туров на основе типа и страны

private string GetSqlCommand(string type, string country)

{

string sql = @"SELECT

Tour.Tour_ID AS 'TourID',

Tour.Name_T AS 'Tour Name',

Tour.Description_T AS 'Description',

Tour.Duration_T AS 'Duration',

Type_T.Name_T AS 'Tour Type',

Season.Name_Season AS 'Season',

Hotel.Name_H AS 'Hotel Name',

Locality.Name_L AS 'Route Locality',

Locality.Country AS 'Country',

Image.FilePath AS 'Image Path'

FROM

Tour

JOIN

Type_T ON Tour.TypeT_ID = Type_T.TypeT_ID

JOIN

TourSeason ON Tour.Tour_ID = TourSeason.Tour_ID

JOIN

Season ON TourSeason.Season_ID = Season.Season_ID

JOIN

TourHotel ON Tour.Tour_ID = TourHotel.Tour_ID

JOIN

Hotel ON TourHotel.Hotel_ID = Hotel.Hotel_ID

JOIN

Route ON Tour.Tour_ID = Route.Tour_ID

JOIN

Locality ON Route.Locality_ID = Locality.Locality_ID

LEFT JOIN

ImageTour ON Tour.Tour_ID = ImageTour.TourID

LEFT JOIN

Image ON ImageTour.ImageID = Image.ImageID";

SqlDataSource1.SelectParameters.Clear();

if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(country))

{

sql += " WHERE Type_T.Name_T = @Type AND Locality.Country = @Country";

SqlDataSource1.SelectParameters.Add(new Parameter("Type", DbType.String, type));

SqlDataSource1.SelectParameters.Add(new Parameter("Country", DbType.String, country));

}

else if (!string.IsNullOrEmpty(type))

{

sql += " WHERE Type_T.Name_T = @Type";

SqlDataSource1.SelectParameters.Add(new Parameter("Type", DbType.String, type));

}

else if (!string.IsNullOrEmpty(country))

{

sql += " WHERE Locality.Country = @Country";

SqlDataSource1.SelectParameters.Add(new Parameter("Country", DbType.String, country));

}

return sql;

}

Рисунок 27- Страница Поиск туров

На рисунках 28-29 показана работа фильтрации.

Рисунок 28- Применение фильтрации по типу тура

Рисунок 29- Применение фильтрации по типу и стране

При нажатии на Выбор пользователь может открыть страницу тура для просмотра более подробной информации о туре. Написана функция GridView1_SelectedIndexChanged, которая получает идентификатор выбранного тура и перенаправляет пользователя на страницу с подробной информацией, передавая идентификатор в качестве параметра в URL.

Листинг 7- Функция обработки нажатия кнопки для просмотра подробной информации о туре

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)

{

int selectedTourID = Convert.ToInt32(GridView1.SelectedDataKey.Value);

Response.Redirect($"TourDetails.aspx?TourID={selectedTourID}");

Листинг 8- Функция отображения подробной информации о туре

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

string tourID = Request.QueryString["TourID"];

if (!string.IsNullOrEmpty(tourID))

{

DataTable tourDetails = GetTourDetails(tourID);

if (tourDetails.Rows.Count > 0)

{

DataRow row = tourDetails.Rows[0];

TourNameLabel.Text = row["TourName"].ToString();

DescriptionLabel.Text = row["Description"].ToString();

DurationLabel.Text = row["Duration"].ToString();

SeasonLabel.Text = row["Season"].ToString();

HotelNameLabel.Text = row["HotelName"].ToString();

LocalityLabel.Text = row["Locality"].ToString();

CountryLabel.Text = row["Country"].ToString();

string imagePath = row["ImagePath"].ToString();

}

}

}

Далее создана возможность оформления заказа пользователем. На странице тура есть возможно выбора дат для путешествия и проверки количества доступных путевок (Рисунок 30). При выборе дат и количества путевок пользователь получает сообщение о доступности или отсутствии путевок (Рисунок 31-32).

Рисунок 30- Страница тура и выбора дат

Рисунок 31 - Получение сообщения о доступности поездки

Рисунок 32- Сообщение о недоступности мест

Листинг 9- Функция для проверки доступности мест для бронирования на выбранную дату

protected void CheckAvailabilityButton_Click(object sender, EventArgs e)

{

string tourID = Request.QueryString["TourID"];

string startDate = StartDateTextBox.Text;

if (!int.TryParse(TicketCountTextBox.Text, out int ticketsRequested) || ticketsRequested <= 0)

{

AvailabilityLabel.Text = "Введите корректное количество путевок.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

return;

}

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["travelConnectionString4"].ConnectionString;

using (SqlConnection conn = new SqlConnection(connectionString))

{

string query = @"SELECT TripCount FROM Trip WHERE Tour_ID = @TourID AND StartDate = @StartDate";

using (SqlCommand cmd = new SqlCommand(query, conn))

{

cmd.Parameters.AddWithValue("@TourID", tourID);

cmd.Parameters.AddWithValue("@StartDate", startDate);

conn.Open();

object result = cmd.ExecuteScalar();

if (result != null && int.TryParse(result.ToString(), out int availableTickets))

{

if (availableTickets >= ticketsRequested)

{

AvailabilityLabel.Text = "Достаточно мест для бронирования.";

AvailabilityLabel.CssClass = "success";

OrderButton.Visible = true;

}

else

{

AvailabilityLabel.Text = "Недостаточно мест для бронирования.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

}

}

else

{

AvailabilityLabel.Text = "Нет данных для выбранной даты.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

}

}

}

}

При нажатии на кнопку «Перейти к оформлению заказа» открывается форма для заполнения данных пассажиров (Рисунок 33). В зависимости от количества путевок создаются текстовые поля и метки для ввода информации о пассажирах. Также рассчитывается общая стоимость тура, умножая цену одной путевки на количество путевок (Листинг 10).

Рисунок 33- Подробная информация о туре

Листинг 10- Функция расчета стоимости

private void CalculateTotalPrice(string tourID, int ticketsCount)

{

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["travelConnectionString4"].ConnectionString;

try

{

using (SqlConnection conn = new SqlConnection(connectionString))

{ string query = @"SELECT Price FROM Trip WHERE Tour_ID = @TourID AND StartDate = @StartDate";

using (SqlCommand cmd = new SqlCommand(query, conn))

{

cmd.Parameters.AddWithValue("@TourID", tourID);

cmd.Parameters.AddWithValue("@StartDate", DateTime.Parse(StartDateLabel.Text));

conn.Open();

object result = cmd.ExecuteScalar();

if (result != null)

{

decimal pricePerTicket = Convert.ToDecimal(result);

decimal totalPrice = pricePerTicket * ticketsCount;

TotalPriceLabel.Text = $"Общая стоимость: {totalPrice:C}"; // Выводим стоимость

}

else

{

ErrorMessage.Text = "Ошибка: Цена не найдена.";

}

}

}

}

catch (Exception ex)

{

ErrorMessage.Text = $"Ошибка расчета стоимости: {ex.Message}";

}

}

При правильно заполненных данных, создается запись в таблице Заказ (Листинг 11), а в таблицу с путевками заносятся данные о пассажирах, которые привязаны к путевке (Листинг 12). Также при оформлении заказа, уменьшается количество доступных путевок (Листинг 13) (Рисунок 34-37).

Рисунок 34- Таблица с доступными путевками до оформления заказа

Рисунок 35- Успешное оформление заказа

Рисунок 36- Таблица с доступными путевками после оформления заказа

Рисунок 37- Таблицами с путевками

Листинг 11- Функция для создания записи в таблице с заказами

private int InsertOrder(SqlConnection conn, SqlTransaction transaction, int tripID, int ticketsCount)

{

string query = @"

INSERT INTO Order_data (OrderDate, Client_ID, PeopleCount, Trip_ID)

OUTPUT INSERTED.Order_ID

VALUES (GETDATE(), @ClientID, @PeopleCount, @TripID)";

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@ClientID", Session["UserId"]);

cmd.Parameters.AddWithValue("@PeopleCount", ticketsCount);

cmd.Parameters.AddWithValue("@TripID", tripID);

return (int)cmd.ExecuteScalar();

}

}

Листинг 12 – Добавление оформленных путевок в таблицу с путевками

private void AddPassengers(SqlConnection conn, SqlTransaction transaction, int orderID, int ticketsCount)

{

string query = @"

INSERT INTO Permit (Order_ID, LastName, FirstName, MiddleName, DOB)

VALUES (@OrderID, @LastName, @FirstName, @MiddleName, @DOB)";

for (int i = 1; i <= ticketsCount; i++)

{

string passengerName = ((TextBox)PassengersPanel.FindControl($"PassengerName_{i}"))?.Text;

string passengerDOB = ((TextBox)PassengersPanel.FindControl($"PassengerDOB_{i}"))?.Text;

string[] nameParts = passengerName?.Split(' ');

if (nameParts == null || nameParts.Length < 2)

{

throw new Exception($"Ошибка в данных пассажира {i}. Укажите ФИО в формате: 'Фамилия Имя Отчество'.");

}

string lastName = nameParts[0];

string firstName = nameParts[1];

string middleName = nameParts.Length > 2 ? nameParts[2] : "";

if (string.IsNullOrEmpty(passengerDOB) || !DateTime.TryParse(passengerDOB, out DateTime dob))

{

throw new Exception($"Ошибка в данных пассажира {i}. Укажите корректную дату рождения.");

}

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@OrderID", orderID);

cmd.Parameters.AddWithValue("@LastName", lastName);

cmd.Parameters.AddWithValue("@FirstName", firstName);

cmd.Parameters.AddWithValue("@MiddleName", middleName);

cmd.Parameters.AddWithValue("@DOB", dob);

cmd.ExecuteNonQuery();

}

}

}

Листинг 13- Функция уменьшения количества доступных путевок

private void UpdateTripCount(SqlConnection conn, SqlTransaction transaction, int tripID, int ticketsCount)

{

string query = @"

UPDATE Trip

SET TripCount = TripCount - @TicketsCount

WHERE Trip_ID = @TripID";

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@TicketsCount", ticketsCount);

cmd.Parameters.AddWithValue("@TripID", tripID);

cmd.ExecuteNonQuery();

}

}

Также для авторизованного пользователя реализована возможность просмотра истории оформленных заказов (Рисунок 38).

Рисунок 38- Просмотр истории заказов

Соседние файлы в предмете Проектирование информационных систем