Проектирование реализации операций бизнес-процесса «Планирование закупок и размещение заказов поставщикам»
Содержание:
ВВЕДЕНИЕ
Использование информационных технологий в производственной деятельности предприятий уже давно не является чем-то необычным. Скорее наоборот, их использование является необходимым условием для поддержания жизнеспособности любого предприятия, любого масштаба и сферы деятельности. Это обусловлено в первую очередь большой производительностью и широким функционалом современных программ. Они позволяют не только хранить данные и формировать шаблонные документы, но и дают возможность составления различных прогнозов, помогают решать задачи планирования деятельности и управления как всем предприятием, так и отдельными его подразделениями. Однако, не смотря на бурное развитие информационных технологий и повсеместное их внедрение, всегда остаются небольшие участки производственного процесса, которые либо плохо автоматизированы, либо не автоматизированы вовсе. Такие слабо автоматизированные участки имеют более низкую производительность труда, что отрицательно сказывается на общей производительности труда на предприятии.
Цель курсовой работы – проектирование информационной системы для реализации бизнес-процесса «Планирование закупок и размещение заказов поставщикам» на примере компании ООО «Протек».
Для достижения поставленной цели необходимо решить следующие задачи:
- проанализировать текущую организацию бизнес-процесса планирования закупок и размещения заказов поставщикам в отделе закупок компании ООО «Протек» и возникающего при его выполнении документооборота;
- выбрать и обосновать проектные решения по информационному и программному обеспечению;
- составить информационную модель проектируемой информационной системы;
- разработать базу данных и программные модули ИС;
- описать контрольный пример реализации проекта.
1 глава. Аналитическая часть
1.1. Выбор комплекса задач автоматизации
ООО «Протек» существует с 2004 года. Специализируется на абонентском обслуживании клиентов в области информационных технологий. Основные направления деятельности компании:
- проектирование ИТ-инфраструктуры организаций;
- организация ИТ-инфраструктуры с возможностью последующего обслуживания;
- модернизация существующей ИТ-инфраструктуры с возможностью последующего обслуживания;
- оказание постоянных(абонентских) или разовых услуг;
Организационную структуру рассматриваемого предприятия можно представить в виде схемы, изображенной на рисунке 1.
Рисунок 1. Организационная схема предприятия
Организационная структура включает в себя следующие подразделения:
- Бухгалтерия;
- Отдел закупок;
- Отдел сетевых коммуникаций;
- Техническая поддержка клиентов;
- Отдел системного администрирования;
- Отдел продаж.
Руководитель – директор компании, которому подчиняются начальники отделов.
Отдел закупок, деятельность которого и является предметом исследования, выполняет обеспечивающую функцию: главная задача работников отдела – взаимодействие с поставщиками необходимых компании материалов и оборудования с целью закупок всех необходимых товаров (как для реализации обслуживания клиентов, так и для обеспечения внутренних потребностей компании).
1.2. Характеристика существующих бизнес – процессов
Для того, чтобы выделить основные бизнес-процессы, составляющие деятельность отдела закупок, воспользуемся функционально-структурным моделированием деятельности. В качестве основной методологии выступает IDEF0.
Методологию IDEF0 создали американские военные для того, чтобы более успешно тиражировать бизнес-процессы на предприятиях аэрокосмической промышленности. В свое время военные столкнулись с проблемой следующего типа.
При проектировании деятельности заводов было замечено, что каждый раз сотрудники выполняют одни и те же действия при проектировании подсистем управления, на что уходило много дополнительного времени и ресурсов. Поэтому возникла идея разработать новый язык, или чертеж, при помощи которого сотрудники могли бы описать типовые подсистемы управления и при создании нового завода использовать эти наработки. Язык, которые был создан для этих целей, лег в основу методологии описания бизнес-процессов на предприятиях IDEF0.
Данная методология описания бизнес-процессов предполагает указание не только входов и выходов, но дополнительных входов. Всего в данном стандарте выделяют три типа входа: первый так и называется вход, второй – управлением, а третий – механизмами.
Стандарт IDEF0 регламентирует с помощью входа (первый тип входных данных) показывать объекты, которые преобразуются в данным бизнес-процессе, это могут быть информационные и материальные потоки. С помощью управления (второй тип) показывают объекты, которые управляют выполнением бизнес-процессам. С помощью механизмов (третий тип) необходимо показывать объекты, которые непосредственно осуществляют данный бизнес-процесс: сотрудники, технические средства, информационный системы. На выходе бизнес процесса показывают результат выполнения данного бизнес-процесса.
На первом этапе построения IDEF0-модели система представляется как единое целое. Основная цель данного этапа – выявить входные и выходные данные, а также механизмы и правила для данной системы. Диаграмма данного этапа называется контекстной, которая изображена на рисунке 2 (для построения диаграмм использовалось CASE- средство AllFusion Process Modeler 7)
Рисунок 2. Контекстная диаграмма деятельности отдела закупок
По мере необходимости сотрудники отделов составляют заявки в отдел закупок о потребностях в тех или иных продуктах/товарах, которые и выступают в роли входных данных. Также в качестве входных данных деятельности отдела закупок выступают данные поставщиков и их прайс-листы, которые запрашиваются у них по мере необходимости, либо присылаются поставщиками самостоятельно при изменении каких-либо данных. Кроме того, ежемесячные отчеты о расходовании материалов также необходимы для реализации деятельности отдела закупок.
Выходными данными выступают заказы поставщикам на поставку товаров. Всю деятельность выполняют сотрудники отдела закупок: руководитель и менеджеры.
Следующий этап построения структурно-функциональной модели в нотации IDEF0 – декомпозиция контекстной диаграммы на составляющие. Диаграмма декомпозиции исследуемой деятельности приведена на рисунке 5.
Рисунок 3. Диаграмма декомпозиции
Деятельность отдела закупок можно разделить на четыре этапа:
- Планирование закупок (выполняется руководителем);
- Распределение заявок среди менеджеров (выполняется руководителем);
- Оформление заказов поставщикам (выполняется менеджерами по закупкам);
- Формирование договора на поставку (выполняется руководителем отдела закупок).
Договор передается в бухгалтерию, сотрудники которой оплачивают указанные в нем товары по необходимым реквизитам. Затем вместе с платежным поручением отправляется поставщику.
1.3. Характеристика документооборота, возникающего при решении задачи
В процессе выполнения бизнес-процесса планирования закупок и размещения заказов поставщикам формируется основной документ – это заказ поставщику. Сначала он выглядит в виде обычного списка товаров, которые необходимо заказать. Затем, менеджеры по закупкам подбирают поставщика для этого списка (поставщиков может быть несколько), после чего создают заказ и отправляют его в бухгалтерию для оплаты и поставщику для отправки товаров.
Схема документооборота приведена на рисунке 4.
Рисунок 4. Схема документооборота заказа поставщику
1.4. Обоснование проектных решений по информационному обеспечению
Информационное обеспечение комплекса задач, которые поставлены перед данным проектом организовано в виде реляционной базы данных, в которой хранится вся информация, необходимая для автоматизации процесса приходования товара.
Существуют определенные правила создания и проектировании базы данных для нужд какой-либо организации:
- База данных должна содержать в себе все необходимые для работы организации данные, хранимая информация должна быть в актуальном состоянии;
- База данных должна обеспечивать доступ ко всей информации за приемлемое время, то есть отвечать заданным требованиям производительности;
- База данных должна удовлетворять выявленным и вновь возникающим требованиям конечных пользователей;
- База данных должна иметь возможности расширения, на случай расширения сферы деятельности организации;
- База данных должна легко изменяться при изменении программной и аппаратной среды;
- Данные, которые загружаются в базу данных, должны быть корректными, поэтому при добавлении данных должна проводиться проверка вводимых данных;
- Доступ к информации, хранимой в БД должны иметь только лица и сотрудники организации, имеющие на это соответствующие полномочия и должностные обязанности;
- Работа с базой данных не должны вызывать трудностей у пользователей, для этого обязательно нужен дружественных интерфейс.
Реляционная модель базы данных – это такая модель, где БД – совокупность отношений, содержащих всю информацию, которая должна храниться в БД. Однако пользователи могут воспринимать такую базу данных как совокупность таблиц.
Входными данными для проектируемой информационной системы автоматизации процесса планирования закупок и размещению заказов поставщикам выступают данные поставщиков, их прайс-листы и списки товаров для закупа.
Всего в информационной системе используется четыре справочника:
- сотрудники (они же пользователи ИС);
- роли сотрудников;
- статусы заказов;
- единица измерения;
- товар;
- категория товаров;
Выходными данными информационной системы выступают сформированные заказы поставщикам и отчет о работе сотрудников отдела закупа. Также к выходным данным стоит отнести и комментарии, которые сотрудники могут оставлять к тому или иному заказу.
Для каждого заказа, поставщика, товара, категории товара и сотрудника, используются классификаторы, предназначенные для идентификации каждой записи в таблице БД.
Описание используемых классификаторов приведено в таблице 1.
Таблица 1
Используемые идентификаторы
№ пп |
Наименование кодируемого множества объектов |
Значность кода |
Мощность кода |
Система кодирования |
1 |
Идентификационный номер пользователя |
4 |
9999 |
Порядковая |
2 |
Идентификационный номер роли пользователя |
4 |
9999 |
Порядковая |
3 |
Идентификационный номер товара |
4 |
9999 |
Порядковая |
4 |
Идентификационный номер единицы измерения |
4 |
9999 |
Порядковая |
5 |
Идентификационный номер категории товаров |
4 |
9999 |
Порядковая |
6 |
Идентификационный номер заказа |
4 |
9999 |
Порядковая |
7 |
Идентификационный номер комментария к заказу |
4 |
9999 |
Порядковая |
8 |
Идентификационный номер поставщика |
4 |
9999 |
Порядковая |
9 |
Идентификационный номер товара поставщика |
4 |
9999 |
Порядковая |
1.5. Обоснование проектных решений по программному обеспечению
Программное обеспечение - это совокупность программ для реализации целей и задач информационной системы, а также нормального функционирования комплекса технических средств.
В состав программного обеспечения входят общесистемные и специальные программные продукты, в том числе: операционная система, системы программирования, инструментальные средства программиста, тестовые и диагностические программы, программные средства телекоммуникации, защиты информации, функциональное программное обеспечение (автоматизированные рабочие места, системы управления базами данных и т. п.).
Для реализации информационной системы автоматизации взаимоотношений с клиентами необходимо выбрать язык программирования для создания пользовательского интерфейса и систему управления базой данных для создания базы данных.
В качестве языка программирования был выбран язык php.
PHP (PersonalHomePageTools – «Инструмент для создания персональных веб-страниц») – является скриптовым языком программирования общего пользования, используемый для создания Web-приложений. В данный момент времени поддерживают подавляющие большинство хостинг-провайдеров и стал одним из ведущих языком программирования, использующих для разработки динамических Web-сайтов.
Популярность языка в создании web-сайтов определяется наличием большого набора средств предназначенных на разработку web-приложений. Основные из них:
- автоматически извлекаемые GET и POST -параметров, а также переменных окружения веб-сервера в предопределённые массивы;
- взаимодействует с очень большим количеством разныхСУБД (MySQL, SQLite,MySQLi, Oracle (OCI8), PostgreSQL, Microsoft SQL Server и пр.);
- автоматическая отправка HTTP-заголовков;
- работает с HTTP-авторизацией;
- работает с сессиями и cookies;
- работает с удалёнными и локальными файлами, сокетами;
- обрабатывает файлы, загруженные на сервер;
В качестве системы управления базой данных была выбрана СУБД MySQL.
MySQL – разработка шведской компании MySQL AB. СУБД MySQL является программным обеспечением с открытым исходным кодом, распространяемым по лицензии GNU (GPL) и коммерческой лицензии для ситуаций, не подпадающих под действие лицензии GPL.
MySQL поддерживает реляционную модель данных, т. е. представляет собой реляционную СУБД.
Основные достоинства СУБД MySQL:
- Высокое качество – MySQL характеризуется устойчивой работой.
- Наряду с Oracle, MySQL считается одной из самых быстрых СУБД в мире.
- Открытый код доступен для просмотра и модернизации, что позволяет постоянно улучшать программный продукт.
- СУБД MySQL, разработанная с использованием языков C/C++, протестирована на многих платформах, среди которых Windows, Linux, FreeBSD, Mac OS X, OS/2, Solaris и др.
- MySQL поддерживает API (Application Programming Interface, программный интерфейс приложения) для С, C++, Eiffel, Java, Perl, PHP, Python, Ruby и Tcl. MySQL можно успешно применять как для построения Web-страниц с использованием Perl, PHP и Java, так и для работы прикладной программы, созданной с использованием Delphi, Builder C++ или платформы .NET.4
- СУБД MySQL предоставляет широкий выбор типов таблиц, в том числе и сторонних разработчиков, что позволяет реализовать оптимальную для решаемой задачи производительность и функциональность.
- Локализация в MySQL выполнена корректно. У пользователя, как правило, не возникает проблем при обработке русского содержимого БД
2 глава. Проектная часть
2.1. Информационная модель и её описание
Информационной моделью называют схему движения входной, промежуточной и результативной информации и функций предметной области. Также с помощью информационной модели объясняется с помощью каких входных данных (документов) и какой нормативно-справочной информации происходит выполнение основных функций. Информационная модель проектируемой ИС представлена на рисунке 4.
Рисунок 4. Информационная модель
Выполнения функций системы выполняется с помощью специальных форм пользовательского интерфейса.
2.2. Характеристика нормативно-справочной, входной и оперативной информации
В информационной системе используются шесть справочников, характеристики которых приведены в таблице 2.
Таблица 2
Справочники информационной системы
№ пп |
Название справочника |
Ответственный за ведение |
Средний объём справочника в записях |
Среднюю частоту актуализации |
Средний объем актуализации, % |
1 |
Пользователи |
Администратор |
5 |
1 раз в месяц |
20 |
2 |
Роль |
- |
2 |
- |
- |
3 |
Статус заказов |
- |
4 |
- |
- |
4 |
Единица измерения |
Администратор |
4 |
1 раз в год |
25 |
5 |
Товар |
Администратор |
1500 |
1 раз в месяц |
2 |
6 |
Категория товаров |
Администратор |
10 |
1 раз в месяц |
10 |
Справочники ролей пользователей и статусов заказов носят нормативный характер, поэтому их актуализация не требуется. Остальные справочники время от времени необходимо актуализировать.
Реквизитный состав каждого справочника представлен в виде таблицы 3.
Таблица 3
Реквизитный состав справочников информационной системы
№ пп |
Название справочника |
Перечень реквизитов |
1 |
Пользователи |
ФИО логин пароль электронная почта телефон |
2 |
Роль |
наименование |
3 |
Статус заказов |
наименование |
4 |
Единица измерения |
наименование краткое наименование |
5 |
Товар |
наименование описание |
6 |
Категория товаров |
наименование |
Редактирование и ввод новых записей во все справочники осуществляется с помощью специальных форм.
На рисунке 5 изображена форма для работы с записями справочника «Пользователи».
Рисунок 5. Форма Пользователь
Поле для ввода пароля продублировано, это необходимо для того, чтобы исключить возможность опечатки при вводе пароля.
Перед сохранением данных проверяется наличие пользователей с таким же логином (каждый пользователь должен иметь уникальный логин), сложность введенного пароля (минимум одна цифра и один прописной знак).
Формы для работы с записями других справочников имеют аналогичный вид (Рисунок 6-8).
Рисунок 6. Форма Единица Измерения
Рисунок 7. Форма Товар
Рисунок 8. Форма Категория товара
В качестве входных данных для информационной системы выступают и данные о поставщиках, товарах, которые они поставляют, и заказах, для которых менеджеры по закупкам подбирают поставщиков и которые затем формируют. Также к входным данным следует отнести комментарии, которые пользователи оставляют к заказам. Эти данные вводятся в ИС с помощью специальных форм, приведенных на рисунках 9-12.
Рисунок 9. Форма для добавления поставщика
Рисунок 10. Форма для добавления товара поставщика
Рисунок 11. Форма для добавления заказа
Рисунок 12. Форма для добавления комментария
Данные, введенные в формы, которые приведены выше, сохраняются в базе данных и используются для формирования выходных данных.
2.3. Характеристика результатной информации
В качестве выходных данных выступают заказ поставщику и отчет о деятельности сотрудников отдела закупа.
Подробное описание выходных данных представлено в таблице 4.
Таблица 4
Описание результатной информации
Наименование |
Заказ поставщику |
Отчет о деятельности сотрудников |
Реквизиты |
Номер заказа поставщику Наименование поставщика Товары в заказе (наименование, количество, стоимость, общая сумма); Дата формирования; Ответственный сотрудник. |
ФИО сотрудника; Количество назначенных заказов; Количество выполненных заказов; Среднее время выполнения заказа. |
Таблицы, на основе которых формируется |
Заказы Поставщики Товары Категории Пользователи Товары поставщиков |
Заказ поставщику Пользователи Статусы заказа |
Частота формирования |
По мере необходимости |
По мере необходимости |
Способ доставки |
Файл в формате Word |
Таблица на html-странице |
2.4. Общие положения (дерево функций и сценарий диалога)
Базовый набор функций разработанной информационной системы можно изобразить в виде дерева, изображенного на рисунке 13.
Рисунок 13. Дерево функций
Функции ИС можно разделить на основные и служебные. К служебным относятся управление профилем пользователя, авторизация и проверка вводимых данных. К основным функциям системы относятся все функции, которые необходимы для автоматизации исследуемого процесса: от управления справочными данными до работы с заказами и отправки комментариев к заказам.
Выполнение функций разработанной информационной системы осуществляется с помощью ведения диалога с пользователем. То есть пользователь информационной системы выполняет какие-то действия, а программа соответствующим образом на них реагирует. Сценарий диалога с пользователем представлен на рисунке 14.
Рисунок 14. Сценарий диалога
После открытия ИС пользователю необходимо пройти авторизацию с помощью логина и пароля.
После авторизации на сайте пользователь переходит по разделам сайта с помощью навигационного меню. В зависимости от выбранного пункта в меню ему отображается содержимое соответствующего раздела.
2.5. Характеристика базы данных
В качестве системы управления базой данный для разрабатываемой информационной системы была выбрана СУБД Mysql.
Для хранения всех необходимых данных была спроектирована и создана база данных, состоящая из 6 таблиц. ER-модель спроектированной базы данных представлена на рисунке 15.
Рисунок 15. ER-модель базы данных
Описание всех таблиц базы данных представлено в таблице 5.
Таблица 5
Описание таблиц базы данных
Атрибут |
Поле таблицы |
Тип данных |
Размер |
Обязательность значений |
Таблица Product (Товар) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Название |
caption |
varchar |
255 |
Да |
Описание |
description |
text |
65655 |
Нет |
Цена |
price |
decimal |
10 |
Да |
Категория |
categoryid |
integer |
4 |
Да |
Единица измерения |
measureid |
Integer |
4 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Удален |
deleted |
tinyint |
1 |
Нет |
Таблица Measure (Единица измерения) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Наименование |
caption |
varchar |
255 |
Да |
Удален |
deleted |
tinyint |
1 |
Нет |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Краткое название |
short |
varchar |
255 |
Да |
Таблица ProductCategory (Категории товаров) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Наименование |
caption |
varchar |
255 |
Да |
Активна |
active |
tinyint |
1 |
Нет |
Таблица Users (Пользователи) |
||||
Идентификатор |
id |
integer |
4 |
Да |
ФИО |
userfio |
varchar |
255 |
Да |
Логин |
login |
varchar |
255 |
Да |
Пароль |
password |
varchar |
255 |
Да |
Телефон |
phone |
varchar |
255 |
Да |
Почта |
|
varchar |
255 |
Да |
Роль |
roleid |
int |
4 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица Role(Роли) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Название |
caption |
varchar |
255 |
Да |
Таблица Orders (Заказы) |
||||
Номер |
id |
integer |
4 |
Да |
Статус |
statusid |
integer |
4 |
Да |
Дедлайн |
plandate |
datetime |
10 |
Да |
Дата фактического завершения |
factdate |
datetime |
10 |
Да |
Комментарий |
description |
varchar |
255 |
Нет |
Удален |
deleted |
tinyint |
1 |
Нет |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
ВИП |
vip |
tinyint |
1 |
Нет |
Сжатые сроки |
shorttime |
tinyint |
1 |
Нет |
Таблица Orderproduct (Товары в заказах) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Товар |
productid |
integer |
4 |
Да |
Заказ |
orderid |
integer |
4 |
Да |
Комментарий |
comment |
varchar |
255 |
нет |
Количество |
amount |
integer |
4 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица Ordercomment (Комментарии к заказу) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Автор |
authorid |
integer |
4 |
Да |
Заказ |
orderid |
integer |
4 |
Да |
Текст комментария |
description |
varchar |
255 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица Provider (Поставщик) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Название |
caption |
varchar |
255 |
Да |
Описание |
description |
varchar |
255 |
Нет |
Адрес |
address |
varchar |
255 |
Нет |
ФИО контактного лица |
fio |
varchar |
255 |
Нет |
Электронная почта |
|
varchar |
255 |
Нет |
Удален |
deleted |
tinyint |
1 |
Нет |
Активен |
active |
tinyint |
1 |
Нет |
Рейтинг |
rate |
double |
4 |
Нет |
Телефон |
phone |
Varchar |
255 |
Да |
Предоплата по умолч |
defaultprepay |
integer |
4 |
Да |
Срок доставки по умолч |
defaultdelivarytime |
integer |
4 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица Providerproduct (Товары поставщика) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Поставщик |
providerid |
integer |
4 |
Да |
Товар |
productid |
integer |
4 |
Да |
Комментарий |
comment |
varchar |
255 |
Нет |
Удален |
deleted |
tinyint |
1 |
Нет |
Активен |
active |
tinyint |
1 |
Нет |
Предоплата |
prepay |
integer |
4 |
Да |
Срок поставки |
delivarytime |
integer |
4 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица OrderStatus (Статусы заказа) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Название |
caption |
varchar |
255 |
Да |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
Таблица Notifiction (Уведомления) |
||||
Идентификатор |
id |
integer |
4 |
Да |
Пользователь |
userid |
integer |
4 |
Да |
Текст |
desctiption |
varchar |
255 |
Нет |
Новое |
new |
tinyint |
1 |
Нет |
Дата создания |
createdat |
datetime |
10 |
Да |
Дата изменения |
modifiedat |
datetime |
10 |
Да |
2.6. Структурная схема пакета (дерево вызова программных модулей)
Популярность языка php обусловила появление большого числа фреймворков, основанных на нем. Фреймворк – программная платформа, определяющая структуру программной системы; программное обеспечение, облегчающее разработку и объединение разных компонентов большого программного проекта.
Для написания информационной системы использовался фреймворк языка php Symfony 2.
Symfony 2 – самый популярный PHP-фреймворк в мире. Он включает в себя весь набор инструментов, используемый для быстрой разработки веб-приложений, и при этом абсолютно ничего не навязывает создаваемому приложению. Разработчик может быстро начать работу, используя дистрибутив Symfony2.
Данный фреймворк работает с подходом к программированию, называемый Model-view-controller (MVC, «модель-представление-контроллер», «модель-вид-контроллер»).
Основная идея данного подхода заключается в разделении данных, их представлениях и обработку действий пользователей на три больших группы:
- Модель (англ. Model). Модель предоставляет знания: данные и методы работы с этими данными, реагирует на запросы, изменяя своё состояние. Объекты данной группы не содержат информации, как эти знания можно визуализировать.
- Представление, вид (англ. View). Отвечает за отображение информации (визуализацию). Часто в качестве представления выступает форма (окно) с графическими элементами. Главная задача – представить информацию, хранимой в модели в виде, воспринимаемым пользователем.
- Контроллер (англ. Controller). Обеспечивает связь между пользователем и системой: контролирует ввод данных пользователем и использует модель и представление для реализации необходимой реакции.
Общая схема архитектуры ИС согласно данной парадигмы изображена на рисунке 16.
Рисунок 16. Архитектура ИС (Model-view-controller)
Список разработанных программных модулей и их назначений представлен в таблице 6.
Таблица 6
Программные модули.
Название |
Описание |
routing.yml |
Файл с настройками маршрутов для маршрутизатора Symfony |
InitializableController.php |
Класс контроллера, содержащий общие методы для всех контроллеров ИС, является родительским классов для всех остальных контроллеров |
DefaultContoller.php |
Класс контроллера, содержащий методы для отображения главной страницы системы |
MeasureController.php |
Класс контроллера, содержащий методы для отображения данных и форм о единицах измерения товаров, обработки отправленных форм |
OrderController.php |
Класс контроллера, содержащий методы для отображения данных и форм, предназначенных для создания, просмотра заказов и управления ими |
ProductCategoryController.php |
Класс контроллера, содержащий методы для отображения данных и форм о категориях товаров, обработки отправленных форм |
ProductsController.php |
Класс контроллера, содержащий методы для отображения данных и форм о товарах, обработки отправленных форм |
ProviderController.php |
Класс контроллера, содержащий методы для отображения данных и форм о поставщиках, обработки отправленных форм |
SecurityController.php |
Класс контроллера, содержащий методы и функции, необходимые для реализации функций авторизации, выхода из сайта, управления профилем пользователя |
UsersController.php |
Класс контроллера, содержащий методы для отображения данных и форм о пользователях, обработки отправленных форм |
AbstractEntity.php |
Класс модели, содержащий общие методы для всех классов модели данных ИС, является родительским классов для всех остальных классов модели |
Measure.php |
Класс модели, содержащий атрибуты и методы для работы с объектом единицы измерения |
Notification.php |
Класс модели, содержащий атрибуты и методы для работы с объектом уведомления пользователя |
Order.php |
Класс модели, содержащий атрибуты и методы для работы с объектом заказа покупателя |
OrderComment.php |
Класс модели, содержащий атрибуты и методы для работы с объектом комментария к заказу |
OrderProduct.php |
Класс модели, содержащий атрибуты и методы для работы с объектом товара в заказе |
OrderProvider.php |
Класс модели, содержащий атрибуты и методы для работы с объектом поставщика в списке поставщиков заказа |
OrderProviderComment.php |
Класс модели, содержащий атрибуты и методы для работы с объектом комментария к поставщику в списке поставщиков заказа |
OrderStatus.php |
Класс модели, содержащий атрибуты и методы для работы с объектом статуса заказа |
Product.php |
Класс модели, содержащий атрибуты и методы для работы с объектом товара |
ProductCategory.php |
Класс модели, содержащий атрибуты и методы для работы с объектом категории товара |
Provider.php |
Класс модели, содержащий атрибуты и методы для работы с объектом поставщика |
ProviderPhone.php |
Класс модели, содержащий атрибуты и методы для работы с объектом телефона поставщика |
ProviderProduct.php |
Класс модели, содержащий атрибуты и методы для работы с объектом товара поставщика |
Role.php |
Класс модели, содержащий атрибуты и методы для работы с объектом роли пользователя |
User.php |
Класс модели, содержащий атрибуты и методы для работы с объектом пользователя |
AbstractFormType.php |
Класс формы, родительский для всех классов форм ИС |
LoginFormType.php |
Класс формы авторизации |
MeasureFormType.php |
Класс формы управления единицами измерения |
OrderCommentFormType.php |
Класс формы для отправки комментария к заказу |
OrderEndFormType.php |
Класс формы для реализации завершения заказа |
OrderFilterFormType.php |
Класс формы для реализации фильтра в списке заказов |
OrderFormType.php |
Класс формы для создания и управления заказом |
OrderProviderCommentFormType.php |
Класс формы для отправки комментария к поставщику в списке поставщиков заказа |
ProductCategoryFilterFormType.php |
Класс формы для реализации фильтра в списке категорий товаров |
ProductCategoryFormType.php |
Класс формы управления данными категории товаров |
ProductFilterFormType.php |
Класс формы для реализации фильтра в списке товаров |
ProductFormType.php |
Класс формы управления товарами |
ProfileFormType.php |
Класс формы для реализации работы с профилем пользователя |
ProviderFilterFormType.php |
Класс формы для реализации фильтра в списке поставщиков |
ProviderFormType.php |
Класс формы управления поставщиками |
ProviderPhoneFormType.php |
Класс формы управления телефонами поставщика |
ProviderProductFormType.php |
Класс формы управления товарами поставщика |
ReportFormType.php |
Класс формы для ввода параметров отчета по заказам |
UserFilterFormType.php |
Класс формы для реализации фильтра в списке пользователей |
UserFormType.php |
Класс формы для реализации работы с данными пользователя |
Исходный код всех программных модулей с комментариями представлен в приложении.
2.8. Контрольный пример реализации проекта и его описание
После перехода на адрес ИС открывается страница авторизации (Рисунок 17).
Рисунок 17. Страница авторизации в ИС
После прохождения авторизации открывается страница просмотра уведомлений (Рисунок 18).
Рисунок 18. Страница просмотра уведомлений
Все уведомления сортируются по дате их отправки пользователю. Не просмотренные уведомления выделяются с помощью зажирнения. Также в панели навигации, расположенной слева, отображается количество не просмотренных уведомлений напротив соответствующего пункта меню. Переход между разделами ИС осуществляется с помощью этой панели навигации (Рисунок 19).
Рисунок 19. Панель навигации
Стоит отметить, что пункты меню «Отчеты» и «Пользователи» доступны только Администратору (руководителю отдела закупок).
При переходе в раздел заказы отображается список всех заказов, а также форма для поиска нужного заказа и их фильтрации (Рисунок 20).
Рисунок 20. Страница со списком заказов
Для добавления нового заказа необходимо нажать на кнопку «Добавить заказ», откроется форма добавления нового заказа (Рисунок 21).
Рисунок 21. Форма добавления нового заказа
После создания нового заказа он получает статус «Черновик», и он виден в списке только Администратору. С данным заказом может работать только Администратор. Работа заключается в добавлении в заказ товаров, которые необходимо заказать. Товары добавляются на отдельной вкладке с помощью специальной формы (Рисунок 22).
Рисунок 22. Вкладка добавления товаров в заказ
После добавления всех товаров нужно отправить его в работу выбранному менеджеру по закупкам, для этого необходим нажать кнопку «Отправить в работу», статус заказа меняется на «Новый» (Рисунок 23).
Рисунок 23. Кнопка «Отправить в работу»
При отправке заказа в работу менеджеру, назначенному на заказ, приходит уведомление (Рисунок 24).
Рисунок 24. Уведомление менеджеру о назначении его на заказ
Менеджеру необходимо подтвердить принятие заказа в работу, перейдя в него. Для этого на первой вкладке страницы работы с заказами имеется специальная кнопка «Подтвердить принятие в работу», она отображается только тому пользователю, который был назначен на заказ (Рисунок 25).
Рисунок 25. Кнопка «Подтвердить принятие в работу»
После подтверждения принятия заказа в работу его статус меняется на «В работе».
Для того, чтобы автоматически сформировать список потенциальных поставщиков для заказа необходимо перейти на вкладку «Список поставщиков» и нажать на кнопку «Получить список поставщиков» (Рисунок 26).
Рисунок 26. Вкладка «Список поставщиков»
Системой будет сформировать список потенциальных поставщиков для данного заказа на основании списков товаров, которые поставщики могут поставлять. Подбираются поставщики по совпадениям не только по товару, но и по категориям товаров (например, если нужна определенная модель планшета, то в список потенциальных поставщиков попадут также поставщики, которые имеют хоть один товар из категории «Планшеты»). Список поставщиков сортируется по рейтингу (Рисунок 27).
Рисунок 27. Вкладка «Список поставщиков» с сформированным списком
Для просмотра более подробных данных и добавления комментария необходимо нажать на ссылку «Подробнее» напротив нужного поставщика в списке. Откроется форма работы с поставщиком (Рисунок 28).
Рисунок 28. Форма работы с поставщиком для заказа
На данной форме помимо общей информации по поставщику отображается также и информация по каждому продукту из заказа: цена продукта, размер предоплаты, срок поступления и количество выполненных заказом данным поставщиком с данным товаром. Также имеется возможность отправить комментарий именно к данному поставщику в данном заказе.
В нижней части страницы расположены кнопки, с помощью которых можно выбрать поставщика, или скрыть его из списка. Скрытые поставщики опускаются вниз списка и помещаются зачеркиванием. Выбранный поставщик поднимается, наоборот, в верх списка и выделяется зеленым цветом (Рисунок 29).
Рисунок 29. Выбранный и скрытый поставщик в списке
После того, как в заказе выбран поставщик, кнопки скрытия и выбора поставщиков больше не отображаются, а заказ переходит в статус «Ждет подтверждения». Администратору приходит соответствующее уведомление (Рисунок 30), он должен перейти в заказ и подтвердить выбор менеджера.
Рисунок 30. Уведомление администратору о выборе поставщика
После подтверждения выбора заказ переходит в статус «Поставщик выбран, ждет поставки». Менеджер должен зайти в заказ и сформировать его в виде документа Word.
После того, как по данному заказу товары поступят на предприятие, менеджер должен поставить оценку действия поставщика и оставить комментарий с общим впечатлением о работе с поставщиком. На основании оценки будет пересчитан рейтинг поставщика, а комментарий будет отображаться в истории заказов поставщика.
Естественно, чтобы система корректно формировала список потенциальных поставщиков и выбор нужно поставщика был точным и верным, необходимо ввести данные по поставщикам: как общие первичные данные, так и данные по товарам, которые поставщики могут поставлять. Эти данные вводятся в разделе «Поставщики». При переходе в данный раздел открывается форма со списком поставщиков (Рисунок 40).
Рисунок 40. Список поставщиков
Добавление нового поставщика выполняется с помощью формы, вызываемой нажатием на кнопку «Добавить поставщика». Для открытия формы редактирования данных необходимо нажать на имя поставщика в списке, откроется страница, состоящая из нескольких вкладок: общие данные, список товаров, история заказов (Рисунок 41).
Рисунок 41. Страница работы с данными поставщика
На второй вкладке отображается список товаров поставщика (Рисунок 42).
Рисунок 42. Вкладка «Список товаров»
На третьей вкладке – «Список заказов», выполненных данным поставщиком (Рисунок 43).
Рисунок 43. Вкладка «Список заказов»
Список товаров заполняется на основе данных справочников «Товары», «Категории товаров» и «Единицы измерения». Работа с этими справочниками выполняется в соответствующих разделах. При переходе в раздел открывается форма со списком записей справочника, добавление и редактирование товара выполняется с помощью соответствующей формы. На рисунке 44 приведен пример формы редактирования данных товара.
Рисунок 44. Форма работы с данными товара
Раздел формирования отчетов доступен только Администратору. При переходе в него открывается форма ввода интервала, за который необходимо сформировать отчет (Рисунок 45).
Рисунок 45. Форма для ввода интервала формирования отчета
После ввода интервала и нажатия на кнопку «Получить данные» под формой отображается таблица с результатами построения отчета (Рисунок 46).
Рисунок 46. Результат формирования отчета
ЗАКЛЮЧЕНИЕ
В ходе проделанной работы были решены следующие задачи:
- Была проанализирована текущая организация бизнес-процесса планирования закупок и размещения заказов поставщикам в компании ООО «Протек», были выделены основные этапы выполнения бизнес-процесса, изучен возникающий документооборот;
- Были выбран проектные решения по информационному обеспечению и программному, в качестве языка программирования был выбран php , а в качестве СУБД – Mysql;
- Была составлена информационная модель информационной системы, которая отражает пути преобразования входной информации в выходную;
- Была разработана база данных и программные модули, реализующие работу ИС.
- Был описан контрольный пример реализации проекта.
Таким образом, все задачи, поставленные перед данным курсовым проектом выполнены, а значит и основная цель достигнута.
СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
1. ГОСТ 2.105 – 95. Общие требования к текстовым документам.
2. ГОСТ 7.32 – 2001. Отчет по научно-исследовательской работе. Структура и правила оформления.
3. ГОСТ 7.82-2001. Библиографическое описание электронных ресурсов.
4. ГОСТ 24.702-85 Эффективность автоматизированных систем управления.
5. ГОСТ Р 7.0.5-2008. Библиографическая запись. Библиографическое описание.
6. Алистер Коберн, Современные методы описания функциональных требований к системам, М.: издательство "Лори", 2017. – 288 с
9. Дунаев В. HTML, скрипты и стили / В. Дунаев. – Спб. : БХВ-Петербург, 2015. – 816 с.
10. Жадеев А. PHP для начинающих / А. Жадеев. – Спб.: «Питер», 2014. – 592 c.
11. Колисниченко Д. PHP и MySQL. Разработка WEB-приложений / Д. Колисниченков – Спб: БХВ-Петербург, 2013. – 560 с.
12. Конналли Т. Базы данных. Проектирование, реализация и сопровождение. Теория и практика / Т. Коналли, К. Бегг. – М.: Издательский дом «Вильямс», 2013. – 1093 c.
13. Лобова Г. Моделирование и анализ бизнес-процессов SADT. – М.: LAP Lambert Academic Publishing, 2014. – 352 c.
14. Макдональд, М. Созданиец Web-сайта. Недостающее руководство / М. Макдональд. – Спб. : БХВ-Петербург, 2013. – 624 с.
17. Маклаков С.В. BPwin и Erwin. CASE-средства разработки информационных систем / С.В. Маклаков. – М. : ДИАЛОГ–МИФИ, 2014. – 369 c.
18. Тельнов, Ю.Ф. Информационные системы и технологии. Information System and Technologies: науч. издание под ред. Тельнова Ю. Ф. – М: Юнити-Дана, 2012 – 303 с.
19. Флэнаган, Д. Javascript. Подробное руководство / Д. Флэнаган : пер с англ. – М. : Символ-Плюс, 2013. – 1080 с.
ПРИЛОЖЕНИЯ
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Notification;
use AppBundle\Entity\Order;
use AppBundle\Entity\OrderComment;
use AppBundle\Entity\OrderProduct;
use AppBundle\Entity\OrderProvider;
use AppBundle\Entity\OrderProviderComment;
use AppBundle\Entity\OrderStatus;
use AppBundle\Entity\ProviderProduct;
use AppBundle\Entity\User;
use AppBundle\Form\Type\OrderCommentFormType;
use AppBundle\Form\Type\OrderEndFormType;
use AppBundle\Form\Type\OrderFilterFormType;
use AppBundle\Form\Type\OrderFormType;
use AppBundle\Form\Type\OrderProductFormType;
use AppBundle\Form\Type\OrderProviderCommentFormType;
use Doctrine\ORM\Query;
use Sensio\Bundle\FrameworkExtraBundle\Configuration as Config;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
class OrderController extends InitializableController
{
/**
* @return RedirectResponse|Response
* @Config\Route("/orders/index/{pagenum}", name = "site_orders_index", defaults={ "pagenum": "1"})
*/
public function indexAction($pagenum=1)
{
$form=$this->createForm(new OrderFilterFormType());
$caption = null;
$form->handleRequest($this->request);
$ordersquery = $this->getRepository('Order')->createQueryBuilder('o')
->leftJoin('o.specs', 's')
->where('o.deleted = 0')
->orderBy('o.vip', 'DESC')
->addOrderBy('o.status', 'ASC')
->addOrderBy('o.plandate', 'ASC');
$ordersquerycount = $this->getRepository('Order')->createQueryBuilder('o')
->select('COUNT(DISTINCT o.id)')
->leftJoin('o.specs', 's')
->where('o.deleted = 0')
->orderBy('o.plandate', 'DESC');
if ($form->isSubmitted() && $form->isValid()) {
$id = $form->get('id')->getData();
$status=$form->get('status')->getData();
$spec=$form->get('spec')->getData();
}
if (!empty($id)) {
$ordersquery->andWhere('o.id = :id')->setParameter('id', $id);
$ordersquerycount->andWhere('o.id = :id')->setParameter('id', $id);
}
if (!empty($status)) {
$ordersquery->andWhere('o.status = :status')->setParameter('status', $status);
$ordersquerycount->andWhere('o.status = :status')->setParameter('status', $status);
}
if (!empty($spec)) {
$ordersquery->andWhere('s.id = :spec')->setParameter('spec', $spec);
$ordersquerycount->andWhere('s.id = :spec')->setParameter('spec', $spec);
}
$count=$ordersquerycount->getQuery()->getSingleScalarResult();
$pages = floor($count / 20) + ($count % 20 > 0 ? 1 : 0);
if ($pages < 1) $pages = 1;
if ($pagenum > $pages) $pagenum = $pages;
$orders = $ordersquery->setFirstResult(($pagenum - 1) * 20)
->setMaxResults(20)
->getQuery()->getResult();
$this->view['orders'] = $orders;
$this->view['form'] = $form->createView();
$this->view['page']=$pagenum;
$this->view['pages']=$pages;
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:index.html.twig');
}
/**
* @return RedirectResponse|Response
* @Config\Route("/orders/add", name = "site_orders_add")
*/
public function addAction()
{
$order = new Order();
$form = $this->createForm(new OrderFormType(), $order);
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var OrderStatus $newstatus**/
$newstatus = $this->getRepository('OrderStatus')->findOneBy(array('id'=>1));
$order->setStatus($newstatus);
foreach ($order->getSpecs() as $spec) {
$spec->getOrders()->add($order);
}
$this->manager->persist($order);
$this->manager->flush();
$this->addNotice('success',
'orders.html.twig',
array('notice' => 'order_added', 'caption' => $order->getId())
);
return $this->redirectToRoute('site_orders_edit',array('order' => $order->getId(), 'step' => 1));
}
$this->view['order'] = null;
$this->forms['order'] = $form->createView();
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:order1.html.twig');
}
/**
* @param Order $order
* @return RedirectResponse|Response
* @Config\Route("/orders/{order}/edit/{step}", name = "site_orders_edit")
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function editAction(Order $order, $step)
{
if ($step > 4) {
$step = 4;
}
switch ($step) {
//общие данные
case 1:
$form = $this->createForm(new OrderFormType(), $order);
$specs=array();
foreach ($order->getSpecs() as $spec) {
array_push($specs, $spec);
}
$form2 = $this->createForm(new OrderEndFormType());
if ($this->request->isMethod('POST')) {
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
//проверяем был ли добавлен новый специалист и если был - отправляем ему уведомление
foreach ($order->getSpecs() as $spec) {
if (!(in_array($spec,$specs ))) {
$this->addNotification($spec,"Вам назначен заказ №".$order->getId().". <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a>" );
$spec->getOrders()->add($order);
}
}
$specsnew=array();
foreach ($order->getSpecs() as $spec) {
array_push($specsnew, $spec);
}
//проверяем, был ли удален пользователь с заказа, если был - отправляем ему уведомление
foreach ($specs as $spec) {
if (!(in_array($spec,$specsnew ))) {
$this->addNotification($spec,"С Вас было снято назначение на заказ №".$order->getId().". <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a>" );
$spec->getOrders()->removeElement($order);
}
}
$this->manager->persist($order);
$this->manager->flush();
$this->addNotice('success',
'orders.html.twig',
array('notice' => 'order_changed', 'caption' => $order->getId())
);
return $this->redirectToRoute(
'site_orders_edit',
array('order' => $order->getId(), 'step' => 1)
);
}
$form2->handleRequest($this->request);
if ($form2->isSubmitted() && $form2->isValid()) {
//ставим дату
$order->setFactdate($form2->get('factdate')->getData());
//ставим статус
/** @var OrderStatus $newstatus**/
$newstatus = $this->getRepository('OrderStatus')->findOneBy(array('id'=>7));
$order->setStatus($newstatus);
//ищем выбранного поставщика
/** @var OrderProvider $orderprovider */
$orderprovider=$this->getRepository('OrderProvider')->createQueryBuilder('op')
->where('op.order = :order')
->andWhere('op.selected = true')
->setParameters(array('order'=>$order))->getQuery()->getOneOrNullResult();
if ($orderprovider) {
//добавляем коммент
$comment= new OrderProviderComment();
$comment->setUser($this->getUser());
$comment->setOrderprovider($orderprovider);
$comment->setDescription($form2->get('comment')->getData());
$this->manager->persist($comment);
$this->manager->flush();
//обновляем рейтинг
$orderprovider->setBall($form2->get('ball')->getData());
$this->manager->persist($orderprovider);
$newrate=$this->getRepository('OrderProvider')->createQueryBuilder('op')
->select('AVG (op.ball)')
->where('op.provider = :provider')
->andWhere('op.selected = true')
->setParameters(array('provider'=>$orderprovider->getProvider()))
->getQuery()->getSingleScalarResult();
$provider= $orderprovider->getProvider();
$provider->setRate($newrate);
$this->manager->persist($provider);
}
$this->manager->persist($order);
$this->manager->flush();
$this->addNotice('success',
'orders.html.twig',
array('notice' => 'order_ended', 'caption' => $order->getId())
);
//отправляем уведомление админу
/** @var user $adminuser**/
$adminuser = $this->getRepository('User')->findOneBy(array('username'=>'admin'));
$this->addNotification($adminuser,"Пользователь ".$this->getUser()->getUserfio()." завершил заказ №".$order->getId().". <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a>" );
return $this->redirectToRoute('site_orders_index');
}
}
$this->view['order'] = $order;
$this->forms['order'] = $form->createView();
$this->forms['endorder'] = $form2->createView();
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:order1.html.twig');
break;
//список товаров
case 2:
$form = $this->createForm(new OrderProductFormType());
$products=$this->getRepository('OrderProduct')->createQueryBuilder('op')
->leftJoin('op.product','p')
->where('p.deleted <> 1')
->andWhere('op.order = :order')
->setParameters(array('order'=>$order))
->orderBy('p.category')->getQuery()->getResult();
if ($this->request->isXmlHttpRequest() && $this->request->isMethod('POST')) {
return $this->handleProductsAjaxRequest();
}
if ($this->request->isMethod('POST')) {
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
$orderproduct = $form->getData();
$orderproduct->setOrder($order);
$this->manager->persist($orderproduct);
$this->manager->flush();
return $this->redirectToRoute(
'site_orders_edit',
array('order' => $order->getId(), 'step' => 2)
);
}
}
$this->view['order'] = $order;
$this->view['products'] = $products;
$this->forms['orderproduct'] = $form->createView();
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:order2.html.twig');
break;
//список поставщиков
case 3:
$orderproviders=$this->getRepository('OrderProvider')->createQueryBuilder('op')
->leftJoin('op.provider','pr')
->where('op.order = :order')
->orderBy('op.selected', 'DESC')
->addOrderBy('op.active', 'DESC')
->addOrderBy('pr.rate', 'DESC')
->setParameters(array('order'=>$order))
->getQuery()->getResult();
$this->view['order'] = $order;
$this->view['orderproviders'] = $orderproviders;
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:order3.html.twig');
break;
//комментарии
case 4:
$ordercomments=$this->getRepository('OrderComment')->createQueryBuilder('oc')
->where('oc.order = :order')
->orderBy('oc.id')
->setParameters(array('order'=>$order))
->getQuery()->getResult();
$ordercomment=new OrderComment();
$form=$this->createForm(new OrderCommentFormType(),$ordercomment );
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
$ordercomment->setOrder($order);
$ordercomment->setUser($this->getUser());
$this->manager->persist($ordercomment);
$this->manager->flush();
return $this->redirectToRoute(
'site_orders_edit',
array('order' => $order->getId(), 'step' => 4)
);
}
$this->view['order'] = $order;
$this->view['ordercomments'] = $ordercomments;
$this->forms['ordercomment']=$form->createView();
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:order4.html.twig');
break;
}
return $this->redirect('site_orders_index');
}
protected function handleProductsAjaxRequest()
{
$category = $this->request->get('category', null);
if (is_null($category)) return new JsonResponse();
$products=$this->getRepository('Product')->createQueryBuilder('p')
->select('p.id as id')
->where('p.category = :category')
->andWhere('p.deleted=0')
->setParameters(array('category'=> $category))
->getQuery()->getResult(Query::HYDRATE_ARRAY);
return new JsonResponse($products);
}
/**
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/remove", name = "site_orders_remove")
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function removeAction(Order $order)
{
$order->setDeleted(true);
$this->manager->persist($order);
$this->manager->flush();
return $this->redirectToRoute('site_orders_index');
}
//добавление поставщиков к заказу
/**
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/providersadd", name = "site_orders_providers_add")
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function providersaddAction(Order $order)
{
//Формируем массив поставшиков с нужными товарами
$products=$this->getRepository('Product')->createQueryBuilder('p')
->innerJoin('p.orderproducts','op')
->where('op.order = :order')
->setParameters(array('order'=>$order))
->getQuery()
->getResult();
$providersp=$this->getRepository('Provider')->createQueryBuilder('p')
->leftJoin('p.providerproducts','pp')
->where('pp.product IN (:products)')
->setParameters(array('products'=>$products))
->getQuery()
->getResult();
//Формируем поставщиков с нужными категориями товаров
$categories=$this->getRepository('ProductCategory')->createQueryBuilder('pc')
->innerJoin('pc.products', 'p')
->innerJoin('p.orderproducts','op')
->where('op.order = :order')
->setParameters(array('order'=>$order))
->getQuery()
->getResult();
$providersc=$this->getRepository('Provider')->createQueryBuilder('p')
->leftJoin('p.providerproducts','pp')
->leftJoin('pp.product', 'pr')
->where('pr.category IN (:categories)')
->setParameters(array('categories'=>$categories))
->getQuery()
->getResult();
//склеиваем массивы
$providers=array_merge($providersp,$providersc);
//убирем повторения
$providers=array_unique($providers, SORT_REGULAR );
$countpr=0;
$countc=0;
// в цикле добавляем поставщиков к заказам
/** @var User $usersystem**/
$usersystem = $this->getRepository('User')->findOneBy(array('username'=>'system'));
foreach ($providers as $provider){
$orderProvider=new OrderProvider();
$orderProvider->setProvider($provider);
$orderProvider->setOrder($order);
//и добавляем к каждому комментарий
$orderProviderComment = new OrderProviderComment();
if ( in_array($provider,$providersp)) {
$orderProviderComment->setDescription('Совпадение по товарам');
$countpr++;
}
else {
$orderProviderComment->setDescription('Совпадение по категориям');
$countc++;
}
$orderProviderComment->setOrderprovider($orderProvider);
$orderProviderComment->setUser($usersystem);
$this->manager->persist($orderProvider);
$this->manager->persist($orderProviderComment);
$this->manager->flush();
}
//Добавляем коммент о сформированном списке поставщиков
$ordercomment = new OrderComment();
$ordercomment->setUser($usersystem);
$ordercomment->setOrder($order);
$ordercomment->setDescription('Автоматически сформирован список потенциальных поставщиков. Всего: '.count($providers).'. Совпадений по товарам:'.$countpr.'. Совпадений по категориям: '.$countc);
$this->manager->persist($ordercomment);
$this->manager->flush();
return $this->redirectToRoute(
'site_orders_edit',
array('order' => $order->getId(), 'step' => 3)
);
}
/**
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/changestatus/{status}", name = "site_orders_changestatus")
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function changestatusAction(Order $order, $status)
{
$oldstatus=$order->getStatus()->getId();
/** @var OrderStatus $newstatus**/
$newstatus = $this->getRepository('OrderStatus')->findOneBy(array('id'=>$status));
$order->setStatus($newstatus);
//отправляем уведомление пользователю
$descriptiontext='';
$notifusers=$order->getSpecs();
switch ($status) {
case 2:
$descriptiontext="Вам был назначен новый заказ № ".$order->getId().". Не забудьте подтвердить принятие в работу. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a> ";
break;
case 3:
//если перед этим был статус "Ждет подтверждения"
if ($oldstatus==4) {
$descriptiontext="Заказ № ".$order->getId()." был вернут в работу. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a> ";
//отменяем выбор поставщика
foreach ($order->getOrderproviders() as $orderprovider) {
$orderprovider->setSelected(false);
$this->manager->persist($orderprovider);
$this->manager->flush();
}
}
//иначе увеомление админу
else {
$descriptiontext="Пользователь ".$this->getUser()->getUserfio()." принял заказ № ".$order->getId()." в работу. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a> ";
$notifusers=array();
/** @var User $notifuser**/
$notifuser = $this->getRepository('User')->findOneBy(array('username'=>'admin'));
array_push($notifusers,$notifuser );
}
break;
case 5: $descriptiontext="Выбор поставщика в заказе №".$order->getId()." был утвержден. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a>";
break;
case 6: $descriptiontext="Заказ №".$order->getId()." был отменен. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>1))."'>Подробнее</a>";
break;
}
foreach ( $notifusers as $notifuser) {
$this->addNotification($notifuser,$descriptiontext);
}
$this->manager->persist($order);
$this->manager->flush();
$this->addNotice('success',
'orders.html.twig',
array('notice' => 'order_changestatus', 'caption' => $order->getId())
);
return $this->redirectToRoute('site_orders_edit', array('order' => $order->getId(), 'step' => 1));
}
/**
* @param OrderProduct $orderproduct
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/orderproducts/{orderproduct}/remove", name = "site_orderproducts_remove")
* @Config\ParamConverter("orderproduct", options = {"mapping": {"orderproduct": "id"}})
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function removeproductAction(OrderProduct $orderproduct, Order $order)
{
$this->manager->remove($orderproduct);
$this->manager->flush();
return $this->redirectToRoute('site_orders_edit', array('order'=>$order->getId(), 'step'=>2));
}
/**
* @param OrderProvider $orderprovider
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/orderproviders/{orderprovider}/edit", name = "site_orderprovider_edit")
* @Config\ParamConverter("orderprovider", options = {"mapping": {"orderprovider": "id"}})
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function orderproviderAction(OrderProvider $orderprovider, Order $order)
{
//Инфа по продуктам
//в цикле перебираем продукты
$products=array();
$orderproducts=$this->getRepository('OrderProduct')->createQueryBuilder('op')
->leftJoin('op.product', 'p')
->where('op.order = :order')
->andWhere('p.deleted = false')
->setParameters(array('order'=>$order))
->getQuery()->getResult();
foreach ($orderproducts as $orderproduct) {
//собираем в массив данные по каждому
$product=array();
$product['product']=$orderproduct->getProduct();
//запрашиваем цену, предоплату и срок поступления
/** @var ProviderProduct $providerproduct**/
$providerproduct=$this->getRepository('ProviderProduct')->createQueryBuilder('pp')
->where('pp.product = :product')
->andWhere('pp.provider = :provider')
->setParameters(array('product'=>$orderproduct->getProduct(), 'provider'=>$orderprovider->getProvider() ))
->getQuery()->getOneOrNullResult();
//если есть - пихаем в массив
if ($providerproduct) {
$product['price']=$providerproduct->getPrice();
$product['prepay']=$providerproduct->getPrepay();
$product['delivarytime']=$providerproduct->getDelivarytime();
}
else {
$product['price']=null;
$product['prepay']=null;
$product['delivarytime']=null;
}
//запрашиваем сколько заказов было выполнено поставщиком с таким товаром
$countorders = $this->getRepository('Order')->createQueryBuilder('o')
->leftJoin('o.orderproviders','op')
->leftJoin('o.orderproducts', 'opr')
->where('op.provider = :provider')
->andWhere('opr.product = :product')
->andWhere('op.selected =1')
->setParameters(array('provider'=>$orderprovider->getProvider(), 'product'=>$orderproduct->getProduct()))
->getQuery()->getArrayResult();
$countorders=count($countorders);
//если есть - пихаем в массив
$product['countorders']=$countorders;
array_push($products, $product);
}
//Комментарии
$orderprovidercomments = $this->getRepository('OrderProviderComment')->createQueryBuilder('opc')
->where('opc.orderprovider = :orderprovider')
->orderBy('opc.id')
->setParameters(array('orderprovider'=>$orderprovider))
->getQuery()->getResult();
$orderprovidercomment=new OrderProviderComment();
$form=$this->createForm(new OrderProviderCommentFormType(),$orderprovidercomment );
$form->handleRequest($this->request);
if ($form->isSubmitted() && $form->isValid()) {
$orderprovidercomment->setOrderprovider($orderprovider);
$orderprovidercomment->setUser($this->getUser());
$this->manager->persist($orderprovidercomment);
$this->manager->flush();
return $this->redirectToRoute(
'site_orderprovider_edit',
array('order' => $order->getId(), 'orderprovider' => $orderprovider->getId())
);
}
$this->view['order'] = $order;
$this->view['orderprovider'] = $orderprovider;
$this->view['products']=$products;
$this->view['orderprovidercomments'] = $orderprovidercomments;
$this->forms['orderprovidercomment']=$form->createView();
$this->navigation = array('active' => 'orders');
return $this->render('AppBundle:Orders:orderprovider.html.twig');
}
//скрытие заказа
/**
* @param OrderProvider $orderprovider
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/orderproviders/{orderprovider}/disabled", name = "site_orderprovider_disabled")
* @Config\ParamConverter("orderprovider", options = {"mapping": {"orderprovider": "id"}})
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function orderproviderdisapledAction(OrderProvider $orderprovider, Order $order)
{
$orderprovider->setActive(false);
$this->manager->persist($orderprovider);
$this->manager->flush();
return $this->redirectToRoute(
'site_orderprovider_edit',
array('order' => $order->getId(), 'orderprovider' => $orderprovider->getId())
);
}
//Открытие заказа
/**
* @param OrderProvider $orderprovider
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/orderproviders/{orderprovider}/enabled", name = "site_orderprovider_enabled")
* @Config\ParamConverter("orderprovider", options = {"mapping": {"orderprovider": "id"}})
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function orderproviderenapledAction(OrderProvider $orderprovider, Order $order)
{
$orderprovider->setActive(true);
$this->manager->persist($orderprovider);
$this->manager->flush();
return $this->redirectToRoute(
'site_orderprovider_edit',
array('order' => $order->getId(), 'orderprovider' => $orderprovider->getId())
);
}
//выбор заказа
/**
* @param OrderProvider $orderprovider
* @param Order $order
* @return Response
* @Config\Route("/orders/{order}/orderproviders/{orderprovider}/selected", name = "site_orderprovider_selected")
* @Config\ParamConverter("orderprovider", options = {"mapping": {"orderprovider": "id"}})
* @Config\ParamConverter("order", options = {"mapping": {"order": "id"}})
*/
public function orderproviderselectedAction(OrderProvider $orderprovider, Order $order)
{
$orderprovider->setSelected(true);
/** @var OrderStatus $newstatus**/
$newstatus = $this->getRepository('OrderStatus')->findOneBy(array('id'=>4));
$order->setStatus($newstatus);
/** @var user $adminuser**/
$adminuser = $this->getRepository('User')->findOneBy(array('username'=>'admin'));
//отправляем уведомление пользователю
$notificationtext="Пользователь".$this->getUser()->getUserfio()." выбрал поставщика для заказа № ".$order->getId().". Необходимо подтвердит результат. <a href='".$this->generateUrl('site_orders_edit', array('order'=>$order->getId(), 'step'=>3))."'>Подробнее</a> ";
$this->addNotification($adminuser, $notificationtext);
$this->manager->persist($order);
$this->manager->flush();
return $this->redirectToRoute(
'site_orders_edit',
array('order' => $order->getId(), 'step' => 3)
);
}
public function addNotification (User $user, $description) {
$notification = new Notification();
$notification->setUser($user);
$notification->setDescription($description);
$this->manager->persist($notification);
$this->manager->flush();
}
}
- Классификация складских помещений
- Основные подходы к построению систем искусственного интеллекта (Определение сфер применения систем искусственного интеллекта)
- Средства разработки клиентских программ (Анализ представленных в России возможностей подачи жалоб на проблемы в сфере ЖКХ)
- История развития средств вычислительной техники (История развития поколения ПК)
- Разработка регламента выполнения процесса «Учет предоставленных услуг салоном красоты» (Разработка диаграмм)
- Организационная структура управления портфелем проектов
- Налоговая декларация в налоговом учете (Понятие налогового учета )
- Роль мотивации в поведении организации ( Потребности человека по А.Маслоу)
- «Мотивация»
- Организация и развитие коммерческой деятельности предприятий на рынке товаров и услуг (Основные теоретические подходов к определению сущности коммерческой деятельности )
- Перспективы развития спортивного маркетинга (ЦЕННОСТНО-ДЕЯТЕЛЬНОСТНАЯ СИСТЕМА КООРДИНАТ В СПОРТИВНОМ МАРКЕТИНГЕ)
- Классификация, структура и основные характеристики современных микропроцессоров ПК.Курсовая работа (Облачные сервисы: характеристики)