Вы находитесь на странице: 1из 45

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ ДНР

ДОНЕЦКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ

Факультет Физико-технический
Кафедра Компьютерных технологий (КТ)

Зав. кафедрой КТ
____________ Т.В.Ермоленко
(подпись)

«___» ____________ 2019 г.

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовой работе бакалавра 3 курса
на тему:

ИНФОРМАЦИОННАЯ СИСТЕМА СЛУЖБЫ ДОСТАВКИ

Автор А.С. Антоник


(подпись)

Направление 09.03.0 Информатика и вычислительная техника


1

Руководитель работы ________________ канд. техн. наук, Шарий Т.В.


подпись

Консультанты по разделам:

Моделирование бизнес-процессов __________________ ст. преп. В.И. Бондаренко


подпись

Проектирование системы __________________ ст. преп. В.И. Бондаренко


подпись

Нормоконтроль __________________ ст. лаборант В.Г. Медведева


подпись

Курсовая работа защищена __________ _____________________


дата итоговая оценка комиссии

Подписи членов комиссии: __________________


__________________
__________________
__________________

Донецк
2019
ГОУ ВПО «Донецкий национальный университет»
кафедра Компьютерных технологий

Утверждаю
Зав. кафедрой
_____________
подпись
_____________
дата

ЗАДАНИЕ

На курсовую работу студента 3 курса А.С. Антоник.


Тема курсовой работы: Информационная система службы доставки.
Краткая постановка задачи: 1. Изучить и проанализировать работу службы доставки.
2. Ознакомиться с программными продуктами службы доставки для обработки баз
данных. 3. Разработать техническое задание на создание программы для работы с базой
данных службы доставки. 4. Разработать проект программного обеспечения системы:
спроектировать структуру входных и выходных данных, классы программы и их
взаимодействие, спроектировать базу данных. 5. Разработать средствами Qt, Python и
Ms Sql Server приложение, которое позволяет обрабатывать информацию таблиц базы
данных, выполнять запросы. 6. Протестировать программное обеспечение. 7. Оформить
отчёт.
Исходные данные: 1. Документация по Microsoft SQL Server Management Studio и Qt
Designer. 2. Информация о службах доставки. 3. Описание языка Python 3. 4. Описание
языка запросов Sql.
Ожидаемые результаты: Информационная система службы доставки
Календарный план работы:
Даты
Отметки о
консультаци Этапы выполнения работы
выполнении
й
10.09.2019 Обсуждение литературы и постановка задачи Выполнен
о
16.09.2019 Предварительное утверждение содержания отчёта выполнено
20.09.2019 Создание бизнес-модели выполнено
30.09.2019 Построение концептуальной, логической, физической выполнено
моделей
15.10.2019 Разработка приложения
20.10.2019 Обсуждения организации тестирования программы выполнено
30.10.2019 Демонстрация программного продукта руководителю выполнено
09.11.2019 Оформление отчёта выполнено
11.11.2019 Предоставление отчёта руководителю выполнено

Дата выдачи задания 10.09.2019 года


Студент А.С. Антоник
Руководитель Т.В. Шарий
АННОТАЦИЯ

Отчёт о курсовой работе: 44 страниц, 18 рисунков, 2 приложения,


7 источников.
Объект исследования – служба доставки.
Предмет исследований – база данных для службы доставки.
Цель работы – разработка приложения, позволяющего вести базу
данных с информацией о доставках.
Метод исследования – анализ возможностей среды Qt для создания
графического интерфейса приложения, возможностей языка
программирования Python для написания основной логики приложения,
возможностей среды Microsoft SQL Server для создания базы данных.
В результате решения задачи спроектирована база данных, которая
будет хранить всю необходимую информацию для работы службы доставки.
Помимо базы данных также будет спроектировано приложение, которое
будет работать с этой базой.
Приложение позволяет хранить информацию о доставках, посылках,
отправителях и получателях, а также о курьерах. Приложение позволяет
оформлять доставки, выбирая способы упаковки, способ доставки.
Приложение может использоваться операторами службы доставки для
формирования доставок от клиентов.
ДОСТАВКИ, КУРЬЕР, SQL-ЗАПРОС, ПОСЫЛКА, БАЗА ДАННЫХ.
4
СОДЕРЖАНИЕ
ВВЕДЕНИЕ..............................................................................................................5
1 АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ................................................................6
1.1 Состояние вопроса........................................................................................6
1.2 Моделирование существующих бизнес-процессов....................................7
1.3 Актуальность и цель работы......................................................................10
2 ТЕХНИЧЕСКОЕ ЗАДАНИЕ.............................................................................12
2.1 Описание области применения и исходных данных приложения..........12
2.2 Требования к пользовательским интерфейсам.........................................12
2.3 Требования к аппаратным, программным и коммуникационным
интерфейсам.......................................................................................................14
2.4 Требования к пользователям продукта......................................................14
2.5 Требования к адаптации на месте..............................................................14
2.6 Функции продукта.......................................................................................15
2.7 Ограничения.................................................................................................16
3 ОБОСНОВАНИЕ ВЫБОРА ИНСТРУМЕНТАЛЬНЫХ СРЕДСТВ..............17
4 РАЗРАБОТКА БАЗЫ ДАННЫХ СЛУЖБЫ ДОСТАВКИ.............................19
4.1 Разработка базы данных приложения.......................................................19
4.1.1 Концептуальное проектирование базы данных.................................19
4.1.2 Логическое проектирование базы данных.........................................20
4.1.3 Физическое проектирование базы данных.........................................21
4.2 Проектирование структуры приложения..................................................25
4.3 Описание классов и методов приложения................................................26
4.4 Описание SQL-запросов к базе данных системы.....................................28
5 ТЕСТИРОВАНИЕ ПРОГРАММНОГО ПРОДУКТА.....................................31
5.1 Аппаратные и программные средства создания и эксплуатации
приложения........................................................................................................31
5.2 Руководство пользователя..........................................................................31
5.3 Описание контрольных примеров..............................................................32
ЗАКЛЮЧЕНИЕ......................................................................................................34
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ............................................35
ПРИЛОЖЕНИЕ А Экранные формы...................................................................36
ПРИЛОЖЕНИЕ Б Фрагменты листинга.............................................................38

