Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Проектирование реализации операций бизнес-процесса. Планирование закупок и размещение заказов поставщикам

Содержание:

ВВЕДЕНИЕ

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

Это обусловлено в первую очередь большой производительностью и широким функционалом современных программ. Они позволяют не только хранить данные и формировать шаблонные документы, но и дают возможность составления различных прогнозов, помогают решать задачи планирования деятельности и управления как всем предприятием, так и отдельными его подразделениями.

Однако, не смотря на бурное развитие информационных технологий и повсеместное их внедрение, всегда остаются небольшие участки производственного процесса, которые либо плохо автоматизированы, либо не автоматизированы вовсе. Такие слабо автоматизированные участки имеют более низкую производительность труда, что отрицательно сказывается на общей производительности труда на предприятии.

Цель курсовой работы – проектирование информационной системы для реализации бизнес-процесса «Планирование закупок и размещение заказов поставщикам» на примере компании ООО «АвтоХаус».

Для достижения поставленной цели необходимо решить следующие задачи:

  • Охарактеризовать существующие бизнес-процессы и выявить необходимость их автоматизации;
  • Выбрать комплекс задач автоматизации и стратегию разработки ИС для компани ООО «АвтоХаус»;
  • Дать обоснование проектных решений;
  • Подробно описать проект разработки проекта ИС.

1 Глава. Аналитическая часть

1.1. Выбор комплекса задач автоматизации

Фирменное наименование общества: Общество с ограниченной ответственностью «АвтоХаус».

Официальное сокращенное наименование общества: ООО «АвтоХаус».

Юридический адресат нахождения общества: Обществовед с ограниченной ответственностью «АвтоХаус» создано в соответствии с Гражданским кодексом Российской Федерации и Федеральным законом Российской Федерации «Об обществах с ограниченной ответственностью». Магазин ООО «АвтоХаус» работает с 2006 года, специализируясь на продажах автомобильных шина и дисков.

Целями деятельности ООО «АвтоХаус» являются расширение рынка товаров и услуг, а также извлечение прибыли.

Предметом деятельности ООО «АвтоХаус» является закуп и реализация дисков и шин для автомобилей. ООО «АвтоХаус» предлагает автомобильные шины и диски ведущих мировых брендов (легковые шины Nokian Tyres, Michelin, Bridgestone, Goodyear, Dunlop; литые диски Kosei, LS Репликар). Продажа шин и дисков осуществляется оптом и в розницу.

Сегодня ООО «АвтоХаус» занимает стабильное положение на рынке автомобильных шин и имеет все возможности для успешного развития и роста. Основными приоритетами деятельности ООО «АвтоХаус» является взаимовыгодное сотрудничество и высокий стандарт качества предлагаемых товаров.

ООО «АвтоХаус» дорожит своей репутацией на рынке и работает напрямую с производителями товаров, в том числе и зарубежными, с которыми заключены долгосрочные соглашения о сотрудничестве.

Над текущий момент компания не применяет системы управления предприятием, однако активно использует программный пакет офисного ПО MS Office: MS Word, MS Excel. При этом в качестве информационных каналов для отправки и получения информации существуют:

  • электронная почта;
  • факс;
  • доставка курьером;
  • обычная почта.

В качестве автоматизируемой деятельности была выбрана деятельность отдела закупок, которая заключается в планировании закупок и размещении заказов поставщикам автомобильных шин и дисков.

1.2. Характеристика существующих бизнес – процессов

Для того, чтобы выделить основные бизнес-процессы, составляющие деятельность отдела закупок, воспользуемся функционально-структурным моделированием деятельности. В качестве основной методологии выступает IDEF0.

Данная методология описания бизнес-процессов предполагает указание не только входов и выходов, но дополнительных входов. Всего в данном стандарте выделяют три типа входа: первый так и называется вход, второй – управлением, а третий – механизмами.

Стандарт IDEF0 регламентирует с помощью входа (первый тип входных данных) показывать объекты, которые преобразуются в данным бизнес-процессе, это могут быть информационные и материальные потоки. С помощью управления (второй тип) показывают объекты, которые управляют выполнением бизнес-процессам. С помощью механизмов (третий тип) необходимо показывать объекты, которые непосредственно осуществляют данный бизнес-процесс: сотрудники, технические средства, информационный системы. На выходе бизнес процесса показывают результат выполнения данного бизнес-процесса.

На первом этапе построения IDEF0-модели система представляется как единое целое. Основная цель данного этапа – выявить входные и выходные данные, а также механизмы и правила для данной системы. Диаграмма данного этапа называется контекстной, которая изображена на рисунке 1 (для построения диаграмм использовалось CASE- средство AllFusion Process Modeler 7).

Рисунок 1. Контекстная диаграмма деятельности отдела закупок

