Рисунок 3.9 - Раздел «мои билеты» в личном кабинете пользователя
Заказать билеты на выбранный киносеанс можно войдя в раздел афиши, в котором выводится полная информация о сеансах, после чего выбрать требуется кинотеатр, после чего нажав на нужный соответствующий сеанс 2 раза откроется раздел «оформление заказа», в котором имеется схема расположения зала и выбор категории ряда (1,2 или 3) и сумма к оплате (рисунок 3.10).
Рисунок 3.10 - Окно заказа билетов
Пользователю предоставляется возможность отменять заказ. Для отмены заказанных билетов необходимо выбрать отменяемый заказ в поле «Мои билеты» и нажать кнопку «Удалить».
Рисунок 3.11 - Окно заказанных билетов
При нажатии на кнопку выход в разделах пользователь и администратор, происходит переход на страницу гостя (стартовую страницу) (рисунок 3.12).
Рисунок 3.12 - главное окно гостя
Кроме обычного пользователя в системе существуют пользователи с правами доступа администратора и гостя. Каждый из них выполняют свою функцию.
Администратор выполняет следующие функции:
- создание и изменение информации о фильмах, кинотеатрах, сеансах;
- добавление билетов;
- просматривать отчеты о популярности фильмов;
- просматривать отчеты о кассовых сборах;
- просматривать отчеты о и среднем числе посетителей кинотеатров;
- выводить отчеты в xml.
Для выполнений функций администратора, необходимо зайти в систему под пользователем, у которого есть права администратора. После входа в аккаунт под администратором появятся дополнительные кнопки для переходов по разделам «администратора»: разделы «добавление фильма», «добавление билета», «просмотр отчетов» (рисунок 3.13).
Рисунок 3.13 - Доступные разделы в кабинете администратора.
В разделе «добавление фильма» администратор может добавлять фильм, для этого требуется заполнить формы «названия фильма», «стоимость», «описание», «длительность» в соответствии с требуемым фильмом(рисунок 3.14).
Рисунок 3.14 - Раздел «добавление фильма»
В разделе «добавление билета» администратор может добавлять билеты в любой из существующих кинотеатров города. Для этого требуется выбрать из списка «фильм», «кинотеатр», и поле «Дата и время» заполнить данными (рисунок 3.14). Одно из установленных правил: сеанс не может проходить в день создания данных о сеансе и ранее. Должен пройти как минимум день после создания сеанса. Это же правило распространяется на изменение данных о сеансе. В случае несоблюдения данного правила система не позволяет сохранить изменения.
Администратору также доступны просмотры отчетов с последующим сохранением их в XML-файлы по «популярности фильмов», по «кассовым сборам» «по фильмам», по «среднему числу посетителей», как показано на рисунках 3.12, 3.13 и 3.14.
Рисунок 3.15 - Просмотр отчетов по «Популярным фильмам»
Рисунок 3.16 - Просмотр отчетов по «кассовым сборам»
Рисунок 3.17 - Просмотр отчетов по «среднему числу посетителей кинотеатров»
Рисунок 3.15 - Сохранение в XML отчета по «среднему числу посетителей»
Кроме зарегистрированных пользователей, просмотр афиши кинотеатров доступен при гостевом входе в систему. Вход под ролью «Гость» осуществляется при запуске программы. У «Гостя» есть возможность просматривать афиши по каждому кинотеатру города, а также регистрироваться для того, чтобы приобрести билет на сеанс (рисунок 3.10) и авторизироваться под уже имеющимися учетными записями.
Рисунок 3.17 - Главное окно гостя с выбором просмотра афиши по кинотеатрам
3.2 Результаты проведения модульного тестирования
После реализации основного функционала приложения, проведено модульное тестирование. А именно тестирование взаимодействия с базой данных на возникновения исключений, получение данных, добавления, обновления и редактирования данных. На рисунке 3.1 приведены результаты проведения модульного тестирования.
Рисунок 3.1 - Результат выполнения модульного тестирования
Модульное тестирование выполнено с помощью пакета NUnit, листинг классов с модульными тестами находится в приложении В.
На рисунке 3.2 приведена иерархия созданных классов для модульного тестирования.
Рисунок 3.2 - Иерархия классов Unit тестов
информационная система билет кинотеатр
По итогу проведения модульного тестирования можно удостоверится в том, что классы, обеспечивающие связь базы данных и приложения, работают корректно и выполняют возложенные на них функции.
ЗАКЛЮЧЕНИЕ
Для реализации информационной системы для реализации билетов на киносеансы в кинотеатры города создана программа, взаимодействующая с базой данных для хранения и получения информации обработки и её анализа. Программа имеет средства, предоставляющие пользователем взаимодействовать с ней и получать определённую информацию о системе. Также созданное приложение автоматизирует работу информационной системы по учёту данных и предоставляет отчёты с возможностью их сохранения в XML-формате для последующего открытия в электронных таблицах.
Для создания приложения использовался язык программирования C# и платформа.NET Framework, который взаимодействует с СУБД MySQL.
Так как приложение реализовано с помощью различных шаблонов проектирования, разбита на модули тем самым является легко масштабируемым. В зависимости от требований может расширяться путём добавлений нового функционала, усовершенствоваться и поддерживаться сторонним разработчиком. Так же может быть перенесено на другую платформу поддерживающих.NET Framework реализующих другие средства графического представления.
СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ
1. Практическое руководство к курсовому проектированию по курсу «Информатика» для студентов технических специальностей дневной и заочной форм обучения - Гомель: ГГТУ им. П.О. Сухого, 2019. - 32 с.
2. Мухортов В.В., Рылов В.Ю. Объектно-ориентированное программирование, анализ и дизайн: Методическое пособие. - Новосибирск, издательство «ИМ СО РАН», 2002. - 108 с.
3. Шилдт Герберт. C# 4.0: полное руководство: учебное пособие - ООО «И.Д. Вильямс», 2011. - 1056 с.
4. Рихтер Джеффри. CLR via C#. Программирование на платформе Microsoft.NETFramework 4.5 на языке C# - ООО Издательство «Питер», 2013. - 896 с.
5. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж., Приемы объектно-ориентированного программирования. Паттерны проектирования. - Спб.: Питер, 2015. - 368 с.
6. Албахари, Д. C# 7.0. Карманный справочник /Д. Албахари, Б. Албахари. - СПб.: ООО «Альфа-книга», 2017. - 224 c.
ПРИЛОЖЕНИЕ Б
(обязательное)
Код программы
User.xaml.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using CourseWorkProject_OOP.Models.Entity;
using MySql.Data.MySqlClient;
namespace CourseWorkProject_OOP
{
/// <summary>
/// Логика взаимодействия для MainWindowUser.xaml
/// </summary>
public partial class User: Window
{
private int userId;
public User(int userId)
{
InitializeComponent();
this.userId = userId;
command = new MySqlCommand("SELECT * FROM tikets.cinema", db.GetConnection());
table = new DataTable();
adapter.SelectCommand = command;
adapter.Fill(table);
foreach (var item in table.Select())
{
cinema.Add(new Cinema(Convert.ToInt32(item.ItemArray[0]), item.ItemArray[1].ToString(), Convert.ToInt32(item.ItemArray[2]),
Convert.ToInt32(item.ItemArray[3]), Convert.ToInt32(item.ItemArray[4]), item.ItemArray[5].ToString()));
}
foreach (var item in cinema)
{
cinemaBox.Items.Add(item.Name);
cinemaBox.SelectedItem = item.Name;
}
getTickets();
}
DB db = new DB();
DataTable table;
MySqlDataAdapter adapter = new MySqlDataAdapter();
List<Cinema> cinema = new List<Cinema>();
List<Ticket> tickets = new List<Ticket>();
List<Sale> sales = new List<Sale>();
MySqlCommand command;
private void getTickets()
{
string selectedCinema = cinemaBox.SelectedItem!= null ? cinemaBox.SelectedItem.ToString(): "";
int selectedId = 1;
foreach (var item in cinema)
{
if (selectedCinema.Equals(item.Name))
selectedId = item.CinemaId;
}
tickets = new List<Ticket>();
command = new MySqlCommand("Select tik.ticket_id, tik.cinema_id, tik.time_seans, fil.film_id, fil.name, fil.description, " +
"fil.cost, fil.length " +
"From tikets.ticket as tik INNER JOIN tikets.film as fil ON tik.film_id = fil.film_id " +
"Where tik.cinema_id = " + selectedId
, db.GetConnection());
table = new DataTable();
adapter.SelectCommand = command;
adapter.Fill(table);
foreach (var item in table.Select())
{
tickets.Add(new Ticket(
Convert.ToInt32(item.ItemArray[0]),
Convert.ToInt32(item.ItemArray[1]),
selectedCinema,
Convert.ToDateTime(item.ItemArray[2]),
Convert.ToInt32(item.ItemArray[3]),
item.ItemArray[4].ToString(),
item.ItemArray[5].ToString(),
"от " + item.ItemArray[6].ToString() + "р.",
Convert.ToInt32(item.ItemArray[7])));
}
filmsGrid.ItemsSource = tickets;
}
private void cinemaBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
getTickets();
}
private void myTickets_Click(object sender, RoutedEventArgs e)
{
cinemaBox.Visibility = Visibility.Hidden;
filmsGrid.ItemsSource = null;
sales = new List<Sale>();
command = new MySqlCommand("Select sal.price, sal.date_sale, cin.name, tik.time_seans, fil.name, fil.description " +
"From tikets.sale as sal " +
"INNER JOIN tikets.ticket as tik ON sal.ticket_id = tik.ticket_id " +
"INNER JOIN tikets.film as fil ON tik.film_id = fil.film_id " +
"INNER JOIN tikets.cinema as cin ON cin.cinema_id = tik.cinema_id " +
"Where sal.user_id = " + userId
, db.GetConnection());
table = new DataTable();
adapter.SelectCommand = command;
adapter.Fill(table);
foreach (var item in table.Select())
{
sales.Add(new Sale(
Convert.ToDouble(item.ItemArray[0]),
Convert.ToDateTime(item.ItemArray[1]),
item.ItemArray[2].ToString(),
Convert.ToDateTime(item.ItemArray[3]),
item.ItemArray[4].ToString(),
item.ItemArray[5].ToString()));
}
filmsGrid.ItemsSource = sales;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
cinemaBox.Visibility = Visibility.Visible;
filmsGrid.ItemsSource = tickets;
}
private void exit_Click(object sender, RoutedEventArgs e)
{
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
Close();
}
private void filmsGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
BronTickets bronTickets = new BronTickets(tickets.ElementAt(filmsGrid.SelectedIndex).TiketId, userId);
bronTickets.Show();
}
}
}
RegisterForm.xaml.cs
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace CourseWorkProject_OOP
{
/// <summary>
/// Логика взаимодействия для RegisterForm.xaml
/// </summary>
public partial class RegisterForm: Window
{
public RegisterForm()
{
InitializeComponent();
}
/// <summary>
///Регистрация нового пользователя
/// </summary>
public bool isLogin = true;
private void regUser_Click(object sender, RoutedEventArgs e)
{
if (loginField.Text == "" || passwordField.Text == "" || fullNameField.Text == "" || birthYearField.Text == "")
{
MessageBox.Show("Вы ввели не все данные!");
return;
}
if (IsUserExists())
return;
DB db = new DB();
MySqlCommand command = new MySqlCommand("INSERT INTO users (login, password, fullname, birth_year, role) VALUES (@login, @password, @fullname, @birth_year, @role)", db.GetConnection());
command.Parameters.Add("@login", MySqlDbType.VarChar).Value = loginField.Text;
command.Parameters.Add("@password", MySqlDbType.VarChar).Value = passwordField.Text;
command.Parameters.Add("@fullname", MySqlDbType.VarChar).Value = fullNameField.Text;
command.Parameters.Add("@birth_year", MySqlDbType.VarChar).Value = birthYearField.Text;
command.Parameters.Add("@role", MySqlDbType.VarChar).Value = "user";
db.openConnection();
if (command.ExecuteNonQuery() == 1)
{
MessageBox.Show("Аккаунт был создан");
loginField.Text = "";
passwordField.Text = "";
fullNameField.Text = "";
birthYearField.Text = "";
}
else
MessageBox.Show("Аккаунт не был создан");
db.closedConnection();
}
/// <summary>
/// Авторизация по логину и паролю
/// </summary>
/// <returns></returns>
public Boolean IsUserExists()
{
DB db = new DB();
DataTable table = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand command = new MySqlCommand("SELECT * FROM users WHERE login = @uL", db.GetConnection());
command.Parameters.Add(new MySqlParameter("@ul", loginField.Text));
adapter.SelectCommand = command;
adapter.Fill(table);
//проверка колличества найденных записей
if (table.Rows.Count > 0)
{
MessageBox.Show("Такой логин уже есть в системе, введите другой!");
return true;
}
else
return false;
}
/// <summary>
/// нажатие на кнопку8
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RegisterLabel_Click(object sender, RoutedEventArgs e)
{
LoginForm loginForm = new LoginForm();
loginForm.Show();
isLogin = false;
Close();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (isLogin)
new MainWindow().Show();
}
}
}
MainWindow.xaml.cs
using CourseWorkProject_OOP.Models.Entity;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Windows;
using System.Windows.Controls;
namespace CourseWorkProject_OOP
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow: Window
{
DB db = new DB();
DataTable table;
MySqlDataAdapter adapter = new MySqlDataAdapter();
List<Cinema> cinema = new List<Cinema>();
List<Ticket> tickets = new List<Ticket>();
MySqlCommand command;
/// <summary>
/// Метод вывода таблицы афиш для каждого кинотеаатра
/// </summary>
public MainWindow()
{
InitializeComponent();
command = new MySqlCommand("SELECT * FROM tikets.cinema", db.GetConnection());
table = new DataTable();
adapter.SelectCommand = command;
adapter.Fill(table);
foreach (var item in table.Select())
{
cinema.Add(new Cinema(Convert.ToInt32(item.ItemArray[0]), item.ItemArray[1].ToString(), Convert.ToInt32(item.ItemArray[2]),
Convert.ToInt32(item.ItemArray[3]), Convert.ToInt32(item.ItemArray[4]), item.ItemArray[5].ToString()));
}
foreach (var item in cinema)
{
cinemaComboBox.Items.Add(item.Name);
}
}
//обработчик события (нажатие на кнопку РЕГИСТРАЦИЯ на главной странице)
private void RegButton_Click(object sender, RoutedEventArgs e)
{
RegisterForm regForm = new RegisterForm();
regForm.Owner = this;
regForm.ShowDialog();
Close();
}
//обработчик события (нажатие на кнопку ВХОД на главной странице)
private void SignInButton_Click(object sender, RoutedEventArgs e)
{
new LoginForm().Show();
Close();