ВВЕДЕНИЕ
5

В современном мире любое предприятие стремится к автоматизации


своих процессов, что позволит уменьшить временные затраты и получать
больше прибыли с меньшими нагрузками. Информационные технологии
позволяют быстро и надёжно передавать информацию на большие
расстояния.
Службы доставки нужны всегда и всем. Чтобы транспортировать
любую вещь, будь то письмо или же партия новых ноутбуков, в соседний
район или же на другую часть планеты, люди всегда сталкиваются с
проблемой транспортировки всего этого. Для оформления доставки нужно
где-то записать и хранить информацию, а если таких доставок будет
огромное количество, то компания столкнётся с проблемой нагромождения
информации.
Становиться ясно, что без хранения этой информации в электронном
виде не получиться адекватно вести учёт доставок. Сейчас уже даже самые
мелкие компании пользуются приложениями для работы с данными.
Использование базы данных для хранения информации о процессах службы
доставки позволит улучшить эффективность работы компании.
В данной курсовой работе будет реализовано приложение, которое
позволит службам доставки автоматизировать свою работу, потратив на это
всего пару минут вместо нескольких часов рутины. Далее представлена
разработка приложения, реализующая выше поставленную задачу.
6

1 АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ

1.1 Состояние вопроса

Условно к логистическим провайдерам, предоставляющим комплекс


услуг по экспедированию и временному хранению грузов, можно отнести
менее 260 компаний. Лишь незначительное число их (менее 5%) могут быть
позиционированы как 3PL-провайдеры, способные решать все вопросы
логистической направленности для своих клиентов, включая оптимизацию
бизнес-процессов на протяжении всей цепочки поставок.
Основная масса экспедиторских и логистических компаний
расположена в Москве и Санкт-Петербурге, а также в портовых городах и
региональных центрах. Около 30% транспортно-логистических компаний
зарегистрированы в ЦФО (в том числе, более 20% - в Москве), 28% - в
Приволжском ФО, 18% - в Уральском ФО и 10% - в Северо-Западном ФО (в
том числе, 9% - в Санкт-Петербурге).
В ходе исследования, проведенного NeoAnalytics на тему “Российский
рынок экспресс-доставки грузов и почты: итоги 2018 г., прогноз до 2021 г.»,
выяснилось, что в 2018 году объем рынка экспресс-доставки составил около
72 млрд.руб. и увеличился на 12,5%.
В последние годы российские компании серьезно потеснили
зарубежных участников рынка. Доля крупных российских операторов
составляет около 60%, и за последние 4-5 лет она увеличилась на 10-15%.
Доля международных компаний составляет около 30% рынка. Крупнейшими
международными компаниями на российском рынке экспресс-доставки
являются DHL и UPS.Среди отечественных компаний лидерами рынка
являются: «DPD», «EMS Почта России», «Pony Express» и др.
7
Стоимость экспресс-доставки у международных компаний выше
стоимости доставки российских компаний на одинаковые параметры
отправления. Однако международные операторы выигрывают в сроках
доставки, как по России, так и в зарубежные страны.
Экспортно-импортные перевозки росли высокими темпами до 2014-
2015гг. Этому способствовало общее увеличение прозрачности рынка и
повышение его привлекательности для игроков международной Интернет-
коммерции. После 2015 г. существенное влияние на сегмент международной
доставки оказали антироссийские санкции, в результате которых объем
сделок с зарубежными партнерами сократился. В настоящее время на
внутрироссийские перевозки приходится около 82%, экспортно-импортные
перевозки составляют около 18% от общего объема рынка экспресс-
перевозки.
Ожидается, что в 2019-2021гг. рынок будет расти на 12-15%, в первую
очередь, за счет рост электронной торговли и выход ритейлеров в онлайн.
Доставка становится важнейшим звеном в цепочке заказа и получения
товаров из Интернет-магазинов. Компаниями экспресс-доставки создаются
специальные решения для обслуживания дистанционной торговли.

1.2 Моделирование существующих бизнес-процессов

Произведём оценку системы в терминах бизнес-процессов организации


с использованием методологий IDEF0. Первый шаг в построении модели –
это определение цели модели, то есть вопросов, на которые призвана
ответить модель. Вопросы следуют из формулировки задачи и анализа
требований.
Построим контекстную диаграмму (самое общее описание системы и её
взаимодействия с внешней средой) и проведём функциональную
декомпозицию (разбиение системы на крупные фрагменты) для построения
8
диаграмм декомпозиции. Контекстная диаграмма, описывающая
функционирование службы доставки, изображена на рисунке 1.1.

Рисунок 1.1 – Контекстная диаграмма

Диаграмма декомпозиции функционального блока «Доставка»


изображена на рисунке 1.2.
9

Рисунок 1.2 – Диаграмма декомпозиции блока «Доставка»

Из диаграммы декомпозиции функционального блок «Доставка»


выделяются 3 основных этапа функционирования службы доставки. Первым
делом оформляется заказ на доставку от клиентов, после чего осуществляется
упаковка посылки в коробку, чтобы не повредить посылку во время доставки.
В заключении производится сама доставка курьером от пункта получения
посылки до конечного адреса получателя.
Диаграмма декомпозиции функционального блока «Оформление
посылки» изображена на рисунке 1.3.
10

Рисунок 1.3 – Диаграмма декомпозиции блока «Оформление посылки»

1.3 Актуальность и цель работы

Целью данного проекта является создание удобного решения для