По мере необходимости сотрудники отделов составляют заявки в отдел закупок о потребностях в тех или иных товарах, которые и выступают в роли входных данных, стоит отметить, что помимо заказа продаваемых товаров у поставщиков отдел закупок также организует закупку и расходных материалов (канцелярия, фирменные паке, спецодежда сотрудников, компьютерная и офисная техника и т.п.). Также в качестве входных данных деятельности отдела закупок выступают данные поставщиков и их прайс-листы, которые запрашиваются у них по мере необходимости, либо присылаются поставщиками самостоятельно при изменении каких-либо данных. Кроме того, ежемесячные отчеты о расходовании и продажах товаров и материалов также необходимы для реализации деятельности отдела закупок.

Выходными данными выступают заказы поставщикам на поставку товаров. Всю деятельность выполняют сотрудники отдела закупок: руководитель и менеджеры.

Следующий этап построения структурно-функциональной модели в нотации IDEF0 – декомпозиция контекстной диаграммы на составляющие. Диаграмма декомпозиции исследуемой деятельности приведена на рисунке 2.

Рисунок 2. Диаграмма декомпозиции

Деятельность отдела закупок можно разделить на четыре этапа:

  • планирование закупок (выполняется руководителем);
  • распределение заявок среди менеджеров (выполняется руководителем);
  • оформление заказов поставщикам (выполняется менеджерами по закупкам);
  • формирование договора на поставку (выполняется руководителем отдела закупок).

Договор передается в бухгалтерию, сотрудники которой оплачивают указанные в нем товары по необходимым реквизитам. Затем вместе с платежным поручением отправляется поставщику.

1.3. Характеристика документооборота, возникающего при решении задачи

В процессе выполнения бизнес-процесса планирования закупок и размещения заказов поставщикам формируется основной документ – это заказ поставщику. Сначала он выглядит в виде обычного списка товаров, которые необходимо заказать. Затем, менеджеры по закупкам подбирают поставщика для этого списка (поставщиков может быть несколько), после чего создают заказ и отправляют его в бухгалтерию для оплаты и поставщику для отправки товаров.

Схема документооборота приведена на рисунке 3.

Рисунок 3. Схема документооборота заказа поставщику

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 изображена форма для работы с записями справочника «Пользователи».

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-30-00.png

Рисунок 5. Форма Пользователь

Поле для ввода пароля продублировано, это необходимо для того, чтобы исключить возможность опечатки при вводе пароля.

Перед сохранением данных проверяется наличие пользователей с таким же логином (каждый пользователь должен иметь уникальный логин), сложность введенного пароля (минимум одна цифра и один прописной знак).

Формы для работы с записями других справочников имеют аналогичный вид (Рисунок 6-8).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-30-30.png

Рисунок 6. Форма Единица Измерения

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-31-13.png

Рисунок 7. Форма Товар

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-31-44.png

Рисунок 8. Форма Категория товара

В качестве входных данных для информационной системы выступают и данные о поставщиках, товарах, которые они поставляют, и заказах, для которых менеджеры по закупкам подбирают поставщиков и которые затем формируют. Также к входным данным следует отнести комментарии, которые пользователи оставляют к заказам. Эти данные вводятся в ИС с помощью специальных форм, приведенных на рисунках 9-12.

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-32-23.png

Рисунок 9. Форма для добавления поставщика

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-32-55.png

Рисунок 10. Форма для добавления товара поставщика

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-33-18.png

Рисунок 11. Форма для добавления заказа

C:\Users\Mixa\YandexDisk\Скриншоты\2017-10-30_12-34-17.png

Рисунок 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

Да

Почта

email

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

Нет

Электронная почта

email

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).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_18-30-05.png

Рисунок 17. Страница авторизации в ИС

После прохождения авторизации открывается страница просмотра уведомлений (Рисунок 18).

Рисунок 18. Страница просмотра уведомлений

Все уведомления сортируются по дате их отправки пользователю. Не просмотренные уведомления выделяются с помощью зажирнения. Также в панели навигации, расположенной слева, отображается количество не просмотренных уведомлений напротив соответствующего пункта меню. Переход между разделами ИС осуществляется с помощью этой панели навигации (Рисунок 19).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_18-29-37.png

Рисунок 19. Панель навигации

Стоит отметить, что пункты меню «Отчеты» и «Пользователи» доступны только Администратору (руководителю отдела закупок).

При переходе в раздел заказы отображается список всех заказов, а также форма для поиска нужного заказа и их фильтрации (Рисунок 20).

Рисунок 20. Страница со списком заказов

Для добавления нового заказа необходимо нажать на кнопку «Добавить заказ», откроется форма добавления нового заказа (Рисунок 21).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_18-41-02.png

Рисунок 21. Форма добавления нового заказа

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

Рисунок 22. Вкладка добавления товаров в заказ