автоматизации работы данных службы доставки и повышение
продуктивности персонала, путем сокращения затрат на ручную работу.
Исходя из указанной цели, можно выделить частные задачи,
поставленные в работе:
1) провести детальный анализ предметной области. Изучить механизм
работы службы доставки, выделить ключевые моменты;
2) изучить технологии: среда разработки PyCharm, среда разработки Qt,
среда разработки Ms SQL Server, язык Python и SQL;
11
3) разработать архитектуру приложения, концептуальную, логическую
и физическую модели базы данных и функционал программы,
соответствующий техническому заданию;
4) разработать полностью рабочее приложение со всем
запланированным функционалом.
Актуальность:
1) операторам службы доставки становиться намного проще
осуществлять оформление заказов на доставку от клиентов;
2) логисты службы доставки смогут более эффективно прокладывать
маршрут между точками отправки и конечными точками доставки, с
учётом видов транспортов;
3) возможность передавать информацию по почте в любой другой
город, где находиться отдел службы доставки;
4) позволит без особых проблем хранить информацию о доставках на
протяжении многих лет из-за большого объёма хранилища.
12
2 ТЕХНИЧЕСКОЕ ЗАДАНИЕ

2.1 Описание области применения и исходных данных приложения

Данное приложение предназначено для использования операторами


службы доставки в целях уменьшения временных затрат на оформление
заказов на доставку посылок, а также на прокладывание маршрута доставки и
выбора оптимального вида транспорта.
Исходными данными для приложения являются:
1) города;
2) курьеры – имя, фамилия, отчество, зарплата, город, в котором
работает курьер;
3) отправители – название отправителя, город и улица, где находиться
отправитель, контактный номер;
4) посылки – серийный номер посылки, вес посылки, вид упаковки,
отправитель;
5) виды посылок по весу и объёму упаковки;
6) доставки – посылка, которую необходимо доставить, вид доставки,
получатель посылки, город и улица, где находится получатель, курьер,
ответственный за доставку и состояние доставки (доставлен или нет);
7) виды доставок – тип транспорта, цена перевозки и скорость
транспортировки;

2.2 Требования к пользовательским интерфейсам

Пользовательский интерфейс должен разрабатываться под разрешение


экрана 800х600 и более. Окна должны обладать системным меню с кнопкой
закрытия.
Требования к окнам приложения:
13
Окно авторизации должно быть разделено на левую и правую часть с
отношением сторон 4:6. В левой части окна авторизации должен находиться
логотип службы доставки. В правой части окна должны находиться элементы
для авторизации пользователя:
1) надпись «Пользователь» с полем для ввода логина пользователя;
2) надпись «Пароль» с полем для ввода пароля пользователя;
3) кнопка «Вход»;
Главное окно приложения должно выполнять следующие задачи:
1) содержать таблицу для просмотра редактирования данных в ней –
таблица должна быть размещена по всему окну с небольшим пустым
местом вверху и справа;
2) содержать кнопки управления данными в таблице – кнопки
«Добавить», «Удалить», «Сохранить», которые должны находиться
вместе с мини-логотипом службы доставки в правой части от
таблицы, где оставлено пустое место;
3) содержать элементы управления таблицами – надпись «Таблицы» с
выпадающим списком, который содержит названия таблиц и кнопка
«Показать».
4) Кнопка «Статистика» перехода на окно запросов.
Окно запросов должно быть разделено на верхнюю и нижнюю часть с
отношением сторон 2:8. В нижней части будет находиться таблица
отображающая результаты запросов. В верхней части будет находиться
элементы для выбора запроса – надпись «Запросы» с выпадающим списком,
содержащего название запросов, а также мини-логотип компании. Помимо
этого должна быть размещена кнопка «Назад» для закрытия окна.

2.3 Требования к аппаратным, программным и


коммуникационным интерфейсам
14
Для установки и работы приложения необходимо иметь
вычислительную систему следующей минимальной аппаратной
конфигурации:
1) процессор: 1.6 ГГц;
2) оперативная память: 1 Гб;
3) свободное место на жёстком диске: 200 Мб;
4) наличие основных средств ввода-вывода (мышь, клавиатура,
монитор);
5) операционная система: Windows XP, 7, 8, 8.1, 10.

Необходимо обеспечить программное взаимодействие системы с:


1) системой управления базами данных Ms SQL Server 2014;
2) программой Ms SQL Server Management Studio 2014;
3) интерпретатор Python 3.6.

2.4 Требования к пользователям продукта

1) Владение компьютером на уровне пользователя;


2) Понимание принципов работы с манипуляторами;
3) Понимание принципов доставки;
4) Понимание принципов работы базы данных.

2.5 Требования к адаптации на месте

На компьютере должен быть установлен интерпретатор Python 3.6,


система управления базами данных Ms SQL Server, программа Ms SQL Server
Management Studio, подключены такие устройства ввода информации как
мышки и клавиатура.
15
2.6 Функции продукта

Приложение должно уметь работать с таблицами базы данных с


информацией о доставках, курьерах, городах, отправителях, посылках, типов
посылок, типов доставки.
В программе должна присутствовать возможность оформления
доставок посылок от клиентов, а также возможность просмотра результата
запросов.
Должна быть реализована функция множественного пользователя, то
есть с приложением могут работать несколько видов пользователей. От вида
пользователя, который авторизовался в приложение, у него должны быть
разные функциональные возможности. В частности в приложении должны
существовать 2 вида пользователей, такие как администратор и оператор
службы доставки.
Администратор получает права на редактирования таблиц в базе
данных, а также контроль пользовательскими учётными аккаунтами:
1) редактирование данных в таблицах (добавление, удаление,
изменение): «Доставки», «Курьеры», «Города», «Отправители»,
«Посылки», «Типы посылок», «Типы доставок»;
2) редактирование данных о пользователях, изменения логина и
пароля, изменение прав на пользование приложением;
Оператор должен иметь возможность оформлять заказы от клиентов, а
также:
1) анализировать информацию о курьерах, оформленной посылке,
месторасположении отправителя и конечном адресе получателя,
типах доставок и типе посылки;
2) прокладывать оптимальный маршрут с учётом типов доставок,
посылки и наличии курьеров в городах.
16
2.7 Ограничения

1) продукт будет работать только в операционной системе Windows 7,


8, 8.1, 10;
2) продукт будет поддерживать только русский язык пользовательского
интерфейса;
3) продукт будет работать только с базой данных Ms SQL Server, и
драйвером QDBC;
4) Продукт не будет работать, если изменить структуру таблиц в базе
данных (например, удалить, или добавить атрибут в таблицу).
17
3 ОБОСНОВАНИЕ ВЫБОРА ИНСТРУМЕНТАЛЬНЫХ СРЕДСТВ

Python – универсальный мультипарадигменный скриптовый язык


программирования.
Основные преимущества Python:
1. Низкий порог вхождения: человеку, знакомому с
программированием, достаточно получаса, чтобы начать писать на нем
полезные для себя скрипты, а не знакомому – Python позволяет легко открыть
для себя программирование и попробовать свои силы в нем.
2. Хорошо спроектирован: Python вобрал в себя современные
тенденции в программировании «с нуля». Кроме того, он динамично
развивается: процесс включения новых конструкций в язык хорошо отлажен,
и он продолжает впитывать в себя приемы функционального
программирования, аспектно-ориентированного программирования и
прочего, оставаясь при этом обратно-совместимым и внутренне
непротиворечивым.
3. Легко читаемый синтаксис (по сравнению с С++, Рerl, РНР):
позволяет легко читать чужой код, разбираться в давно написанном
собственном коде. В сочетании со сказанным выше это настраивает
создателей библиотек на простоту и логичность интерфейсов.
4. Огромное количество библиотек с кодом на любой случай жизни:
будь то работа с таблицами Excel, изображениями или сетью Twitter.
5. Переносимость: Python реализован под всеми
распространенными операционными системами и на множестве архитектур –
Windows, Linux, MacOS, даже на мини-компьютерах Arduino. Система
зависимостей хорошо продумана, и разворачивание приложений на другой
машине происходит легко и без сюрпризов.
MS SQL Server – это платформа для решения критически важных задач
в масштабе предприятия, обладающая высокой доступностью, повышенной
18
производительностью и безопасностью. Решение представляет собой хорошо
масштабируемый, полностью реляционный, быстродействующий сервер,
способный обрабатывать большие объемы данных для клиент-серверных
приложений. Рекордная производительность MS SQL Server обеспечивается
новыми технологиями работы с памятью, что помогает предприятиям
ускорить свой бизнес и реализовать новые сценарии работы. Кроме того, SQL
Server позволяет использовать новые гибридные облачные решения и
пользоваться новыми преимуществами облачных вычислений. Расширенные
функции безопасности, в сочетании со встроенными, удобными для
использования инструментами и управляемым доступом к данным,
позволяют организации выполнить требования строгих политик соответствия
нормам.
19
4 РАЗРАБОТКА БАЗЫ ДАННЫХ СЛУЖБЫ ДОСТАВКИ

4.1 Разработка базы данных приложения

4.1.1 Концептуальное проектирование базы данных.

Концептуальное проектирование – построение семантической модели


предметной области (информационной модели самого высокого уровня
абстракции). Концептуальная модель базы данных включает в себя:
В ходе изучения предметной области выделены следующие сущности,
представляющие информационное значение для задачи:
1) город – информация о городах;
2) отправитель – информация об отправителях посылок, которые
оформили заказ у оператора;
3) посылка – информация о посылках, которые необходимо доставить к
пункту назначения;
4) доставка – информация о доставке посылки;
5) курьер – информация о сотруднике службы доставки;
6) тип доставки – все типы доставок по способу доставки;
7) тип посылки – все типы посылок по объёму и массе;
8) пользователь – информация о пользователях приложения.
Концептуальное представление базы данных приведено на рисунке 4.1.
20

Рисунок 4.1 – Концептуальная модель базы данных

4.1.2 Логическое проектирование базы данных.

Логическое проектирование – создание схемы базы данных на основе


конкретной модели данных, например, реляционной модели данных.
В логической модели данных сущности получают атрибуты, которые
характеризуют определённый экземпляр объекта. Все из этих атрибутов
обязательны к заполнению. Некоторые атрибуты являются связывающими с
другой сущностью, они называются также как и таблица, с которой они
связывают.
Логическое представление базы данных приведено на рисунке 4.2.
21

Рисунок 4.2 – Логическая модель базы данных

4.1.3 Физическое проектирование базы данных

Физическое проектирование – создание схемы базы данных для


конкретной СУБД. Данное физическое представление базы данных для
службы доставок разрабатывалось в Microsoft SQL Server Management Studio.
Физическое представление содержит первичные ключи, внешние
ключи и ограничения.
Физическая модель базы данных изображена на рисунке 4.3.
22

Рисунок 4.3 – Физическое представление модели базы данных

Физическое представление каждой отдельной таблицы с описанием её


атрибутов изображено на рисунках 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 4.10, 4.11.

Рисунок 4.4 – Физическое представление таблицы «Cities»


23

Рисунок 4.5 – Физическое представление таблицы «TypesOfDeliveries»

Рисунок 4.6 – Физическое представление таблицы «TypesOfPackages»

Рисунок 4.7 – Физическое представление таблицы «Couriers»

Таблица «Couriers» содержит внешний ключ в атрибуте «City»,


который связан с атрибутом «Id» в таблице «Cities».

Рисунок 4.8 – Физическое представление таблицы «Senders»

Таблица «Senders» содержит внешний ключ в атрибуте «City», который


связан с атрибутом «Id» в таблице «Cities».
24

Рисунок 4.9 – Физическое представление таблицы «Packages»