После добавления всех товаров нужно отправить его в работу выбранному менеджеру по закупкам, для этого необходим нажать кнопку «Отправить в работу», статус заказа меняется на «Новый» (Рисунок 23).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_18-57-05.png

Рисунок 23. Кнопка «Отправить в работу»

При отправке заказа в работу менеджеру, назначенному на заказ, приходит уведомление (Рисунок 24).

Рисунок 24. Уведомление менеджеру о назначении его на заказ

Менеджеру необходимо подтвердить принятие заказа в работу, перейдя в него. Для этого на первой вкладке страницы работы с заказами имеется специальная кнопка «Подтвердить принятие в работу», она отображается только тому пользователю, который был назначен на заказ (Рисунок 25).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_18-58-51.png

Рисунок 25. Кнопка «Подтвердить принятие в работу»

После подтверждения принятия заказа в работу его статус меняется на «В работе».

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

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_19-00-19.png

Рисунок 26. Вкладка «Список поставщиков»

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

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_19-10-03.png

Рисунок 27. Вкладка «Список поставщиков» с сформированным списком

Для просмотра более подробных данных и добавления комментария необходимо нажать на ссылку «Подробнее» напротив нужного поставщика в списке. Откроется форма работы с поставщиком (Рисунок 28).

Рисунок 28. Форма работы с поставщиком для заказа

На данной форме помимо общей информации по поставщику отображается также и информация по каждому продукту из заказа: цена продукта, размер предоплаты, срок поступления и количество выполненных заказом данным поставщиком с данным товаром. Также имеется возможность отправить комментарий именно к данному поставщику в данном заказе.

В нижней части страницы расположены кнопки, с помощью которых можно выбрать поставщика, или скрыть его из списка. Скрытые поставщики опускаются вниз списка и помещаются зачеркиванием. Выбранный поставщик поднимается, наоборот, в верх списка и выделяется зеленым цветом (Рисунок 29).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_19-29-17.png

Рисунок 29. Выбранный и скрытый поставщик в списке

После того, как в заказе выбран поставщик, кнопки скрытия и выбора поставщиков больше не отображаются, а заказ переходит в статус «Ждет подтверждения». Администратору приходит соответствующее уведомление, он должен перейти в заказ и подтвердить выбор менеджера.

После подтверждения выбора заказ переходит в статус «Поставщик выбран, ждет поставки». Менеджер должен зайти в заказ и сформировать его в виде документа Word.

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

Естественно, чтобы система корректно формировала список потенциальных поставщиков и выбор нужно поставщика был точным и верным, необходимо ввести данные по поставщикам: как общие первичные данные, так и данные по товарам, которые поставщики могут поставлять. Эти данные вводятся в разделе «Поставщики». При переходе в данный раздел открывается форма со списком поставщиков (Рисунок 39).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_19-48-46.png

Рисунок 39. Список поставщиков

Добавление нового поставщика выполняется с помощью формы, вызываемой нажатием на кнопку «Добавить поставщика». Для открытия формы редактирования данных необходимо нажать на имя поставщика в списке, откроется страница, состоящая из нескольких вкладок: общие данные, список товаров, история заказов (Рисунок 40).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_19-49-07.png

Рисунок 40. Страница работы с данными поставщика

На второй вкладке отображается список товаров поставщика (Рисунок 41).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_20-06-22.png

Рисунок 41. Вкладка «Список товаров»

На третьей вкладке – «Список заказов», выполненных данным поставщиком (Рисунок 42).

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_20-06-05.png

Рисунок 42. Вкладка «Список заказов»

Список товаров заполняется на основе данных справочников «Товары», «Категории товаров» и «Единицы измерения». Работа с этими справочниками выполняется в соответствующих разделах. При переходе в раздел открывается форма со списком записей справочника, добавление и редактирование товара выполняется с помощью соответствующей формы. На рисунке 43 приведен пример формы редактирования данных товара.

C:\Users\Mixa\YandexDisk\Скриншоты\2017-05-29_20-08-43.png

Рисунок 43. Форма работы с данными товара

Раздел формирования отчетов доступен только Администратору. При переходе в него открывается форма ввода интервала, за который необходимо сформировать отчет (Рисунок 44).

Рисунок 44. Форма для ввода интервала формирования отчета

После ввода интервала и нажатия на кнопку «Получить данные» под формой отображается таблица с результатами построения отчета (Рисунок 45).

Рисунок 45. Результат формирования отчета

ЗАКЛЮЧЕНИЕ

В ходе проделанной работы были решены следующие задачи:

  • была проанализирована текущая организация бизнес-процесса планирования закупок и размещения заказов поставщикам в компании ООО «АвтоХаус», были выделены основные этапы выполнения бизнес-процесса, изучен возникающий документооборот;
  • были выбран проектные решения по информационному обеспечению и программному, в качестве языка программирования был выбран 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();
}

}