Таблица «Packages» содержит внешний ключ в атрибуте «Type»,


который связан с атрибутом «Id» в таблице «TypesOfPackages», внешний
ключ в атрибуте «Sender», который связан с атрибутом «Id» в таблице
«Senders».

Рисунок 4.10 – Физическое представление таблицы «Deliveries»

Таблица «Deliveries» содержит внешний ключ в атрибуте «Type»,


который связан с атрибутом «Id» в таблице «TypesOfDeliveries», внешний
ключ в атрибуте «Courier», который связан с атрибутом «Id» в таблице
«Couriers», внешний ключ в атрибуте «City», который связан с атрибутом
«Id» в таблице «Cities», внешний ключ в атрибуте «Package», который связан
с атрибутом «Id» в таблице «Packages».
25

Рисунок 4.11 – Физическое представление таблицы «Users»

4.2 Проектирование структуры приложения

Проект UPS состоит разделён по папкам: Delegates, FormModels, Forms,


Services. Кроме того в проекте присутствуют ещё 2 файла:
- DataBase.py – содержит переменные для названия таблиц в базе
данных, списки названия столбцов в таблицах, список запросов для базы
данных;
- resf.py – содержит код ресурсов проекта.
В папке Delegates находятся такие файлы:
- BoolColumnDelegate.py – файл, содержащий делегат, который
представляет собой столбец, содержащий булевы значения (true или false);
- NoneColumnDelegate.py - файл, содержащий делегат, который
представляет собой столбец, который невозможно редактировать;
- NotEmptyTextColumnDelegate.py - файл, содержащий делегат,
который представляет собой столбец, содержащий строку, в которой есть, по
крайней мере, один символ, отличный от пробела;
- UnsignedDoubleColumnDelegate.py - файл, содержащий делегат,
который представляет собой столбец, содержащий значение вещественного
числа в переданных в конструкторе пределах;
- UnsignedIntegerColumnDelegate.py - файл, содержащий делегат,
который представляет собой столбец, содержащий значение целого числа в
переданных в конструкторе пределах;
26
В папке FromModels находятся такие файлы:
- authFormModel.py – файл, содержащий основную логику окна
авторизации;
- headFormModel.py - файл, содержащий основную логику главного
окна приложения;
- supFormModel.py - файл, содержащий основную логику окна
запросов;
В папке Forms находятся такие файлы:
- authWindow.py – файл, содержащий описание элементов управления
окна авторизации;
- headWindow.py - файл, содержащий описание элементов управления
главного окна приложения;
- supWindow.py - файл, содержащий описание элементов управления
окна запросов;
В папке Services находится файл ServiceModelTable.py, который при
выборе таблицы устанавливает для её столбцов соответствующие делегаты, а
также отношения между таблицами.

4.3 Описание классов и методов приложения

Все делегаты имеют похожую структуру. Делегаты являются классами,


которые наследуются от класса QStyledItemDelegate, который находится в
модуле QtWidgets из пакета PyQt5.
Все делегаты имеют метод createEditor, который создаёт элемент
управления editor, в котором будут обрабатываться данные столбца.
Метод setEditorData срабатывает при нажатии на любую ячейку
столбца, считывает из модели данных значение и присваивает элементу
управления editor.
27
Метод setModelData срабатывает, после того кого работа с ячейкой
закончилась, записывает значение из элемента управления editor в модель
данных.
Файл authFromModel.py содержит класс FormAuth, который
наследуется от класса QtWidget модуля QtWidgets из пакета PyQt5, и класса
Ui_Form из модуля authWindow.
Класс FormAuth содержит обработку кнопки «Вход», который
заключается в выполнении запроса на поиск пользователя по указанному в
полях userLineEdit и passLineEdit значениях логина и пароль. Если результат
вернул хотя бы один кортеж, то открывается главное окно приложения
FormHead.
Файл headFromModel.py содержит класс FormHead, который
наследуется от класса QtWidget модуля QtWidgets из пакета PyQt5, и класса
Ui_Form из модуля headWindow.
Класс FormHead содержит методы работы с моделью данных, такие как
добавление строки (addStroke), удаление выбранных строк (deleteStroke),
сохранение всех изменений таблицы в базу данных (submit).
Метод showTable выполняется при нажатии на кнопку «Отобразить».
Считывается название таблицы из выпадающего списка comboBox и с
помощью ServiceModelTable таблица изменяется для удобного представления
пользователю.
Файл supFromModel.py содержит класс FormSup, который наследуется
от класса QtWidget модуля QtWidgets из пакета PyQt5, и класса Ui_Form из
модуля supWindow.
Класс FormSup содержит метод отображения результата запроса,
который считывает название запроса из выпадающего списка comboBox и
через словарь queries из модуля DataBase возвращает код SQL-запроса, после
чего выполняет его и отображает в таблице tableView.
28
4.4 Описание SQL-запросов к базе данных системы

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


добавление, удаление, изменение данных также предоставляет возможность
выполнение SQL-запросов.
Запросы к базе данных, которые выполняются в приложении:
1) запрос на вывод количества посылок по типам посылок, должен
содержать все название типов посылок в первом столбце и по
каждому типу количество посылок данного типа:
SELECT t.Name AS [Тип посылки], COUNT(p.ID) AS [Кол-ство]
FROM Packages AS p
INNER JOIN TypesOfPackages AS t
ON p.Type = t.Id
GROUP BY t.Name;
2) запрос на вывод количества доставок по типам доставок, должен
содержать все названия типов доставок в первом столбце и по
каждому типу количество доставок данного типа:
SELECT t.Name AS [Тип доставки],
COUNT(d.ID) AS [Кол-ство]
FROM Deliveries AS d
INNER JOIN TypesOfDeliveries AS t
ON d.Type = t.Id
GROUP BY t.Name;
3) запрос на вывод суммарного веса посылок по отправителям, должен
содержать наименование отправителей доставок в первом столбце и
суммарный вес всех посылок, которые отправил этот клиент:
SELECT s.Name AS [Отправитель],
SUM(p.Weight) AS [Вес, г]
FROM Senders AS s
INNER JOIN Packages AS p
ON s.Id = p.Sender
29
GROUP BY s.Name;
4) запрос на вывод свободных курьеров, должен содержать имя,
фамилию, отчество курьера и город в котором он проживает, если он
свободен в данный момент:
SELECT c.Name AS [Имя],
c.Surname AS [Фамилия],
c.Patronymic AS [Отчество],
ct.Name AS [Город]
FROM Couriers AS c
INNER JOIN Cities AS ct
ON ct.Id = c.City
EXCEPT
SELECT c.Name AS [Имя],
c.Surname AS [Фамилия],
c.Patronymic AS [Отчество],
ct.Name AS [Город]
FROM Deliveries AS d
INNER JOIN (Couriers AS c
INNER JOIN Cities AS ct ON ct.Id = c.City)
ON d.Courier = c.Id
WHERE d.Done = 0;
5) запрос на вывод доставок, которые производят доставку в другой
город, должен содержать серийный номер доставки, фамилию
курьера и город доставки;
SELECT p.SerialNumber AS [Посылка],
c.Surname AS [Курьер],
ct.Name AS [Город доставки]
FROM Couriers AS c INNER JOIN
(Packages AS p INNER JOIN (Cities AS ct
INNER JOIN Deliveries AS d ON ct.Id = d.City)
ON d.Package = p.Id) ON c.Id = d.Courier
WHERE c.City != ct.Id;
30
6) запрос на вывод количества курьеров по городам, должен содержать
все название городов в первом столбце и по каждому городу
количество курьеров данного города:
SELECT ct.Name AS [Город],
COUNT(c.Id) AS [Кол-ство]
FROM Couriers AS c
INNER JOIN Cities AS ct ON c.City = ct.Id
GROUP BY ct.Name;
31
5 ТЕСТИРОВАНИЕ ПРОГРАММНОГО ПРОДУКТА

5.1 Аппаратные и программные средства создания и эксплуатации


приложения

Для работы приложения требуется следующеее аппаратное


обеспечение:
1) процессор с тактовой частотой 1.6 ГГц;
2) оперативная память 1 Гб и более;
3) монитор 800х600 или с более высоким разрешением.
Программные требования к приложению.
На компьютере должны быть установлено следующее программное
обеспечение:
1) операционная система —Windows XP или Windows 7/8/8.1/10;
2) Microsoft SQL Server 2014/2017;
3) Драйвер QDBC;
4) Интерпретатор Python 3.6.

5.2 Руководство пользователя

Для работы приложения необходимо:


Установить на компьютере интерпретатор Python 3.6 (ссылка:
https://www.python.org/downloads/).
Установить на компьютере Microsoft SQL Server 2014 Express (ссылка:
https://www.microsoft.com/en-us/download/details.aspx?id=42299).
Создать на жёстком диске папку с любым именем и скопировать в неё
все файлы приложения, включая исполнительный файл UPS.exe.
Скопировать в папку базу данных, где находится базы данных, затем
подключить эту базу данных через Microsoft SQL Server 2014.
32
После всего этого, необходимо перейти в папку с ране скопированными
файлами приложения и запустить приложение через исполняющий файл
UPS.exe.

5.3 Описание контрольных примеров

Для запуска приложения необходимо нажать дважды левой кнопкой


мыши на файл AppExcel.exe, после чего откроется страница авторизации
пользователя в приложение, вид которого изображён на рисунке А1.
Чтобы войти в приложение под каким-либо видом пользователя,
необходимо ввести в поля логин и пароль, после чего нажать на кнопку
«Войти», и если всё введено правильно, пользователь попадёт на главную
страницу приложения. В противном случае пользователь не получит доступ к
дальнейшей части приложения.
После входа в основную часть, вид которого изображён на рисунке А2,
А3, пользователь может выбрать в выпадающем списке рядом с надписью
«Таблицы» таблицу, которую хочет просмотреть или редактировать, а затем
нажать на кнопку «Отобразить».
Если пользователю нужно добавить или удалить строку в таблице, то
необходимо для начала отобразить нужную таблицу, а затем нажать на
соответствующие кнопки «Добавить» и «Удалить».
Чтобы сохранить все изменения над таблицей в базу данных,
необходимо нажать на кнопку «Сохранить».
Для перехода в страницу запросов приложения, пользователь должен
нажать на кнопку «Статистика», вид которого изображён на рисунке А4.
После перехода в окно запросов, пользователь может выбрать в
выпадающем списке с надписью «Запросы» необходимый запрос, а затем
нажать на кнопку «Отобразить».
33
Для возврата в главное окно пользователь должен нажать на кнопку
«Назад».
34
ЗАКЛЮЧЕНИЕ

В результате решения задачи спроектирована база данных и


информационная система, автоматизирующая процесс оформления заказов от
клиентов на доставку посылок от отправителя до конечной точки назначения.
Приложение позволяет хранить, обрабатывать данные о доставках,
посылках, типах доставок, типах посылок, курьерах, отправителях, городах и
пользователях. Также приложение позволяет разграничить доступ к
функционалу приложения не несколько видов пользователей, в частности на
администратора и оператора.
Приложение рассчитывает: количество доставок по типам доставок,
количество посылок по типам посылок, количество курьеров в каждом
городе, суммарный вес посылок от всех клиентов.
Приложение отображает: свободных на данный момент курьеров,
доставки, конечный адрес, которых находится в другом городе по сравнению
с начальной точкой.
Для управления базой данных был выбран Microsoft SQL Server
Management Studio 2014, для связи с сервером использовался драйвер QDBC.
Разработка графической части приложения производилась в Qt
Designer, а для бизнес-логики был выбран язык Python 3.6.
Приложение может использоваться сотрудниками службы доставки для
оформления заказов на доставку от клиентов, для простого и быстрого
функционирования службы доставки.
35
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1. Руководство по языку программирования Python.


URL: https://metanit.com/python/tutorial/ (дата обращения: 01.10.2019)
2. Руководство по Qt Designer.
URL: http://doc.crossplatform.ru/qt/4.5.0/designer-manual.html (дата обращения:
08.10.2019)
3. Горборуков В. Современная транспортная логистика /
В. В. Горборуков. – СПБ: Питер, 2018. – 260 с.
4. Meier B. A. Python GUI Programming Cookbook /
B. A. Meier. – UK: Birmingham, 2015. – 415 с.
5. Бизнес-план курьерской службы.
URL: https://www.bi-plan.ru/biznes_plan_kurerskoj_sluzhby/ (дата обращения:
26.09.2019)
6. Gries P. Practical Programming /
P. Gries. – CA: O’Reilly, 2017. – 524 c.
7. Бондарь Александр. Microsoft SQL Server 2012 /
А. Бондарь. – СПБ: БХВ-Петербург, 2012. – 608 c.
36
ПРИЛОЖЕНИЕ А
Экранные формы

Рисунок А1 – Окно авторизации пользователя

Рисунок А2 – Главное окно, таблица «Города»


37

Рисунок А3 – Главное окно, таблица «Курьеры»

Рисунок А4 – Окно «Статистика»


38
ПРИЛОЖЕНИЕ Б
Фрагменты листинга

Листинг Б1 – Файл «authFormModel.py»

from PyQt5 import QtWidgets, QtCore


from PyQt5.QtSql import QSqlQueryModel
import sys
from Forms import authWindow
from FormModels import headFormModel
import DataBase

class FormAuth(QtWidgets.QWidget, authWindow.Ui_Form):


def __init__(self, parent=None):
super(FormAuth, self).__init__(parent, QtCore.Qt.Window)
self.setupUi(self)
self.enterPushButton.clicked.connect(self.open)

DataBase.con(self)
self.head_form = headFormModel.FormHead()

def open(self):
query = QSqlQueryModel()
query.setQuery("SELECT * FROM Users WHERE Login = '%s'
AND Password = '%s'"
% (self.userLineEdit.text(),
self.passLineEdit.text()))
if query.rowCount() > 0:
self.close()
self.head_form.show(query)

def showForm():
app = QtWidgets.QApplication(sys.argv)
window = FormAuth()
window.show()
sys.exit(app.exec_())

if __name__ == '__main__':
showForm()

Листинг Б2 – Файл «headFormModel.py»

from PyQt5 import QtWidgets, QtCore


from PyQt5.QtSql import QSqlRelationalDelegate
import sys
39
from Forms import headWindow
import DataBase
from Services import ServiceModelTable
from FormModels import supFormModel

class FormHead(QtWidgets.QWidget, headWindow.Ui_Form):


def __init__(self, parent=None):
super(FormHead, self).__init__(parent, QtCore.Qt.Window)
self.setupUi(self)
self.sup_window = supFormModel.FormSup(self)
self.showPushButton.clicked.connect(self.showTable)
self.supPushButton.clicked.connect(self.sup_window.show)
self.addPushButton.clicked.connect(self.addStroke)
self.deleetePushButton.clicked.connect(self.deleteStroke
)
self.submitPushButton.clicked.connect(self.submit)

DataBase.con(self)

def showTable(self):
self.current_table =
DataBase.tables[self.comboBox.currentText()]
ServiceModelTable.setModel(self, self.tableView,
self.default_delegates, self.current_table)
self.tableView.setColumnHidden(0, True)

def submit(self):
if self.tableView.model() != None:
self.tableView.model().submitAll()
self.tableView.model().select()

def deleteStroke(self):
if self.tableView.model() == None or
self.tableView.selectionModel().hasSelection() == False:
return
indexes = [QtCore.QPersistentModelIndex(index) for index
in self.tableView.selectionModel().selectedRows()]
for index in indexes:
self.tableView.model().removeRow(index.row())

def addStroke(self):
if self.tableView.model() != None:
self.tableView.model().insertRow(self.tableView.mode
l().rowCount())

def show(self, access=None):


if access!=None:
self.type_access = access.record(0).value(3)
else:
40
self.type_access = 0
self.comboBox.addItems(DataBase.tables.keys())
self.default_delegates =
[self.tableView.itemDelegateForColumn(column) for column in
range(10)]
self.tableView.setItemDelegate(QSqlRelationalDelegate(se
lf.tableView))
if self.type_access != 0:
self.tableView.setEditTriggers(QtWidgets.QAbstractIt
emView.NoEditTriggers)
self.addPushButton.setDisabled(True)
self.deleetePushButton.setDisabled(True)
self.submitPushButton.setDisabled(True)
self.comboBox.removeItem(self.comboBox.count()-1)
QtWidgets.QMainWindow.show(self)

def showForm():
app = QtWidgets.QApplication(sys.argv)
window = FormHead()
window.show()
sys.exit(app.exec_())

if __name__ == "__main__":
showForm()

Листинг Б3 – Файл «supFormModel.py»

from PyQt5 import QtWidgets, QtCore


from PyQt5.QtSql import QSqlQueryModel
import sys
from Forms import supWindow
import DataBase

class FormSup(QtWidgets.QWidget, supWindow.Ui_Form):


def __init__(self, parent=None):
super(FormSup, self).__init__(parent, QtCore.Qt.Window)
self.setupUi(self)
self.backPushButton.clicked.connect(self.close)
self.showPushButton.clicked.connect(self.showTable)
self.comboBox.addItems(DataBase.queries.keys())

DataBase.con(self)

def showTable(self):
self.query = QSqlQueryModel()
self.query.setQuery(DataBase.queries[self.comboBox.curre
ntText()])
41
self.tableView.setModel(self.query)

def show(self):
QtWidgets.QMainWindow.show(self)

def showForm():
app = QtWidgets.QApplication(sys.argv)
window = FormSup()
window.show()
sys.exit(app.exec_())

if __name__ == "__main__":
showForm()

Листинг Б4 – Файл «ServiceModelTable.py»

from Delegates import UnsignedIntegerColumnDelegate,


UnsignedDoubleColumnDelegate, NotEmptyTextColumnDelegate,\
BoolColumnDelegate
from PyQt5 import QtCore
from PyQt5.QtSql import QSqlRelationalTableModel, QSqlRelation
import DataBase

def setModel(parent, table_view, def_del, table):


model = QSqlRelationalTableModel()
model.setTable(table)
model.select()
table_view.setModel(model)
for column in range(len(def_del)):
table_view.setItemDelegateForColumn(column,
def_del[column])
edit_model[table](model, table_view, parent)
model.setEditStrategy(QSqlRelationalTableModel.OnManualSubmi
t)
model.select()

def edit_cities(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_cities][i])

def edit_couriers(model,table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(2,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
42
table_view.setItemDelegateForColumn(3,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(4,
UnsignedDoubleColumnDelegate.UnsignedDoubleColumnDelegate(2000,
parent=parent))
model.setRelation(5, QSqlRelation(DataBase.t_cities, 'Id',
'Name'))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_couriers][i])

def edit_deliveries(model,table_view, parent):


table_view.setItemDelegateForColumn(3,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(4,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(7,
BoolColumnDelegate.BoolColumnDelegate(parent))
model.setRelation(1, QSqlRelation(DataBase.t_packages, 'Id',
'SerialNumber'))
model.setRelation(2,
QSqlRelation(DataBase.t_types_of_deliveries, 'Id', 'Name'))
model.setRelation(5, QSqlRelation(DataBase.t_couriers, 'Id',
'Surname'))
model.setRelation(6, QSqlRelation(DataBase.t_cities, 'Id',
'Name'))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_deliveries][i])

def edit_packages(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(2,
UnsignedIntegerColumnDelegate.UnsignedIntegerColumnDelegate(pare
nt=parent))
model.setRelation(3,
QSqlRelation(DataBase.t_types_of_packages, 'Id', 'Name'))
model.setRelation(4, QSqlRelation(DataBase.t_senders, 'Id',
'Name'))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_packages][i])

def edit_senders(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(2,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
43
table_view.setItemDelegateForColumn(3,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
model.setRelation(4, QSqlRelation(DataBase.t_cities, 'Id',
'Name'))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_senders][i])

def edit_types_of_deliveries(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(2,
UnsignedDoubleColumnDelegate.UnsignedDoubleColumnDelegate(1,
parent=parent))
table_view.setItemDelegateForColumn(3,
UnsignedIntegerColumnDelegate.UnsignedIntegerColumnDelegate(1,
parent=parent))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_types_of_deliveries][i])

def edit_types_of_packages(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_types_of_packages][i])

def edit_users(model, table_view, parent):


table_view.setItemDelegateForColumn(1,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(2,
NotEmptyTextColumnDelegate.NotEmptyTextColumnDelegate(parent))
table_view.setItemDelegateForColumn(3,
UnsignedIntegerColumnDelegate.UnsignedIntegerColumnDelegate(pare
nt=parent))
for i in range(model.columnCount()):
model.setHeaderData(i, QtCore.Qt.Horizontal,
DataBase.columns[DataBase.t_users][i])

edit_model = {
DataBase.t_cities: edit_cities,
DataBase.t_couriers: edit_couriers,
DataBase.t_deliveries: edit_deliveries,
DataBase.t_packages: edit_packages,
DataBase.t_senders: edit_senders,
DataBase.t_types_of_deliveries: edit_types_of_deliveries,
DataBase.t_types_of_packages: edit_types_of_packages,
DataBase.t_users: edit_users
}
44
Листинг Б5 – Файл «NotEmptyTextColumnDelegate.py»

from PyQt5.QtCore import QModelIndex, Qt


from PyQt5.QtGui import QStandardItemModel, QPalette, QBrush
from PyQt5.QtWidgets import (QApplication, QLineEdit,
QStyledItemDelegate,
QTableView)

class NotEmptyTextColumnDelegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
lineEdit = QLineEdit(parent)
return lineEdit

def setEditorData(self, editor, index):


value = index.model().data(index, Qt.EditRole)
editor.setText(str(value) if value is not None else '')

def setModelData(self, editor, model, index):


if editor.text().strip() != '':
model.setData(index, editor.text().strip(),
Qt.EditRole)

def updateEditorGeometry(self, editor, option, index):


editor.setGeometry(option.rect)

Листинг Б6 – Файл «UnsignedDoubleColumnDelegate.py»

from PyQt5.QtCore import QModelIndex, Qt


from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import (QApplication, QDoubleSpinBox,
QStyledItemDelegate,
QTableView)

class UnsignedDoubleColumnDelegate(QStyledItemDelegate):
def __init__(self, minimum=0, maximum=100000000,
dimension=2, parent=None):
super(UnsignedDoubleColumnDelegate,
self).__init__(parent)
self.minimum = minimum
self.maximum = maximum
self.dimension = dimension

def createEditor(self, parent, option, index):


spinbox = QDoubleSpinBox(parent)
spinbox.setRange(self.minimum, self.maximum)
spinbox.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
spinbox.setDecimals(self.dimension)
45
return spinbox

def setEditorData(self, editor, index):


value = index.model().data(index, Qt.EditRole)
editor.setValue(value if value is not None else
editor.minimum())

def setModelData(self, editor, model, index):


editor.interpretText()
model.setData(index, editor.value(), Qt.EditRole)

def updateEditorGeometry(self, editor, option, index):


editor.setGeometry(option.rect)