70343

Разработка программного обеспечения (ПО) для системы он-лайн продаж строительных материалов на примере ОАО «Гродненский комбинат строительных материалов»

Дипломная

Информатика, кибернетика и программирование

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

Русский

2015-01-11

5.21 MB

13 чел.

СОДЕРЖАНИЕ 

[1]
1 Обзор состояния вопроса

[2]
2 Постановка задачи проектирования

[3]
3 Проектирование базы данных

[3.0.1] 3.2 Построение концептуальной модели данных

[3.0.2] 3.3 Логическое моделирование

[3.0.3] 3.3.1 Построение логической модели данных

[3.0.4] 3.3.2 Разработка диаграмм вариантов использования

[3.0.5] 3.3.3 Построение диаграмм состояний

[3.0.6] 3.3.4 Разработка макетов экранных форм

[3.0.7] 3.4.1 Выбор среды разработки, языка программирования и инструментальных средств разработки

[3.0.8] 3.4.2 Построение физической модели данных

[3.0.9] 3.4.3 Построение диаграмм компонентов

[3.0.10] 4.1 Назначение и описание компонентов программного обеспечения, и их исходные тексты

[3.0.11] 4.2 Тестирование программного обеспечения

[4]
5 Руководство пользователя

[5]
6 Определение экономической эффективности разработки программного обеспечения

[5.0.1] 7.2.1 Требования к помещениям вычислительного центра

[5.0.2] 7.2.2 Микроклимат в помещениях вычислительного центра

[5.0.3] 7.2.3 Шум и вибрация в помещениях вычислительного центра

[5.0.4] 7.2.4 Электромагнитные излучения

[5.0.5] 7.2.5 Производственное освещение

[5.0.6] 7.2.6 Организация рабочего места программиста

[6]
Список использованных источников

[6.0.1]
Приложение А
Концептуальная, логическая и физическая модели данных    

[6.0.2]
Приложение Б
Листинг программы      

[6.0.3] Приложение В
Листинг хранимых процедур базы данных    

[6.0.4] Приложение Г
Примеры пользовательского интерфейса    

[6.0.5]
Приложение Д
Опись листов графической части дипломного проекта    


Введение

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

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

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

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

Целью дипломного проекта является разработка программного обеспечения (ПО) для системы он-лайн продаж строительных материалов на примере ОАО «Гродненский комбинат строительных материалов».

Задачи дипломного проекта:

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

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

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

В разделе «Постановка задачи» приводится постановка основной задачи и перечень решаемых в работе подзадач.

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

Четвертый раздел – «Реализация и тестирование программного обеспечения» – здесь будут описываться все методы испытаний данной программы, принцип, по которому проводились испытания каждого пункта меню, каждой операции и общей надежности программы.

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

В «Экономическом разделе» будут рассчитаны затраты на разработку программного продукта и его экономическая эффективность.

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

Завершит пояснительную записку раздел «Заключение», который будет содержать краткую формулировку задачи и пути ее решения, а также методы и средства, используемые для ее осуществления.

К пояснительной записке будет прилагаться список литературы, который отобразит информационные источники, используемые при написании программы.

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

Графическая часть будет содержать модель данных, функциональную модель, схему работы системы.

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


1 Обзор состояния вопроса

1.1 Понятие и сущность Интернет-магазина

Интернет-магазин – это сайт, содержащий подробный каталог товаров с описанием и изображением. Основное отличие от обычного Интернет-каталога состоит в том, что товары представленные в электронном магазине можно не только увидеть, но и заказать, не вставая с места.

Существует несколько типов Интернет-магазинов:

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

Для всех электронных магазинов свойственен определенный обязательный набор элементов, таких как:

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

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

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

Интернет-магазин имеет следующие преимущества:

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

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

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

Несмотря на кажущиеся технические сложности, создать Интернет-магазин проще и дешевле. К тому же «он-лайн» магазин будет хорошим дополнением и рекламой «офф-лайновой» деятельности. А главное – покупателями станут те, у кого по каким-то причинам нет возможности или времени выйти в обычный магазин, да и те счастливцы, кто познал прелесть покупки, не вставая с места. Таких людей становится все больше и больше.

1.2 Обзор существующих решений для Интернет-магазинов строительных материалов

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

  1.  Интернет-магазины стройматериалов. Их ассортимент может быть от сверхширокого до узкоспециализированного, когда магазин продает исключительно изделия из натурального камня или керамическую плитку. Это наиболее многочисленная группа сайтов в белорусском интернете. Возможен вариант, когда продажа стройматериалов - это только один из разделов ассортимента Интернет-магазина.
  2.  Сайты-визитки строительных организаций или магазинов. Это, как правило, ресурсы с доменом третьего уровня и на бесплатном хостинге с незатейливым дизайном. Чаще всего такие ресурсы создаются как визитки на каком-либо информационно-справочном портале. Не лишне упомянуть и о национальных белорусских каталогах TUT.BY и ALL.BY. Попадание в эти каталоги абсолютно бесплатное и единственное условие – сайт должен быть ориентирован на белорусскую аудиторию. Такая позиция позволяет предоставить пользователям наиболее качественный каталог.

Во всех Интернет-магазинах торгующих строительными материалами оплата товара производится двумя способами: оплата наличными и оплата кредитными картами VISA, EuroCard, MasterCard и др.

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

Способы доставки, которые используют белорусских Интернет-магазины строительных материалов:

  •  местные, региональные и собственные службы доставки;
  •  самовывоз.

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

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

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

Таким образом, при разработке программного обеспечения для системы он-лайн продаж строительных материалов для ОАО «Гродненский комбинат строительных материалов» необходимо учесть, указанный выше обязательный набор элементов для разработки Интернет-магазинов, используя программирование на стороне сервера, реализуемое с помощью языка PHP и СУБД MySQL.

1.3 Обзор литературных источников

Для реализации цели дипломного проекта будет использована литература по следующим взаимосвязанным направлениям (непосредственно применяемых при создании программного комплекса):

  •  проектирование и создание баз данных, с помощью MySQL;
  •  программирование в средах HTML, PHP.

Вопрос разработки баз данных наиболее хорошо раскрыт изданиями, перечисленными ниже.

В книге Гизберта Дамашке «PHP и MySQL» описываются приемы создания привлекательных веб-сайтов с помощью РНР 5 и MySQL. Предельно понятные пояснения и поэтапное изложение материала делают ее весьма полезной для начинающих веб-дизайнеров. Книга поможет самостоятельно создавать различные приложения для сайта - счетчик посетителей, гостевую книгу, небольшую систему управления содержимым сайта и многое другое [15].

Джойс Парк, Кларк Морган и Тим Конверс являются авторами еще одного издания посвященного разработке баз данных – «PHP 5 и MySQL. Библия пользователя». В книге приведены исчерпывающие сведения по созданию динамических веб-узлов на основе программных средств, предоставляемых бесплатно в общее пользование (языка PHP, сервера Apache и СУБД MySQL), а также показано, как обеспечить бесперебойную эксплуатацию таких узлов под управлением операционной системы Windows или Linux [22]. Многочисленные сценарии и готовые программы, представленные в книге, подробно описаны, тщательно прокомментированы и составляют основу практически значимых приложений. Книга дополняет оперативную документацию, содержит все необходимые справочные данные и рассчитана на широкий круг читателей.

Современная книга «PHP 5/6 и MySQL 6. Разработка веб-приложений» российского автора Дениса Колисниченко на практических примерах описывает разработку веб-приложений на языке РНР версий 5 и 6. Большая часть кода примеров совместима с обеими версиями РНР, но особое внимание уделено новым функциям РНР 6. Даны начала программирования на РНР: установка и настройка РНР и MySQL, выбор редактора РНР-кода, основы синтаксиса и самые полезные функции РНР. Рассмотрено создание собственного движка сайта и ряда дополнительных модулей - фотогалереи, RSS-граббера, модуля для работы с МРЗ, модуля продажи недвижимости, гостевой книги, а также применение мощного шаблонизатора Smarty и создание простейшего собственного шаблонизатора [18].

Другое важное направления в работе с базами данных это эффективное использование SQL-запросов. По данной тематике также существует небольшое количество переведенных изданий, и практически полностью отсутствуют работы российских авторов. Однако в последнее время и в нашей стране в связи с беспрецедентным господством во всем мире систем на платформе «клиент/сервер» для промышленных СУБД, наблюдается повышение интереса к литературе по SQL и управлению реляционными базами данных. Одним из лучших изданий на сегодня здесь является книга Д.С. Боумана «Практическое руководство по SQL». Автор этой книги считает, что она поможет даже в тех случаях, когда бесполезно самое лучшее руководство пользователя. Здесь раскрываются темы, которые часто пропускаются или очень кратко описаны в стандартных руководствах пользователя - структуры базы данных, индексация, подзапросы, виртуальные таблицы, производительность и целостность данных [1].

Еще одним изданием по данной тематике является книга «SQL» Мартина Грабера. Она подойдет для всех, кто программирует на SQL. Эта книга предлагает практический подход к освоению языка запросов и программирования. Изучение SQL происходит в процессе его использования - создавая приложения баз данных, администрируя базы данных и работая с данными в интерактивном режиме. Четкое и ясное изложение автором основ технологии реляционных баз данных позволит овладеть подходом к максимально эффективному решению задач, связанных с применением SQL. В книге дано подробное описание языка, поэтому от читателя не требуется никакой предварительной подготовки. Сопровождаемая практическими учебными материалами, книга представляет собой полное справочное руководство по SQL [14].

Рассмотрим источники, посвященные PHP.

«PHP в примерах» Холзнера – одна из популярных книг, посвященных программированию на РНР. В рамках данной книги автору удалось, начав с основ языка РНР, охватить весьма широкий круг вопросов – от объектно-ориентированного программирования до сложной обработки веб-форм, от сохранения данных сеанса работы до формирования e-mail. Теоретический материал излагается в компактной и сжатой форме. И основное место отдано практическим примерам использования богатых возможностей РНР [29].

Книга известного автора в области разработки веб-приложений Джона Коггзолла «PHP 5. Полное руководство» посвящена новой версии самого популярного в настоящее время языка написания сценариев для сервера — РНР 5. Этот язык позволяет разрабатывать высокопроизводительные веб-сайты любого масштаба и любой категории сложности. В книге подробно рассматриваются такие вопросы, как базовые синтаксические конструкции языка, объектно-ориентированное программирование на РНР, работа с базами данных и графическими изображениями, а также построение WAP-содержимого. Большое внимание уделяется эффективным решениям типовых практических задач, среди которых аутентификация посетителей, шифрование данных, использование сеансов, обработка ошибок, работа с электронной почтой. Книга изобилует множеством примеров, которые доступны для загрузки на веб-сайте издательства [17].

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

Вопросам разработки веб-дизайна с использованием различных платформ посвящено множество книг и статей, однако можно отметить следующее издание: «Искусство веб-дизайна. Самоучитель» Джеффри Вина. В книге рассматриваются основные проблемы, с которыми каждый день сталкивается любой разработчик электронных страниц. Основное внимание уделено принципам классического и современного дизайна и их применению в области веб-разработки. Своеобразие авторского стиля, логичность и последовательность изложения, подчеркнутый отказ от технических деталей выделяют эту книгу из целого ряда изданий, посвященных проблемам веб-разработки [3].

Билл Скотт и Тереза Нейл авторы книги «Проектирование веб-интерфейсов» - специалисты по проектированию пользовательских интерфейсов - предлагают более 75 шаблонов проектирования взаимодействия для создания собственных удобных и привлекательных веб-приложений. Приводимые шаблоны иллюстрируют шесть ключевых принципов проектирования, позволяющих в полной мере использовать возможности современных веб-технологий и обеспечить эффективность процесса взаимодействия с пользователем. Обсуждается и ряд антишаблонов, которых следует избегать при проектировании интерфейсов [26].

При проектировании программного обеспечения будет использована книга «Проектирование баз данных» Л.В. Рудиковой, в которой рассматриваются различные аспекты, касающиеся проектирования баз данных: изучение предметной области, инфологическое моделирование, создание концептуальной модели базы данных и физическое моделирование и основы языка SQL [24].


2 Постановка задачи проектирования

2.1 Основные цели и задачи проектирования

В дипломном проекте предполагается разработка программного обеспечения информационной системы он-лайн продаж строительных материалов с использованием динамических элементов.

Исходя из выше указанной цели, можно выделить следующие задачи.

  •  Выбор программного обеспечения. Необходимо выбрать программное обеспечение, которое позволит в полной мере реализовать поставленные задачи.
  •  Определение состава исходных данных. База данных должна иметь логическую структуру, содержать информацию, необходимую администратору сайта. Данные должны храниться в клиент/серверной базе данных.
  •  Создание каталога. Структура каталога должна быть четко спроектирована, так как он является основой системы он-лайн заказов. Определить способы обновления каталогов еще на этапе проектирования.
  •  Разработка интерфейсной части проекта. Необходимо обеспечить удобную форму просмотра информации. Грамотно определить оптимальную систему авторизации пользователей. Правильно сформировать структуру страниц Интернет-магазина с целью уместить как можно больше позиций на странице. Обеспечить возможность поиска, добавления, удаления, просмотра, корректировки информации.
  •  Оформление дизайна сайта. Должен чувствоваться стиль, который будет соответствовать выбранной тематике. Все страницы сайта должны быть выдержаны в одном стиле. Формирование результатов поиска должно осуществляться динамически.
  •  Осуществление пожеланий пользователей. Вся работа должна быть ориентирована на конечного потребителя. Сайт должен включать в себя не только авторские задумки, но и пожелания пользователей. Учесть, что сделки могут совершать как физические, так и юридические лица.

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

Следовательно, можно выделить основные функции программы:

  •  привлечение большего числа клиентов;
  •  упрощение процесса заключения сделок;
  •  расширение рынка сбыта.

Таким образом, становятся очевидны основные этапы решения задачи.

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

2.2 Анализ предметной области

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

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

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

Каждый товар определяется следующими параметрами:

  •  наименование товара;
  •  описание товара;
  •  цена товара;
  •  цена со скидкой;
  •  изображение товара.

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

К параметрам категории и отдела относятся их наименования и описания.

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

  •  атрибуты товара;
  •  количество товаров в корзине;
  •  дата добавления товара;
  •  срок покупки.

О каждом клиенте, воспользовавшемся (либо пользующемся периодически) услугами данного электронного магазина, имеются следующие данные: уникальный идентификатор клиента, имя, e-mail, пароль, кредитная карта, адрес, адрес 2, город, регион, страна, телефон, рабочий телефон, мобильный телефон.

Для каждого заказа, сделанного клиентом, фиксируется:

  •  номер заказа;
  •  дата размещения;
  •  дата выполнения;
  •  стоимость заказа;
  •  статус;
  •  комментарии;
  •  код аутентификации;
  •  номер транзакции.

Кроме того, для сведений о товарах, включенных в заказ, используется информация, связанная с:

  •  код созданного заказа;
  •  атрибуты товара;
  •  наименование товара;
  •  количество заказанных единиц;
  •  цена.

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

Следует учесть также и следующие ограничения.

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

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

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

Делать заказы, оставлять отзывы и управлять корзиной могут только зарегистрированные пользователи.

К информационной системе будут иметь доступ следующие группы пользователей:

  •  администратор информационной системы;
  •  клиенты Интернет-магазина.

При работе с системой ее администратор может производить следующие действия:

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

При обращении к системе клиенты могут производить следующие действия:

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

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


3 Проектирование базы данных

3.1 Выбор методологий моделирования и инструментария

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

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

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

В настоящее время существует более 20 технологий моделирования бизнес-систем и бизнес-процессов и несколько сотен инструментов, предназначенных для автоматизации этого процесса. Следовательно, актуальной является проблема их сравнения для обеспечения правильного выбора технологии и инструментария при решении конкретных задач пользователей [20].

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

Oracle Designer представляет собой инструмент, позволяющий проектировать данные, моделировать бизнес-процессы, создавать диаграммы потоков данных и функциональные модели, а также реализовывать их в виде серверных объектов. Этот продукт главным образом предназначен для применения совместно с СУБД Oracle и поддерживает все особенности данной СУБД, хотя с его помощью можно осуществлять и обратное проектирование для СУБД других производителей.

Sybase PowerDesignerCASE-средство (Computer-Aided Software/System Engineering), поддерживающее разработку информационных систем и позволяющее аналитикам, проектировщикам и разработчикам действовать в совместно используемой среде, создавать согласованные и надежные приложения.

В PowerDesigner одновременно можно решать несколько различных задач моделирования, не ограничивая проектировщиков жесткими рамками. Например, разрабатывать проект базы данных и/или объектно-ориентированную модель бизнес-логики. Таким образом, PowerDesigner представляет собой единую среду разработки, объединяющую как проектировщиков баз данных, так и разработчиков приложений [24].

IBM Rational Rose  - одно из самых популярных средств объектно-ориентированного UML-моделирования приложений. Данный продукт позволяет решать практически любые задачи в проектировании информационных систем – от анализа бизнес-процессов и моделирования данных до генерации кода на различных языках программирования, а также обладает средствами интеграции с другими инструментами Rational, в частности с Requisite Pro.

Rational XDE Professional (IBM) - инструмент UML-моделирования, встраиваемый в среды разработки Microsoft Visual Studio .NET и IBM WebSphere Studio Application Developer. Этот продукт дает возможность осуществлять визуальное проектирование на основе диаграмм UML и по окончании процесса проектирования генерировать код на выбранном языке программирования, а также проводить двустороннюю синхронизацию кода и модели [28].

BPwin – мощный инструмент для создания моделей, позволяющих анализировать, документировать и планировать изменения сложных бизнес-процессов. BPwin предлагает средство для сбора всей необходимой информации о работе предприятия и графического изображения этой информации в виде целостной и непротиворечивой модели. Причем, поскольку модель является некоторым графическим представлением действительности, можно утверждать, что человек вернулся к своему излюбленному средству документирования бизнес-процессов – к рисунку. Но возвращение это произошло на новом уровне – целостность и непротиворечивость модели-рисунка гарантируются рядом методологий и нотаций, которым следуют создатели модели. BPwin умеет проверять создаваемые модели с точки зрения синтаксиса выбранной методологии, проверяет ссылочную целостность между диаграммами, а также выполняет ряд других проверок, чтобы помочь вам создать правильную модель, а не просто рисунок. При этом сохраняются главные преимущества рисунка – простота создания и наглядность [19].

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

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

Таким образом, анализируя выше изложенное, можно сделать вывод, что при разработке программного обеспечения для системы он-лайн продаж строительных материалов на ОАО «Гродненский КСМ» и достижения наилучшего результата будут использованы методологии структурно-функционального анализа и объектно-ориентированные методологии. В качестве Case-средства, поддерживающего этап проектирования, был выбран Power Designer.

3.2 Построение концептуальной модели данных

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

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

Проанализировав предметную область, были определены основные объекты концептуальной модели для проектируемой БД:

1. Сущности:

  •  родительские: атрибуты, аудит, отдел, регион доставки, доставка, налоги;
  •  дочерние сильные: товары, клиенты, корзина;
  •  дочерние слабые: значения атрибутов, категория, созданные заказы, отзыв;
  •  дочерние ассоциативные: заказы.

2. Связи:

  •  «иметь» имеет связность один-ко-многим в направлении атрибуты – значения атрибутов, тип участия – полная со стороны атрибуты;
    •  «принадлежать» имеет связность многие-ко-многим в направлении значения атрибутов – товары, тип участия – полная со стороны значения атрибутов;
    •  «содержать» имеет связность многие-ко-многим в направлении категория – товары и имеет частичную степень участия со стороны категория;
    •  «включать» имеет связность один-ко-многим в направлении отдел – категория, тип участия – полная со стороны категория;
    •  «помещать» обладает связностью один-ко-многим со стороны товары - корзина и имеет частичную степень участия с обеих сторон;
    •  «оформлять» имеет связность один-ко-многим в направлении заказы – корзина и имеет частичную степень участия со стороны корзина;
    •  «хранить» имеет связность один-ко-многим в направлении заказы – созданные заказы, тип участия – полная с обеих сторон;
    •  «проходить» имеет связность один-ко-многим в направлении аудит – заказы, тип участия – полная с обеих сторон;
    •  «делать» имеет связность один-ко-многим в направлении клиенты – заказы и имеет частичную степень участия со стороны клиенты;
    •  «входить» имеет связность один-ко-многим в направлении доставка – заказы и имеет частичную степень участия со стороны заказы;
    •  «помещать» имеет связность один-ко-многим в направлении налоги – заказы и имеет частичную степень участия со стороны заказы;
    •  «выбирать» имеет связность один-ко-многим в направлении клиенты – отзыв и имеет частичную степень участия с обеих сторон;
    •  «быть а наличии» имеет связность один-ко-многим в направлении регион доставки – клиенты и имеет частичную степень участия со стороны регион доставки.

3. Ограничения:

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

Таким образом, концептуальная модель данных для программного обеспечения системы он-лайн продаж строительных материалов на ОАО «Гродненский КСМ» приводится на рисунке А.1.

3.3 Логическое моделирование

3.3.1 Построение логической модели данных

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

При проектировании логической структуры базы данных определяется оптимальный состав таблиц для хранения исходной информации. Для каждой таблицы указывается ее название, перечень полей и первичный ключ. Идентифицируются связи между таблицами. В рамках логического проектирования БД могут формулироваться ограничения целостности, приниматься решения о создании индексов, транзакций, представлений и авторизации доступа. Также после процедуры преобразования объектов к отношениям реляционной модели необходимо проверить корректность полученной структуры путем нормализации отношений. Это позволит получить адекватный проект и в дальнейшем наращивать логическую модель [24].

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

Логическая модель данных для программного обеспечения системы он-лайн продаж строительных материалов, полученная на основе концептуальной приводится на рисунке А.2.

 

3.3.2 Разработка диаграмм вариантов использования

Для того чтобы сформулировать общие требования к функциональному поведению проектируемой системы, используем описание функциональности системы через варианты использования (Use Case). Разрабатываемая система представляется в виде множества сущностей или актеров, взаимодействующих с ней с помощью вариантов использования. При этом актером (actor) или действующим лицом называется любая сущность, взаимодействующая с системой извне. Вариант использования служит для описания сервисов, которые система предоставляет актеру. В данном программном обеспечении можно выделить гостя, клиента, администратора, как действующими лицами. Реализуем диаграмму вариантов использования с помощью Power Designer.

Все задачи выполняемые гостем (незарегистрированным пользователем), клиентом и администратором изображены на рисунке 3.1.

Рисунок 3.1 – Диаграмма вариантов использования для гостя, клиента и администратора

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

3.3.3 Построение диаграмм состояний

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

Диаграммы состояния, отображенные на рисунках 3.2, 3.3 и 3.4, описывают работу гостя, клиента и сотрудника, соответственно.

Рисунок 3.2 – Диаграмма состояния для гостя

Рисунок 3.3 – Диаграмма состояния для клиента

Рисунок 3.4 – Диаграмма состояния для продавца

3.3.4 Разработка макетов экранных форм

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

Таким образом, меню приложения и интерфейс, должны быть оптимальными (в плане удобства пользования). Макет экранной формы, проектируемого Интернет-магазина, представлен на рисунке 3.5.

Рисунок 3.5 – Макет экранной формы Интернет-магазина строительных материалов

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

Следует привести также структуру сайта для разработанного Интернет-магазина строительных материалов (рисунок 3.6).

Рисунок 3.6 – Структура сайта Интернет-магазина строительных материалов

3.4 Физическое моделирование

3.4.1 Выбор среды разработки, языка программирования и инструментальных средств разработки

Для реализации системы он-лайн продаж были выбраны следующие средства разработки:

  •  язык PHP 5.3.5;
  •  СУБД MySQL 5.5.8;
  •  Web Server Apache 2.2.17.

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

Аббревиатура PHP означает «Hypertext Preprocessor (Препроцессор Гипертекста)». Синтаксис языка берет начало из C, Java и Perl. PHP достаточно прост для изучения.

Преимущества PHP:

  •  традиционность. Код РНР очень похож на тот, который встречается в типичных программах на С или Pascal. Это заметно снижает начальные усилия при изучении РНР. PHP — язык, сочетающий достоинства Perl и Си и специально нацеленный на работу в Интернете, язык с универсальным и ясным синтаксисом;
  •  простота. При написании РНР-кода не требуется подгружать библиотеки и указывать специальные параметры компиляции. Если код имеет правильный синтаксис, он исполняется в точности так, как указал программист. PHP — язык, который может быть встроен непосредственно в html-код страниц, которые, в свою очередь будут корректно обрабатываться PHP -интерпретатором;
  •  эффективность. В PHP испеользуется транслирующий интерпретатор, что позволяет обрабатывать сценарии с достаточно высокой скоростью;
  •  безопасность. РНР предоставляет в распоряжение разработчиков и администраторов гибкие и эффективные средства безопасности, которые условно делятся на две категории: средства системного уровня и средства уровня приложения;
  •  гибкость. Поскольку РНР является встраиваемым (embedded) языком, он отличается исключительной гибкостью по отношению к потребностям разработчика. Хотя РНР обычно рекомендуется использовать в сочетании с HTML, он с таким же успехом интегрируется и в JavaScript, WML, XML и другие языки. Нет проблем и с зависимостью от браузеров, поскольку перед отправкой клиенту сценарии РНР полностью компилируются на стороне сервера.

Поскольку РНР не содержит кода, ориентированного на конкретный web-сервер, пользователи не ограничиваются определенными серверами – Apache, Microsoft IIS, Netscape Enterprise Server, Stronghold и Zeus. Поскольку эти серверы работают на разных платформах, РНР в целом является платформенно-независимым языком и существует на таких платформах, как UNIX, Solaris, FreeBSD и Windows 95/98/NT/2000/XP/2003.

Наконец, средства РНР позволяют программисту работать с внешними компонентами, такими как Enterprise Java Beans или СОМ-объекты Win32. Благодаря этим новым возможностям РНР занимает достойное место среди современных технологий и обеспечивает масштабирование проектов до необходимых пределов.

Существует еще одна «характеристика», которая делает РНР особенно привлекательным: он распространяется бесплатно. Причем, с открытыми исходными кодами (Open Source).

Небольшим недостатком РНР является то, что откомпилированные исполняемые файлы будут работать значительно быстрее – в десятки, а иногда и в сотни раз. Но производительность PHP вполне достаточна для создания вполне серьезных веб-приложений [23].

Так как средой программирования был выбран язык PHP, то рационально выбрать MySQL системой управления базой данных и работать в связке Apache/PHP/MySQL.

СУБД MySQL – одна из множества баз данных, поддерживаемых в PHP. MySQL разработал Михаэль Видениус. MySQL является относительно небольшой и быстрой реляционной СУБД основанной на традициях Hughes Technologies Mini SQL (mSQL).

Система MySQL распространяется бесплатно и обладает достаточной мощностью для решения реальных задач. SQL – это аббревиатура от слов Structured Query Language, что означает структурированный язык запросов. Этот язык является стандартным средством для доступа к различным базам данных.

Основные преимущества MySQL:

  •  многопоточность, поддержка нескольких одновременных запросов;
  •  оптимизация связей с присоединением многих данных за один проход;
  •  записи фиксированной и переменной длины;
  •  ODBC драйвер в комплекте с исходником;
  •  гибкая система привилегий и паролей;
  •  гибкая поддержка форматов чисел, строк переменной длины и меток времени;
  •  интерфейс с языками C и perl;
  •  быстрая работа, масштабируемость;
  •  совместимость с ANSI SQL;
  •  бесплатна в большинстве случаев;
  •  хорошая поддержка со стороны провайдеров услуг хостинга;
  •  быстрая поддержка транзакций через механизм InnoDB [16].

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

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

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

Недостатком наиболее часто называется отсутствие удобного стандартного интерфейса для администратора.

Веб-сервер Apache разрабатывается и поддерживается открытым сообществом разработчиков под эгидой Apache Software Foundation и включен во многие программные продукты, среди которых СУБД Oracle и IBM WebSphere [4].

3.4.2 Построение физической модели данных

Заключительным этапом проектирования базы данных является физическое моделирование, которое представляет собой процесс определения структуры хранения данных и методов доступа к данным в базе и осуществляется на основе логической модели. Результатом этого процесса является физическая модель, содержащая полную информацию, необходимую для создания всех объектов базы данных. Физическая модель данных для разрабатываемой системы представлена рисунке А.3 [24].

3.4.3 Построение диаграмм компонентов

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

На рисунке 3.6 показана диаграмма компонентов Интернет-магазина, на которой модуль Presentation реализует интерфейс веб-сайта и логику, обеспечивающую взаимодействие сайта с пользователем, модуль Business - бизнес-логику сервера, а модули Data и DataDB отвечают за взаимодействие с базой данных заказов и синхронизацию с системой обработки заказов.

Рисунок 3.7 – Диаграмма компонентов Интернет-магазина строительных материалов

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

Возможна также независимость периода исполнения - каждая из компонент может находиться или на отдельном компьютере, или в отдельном процессе операционной системы, или работать в контексте отдельной нити (thread).

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

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


4 Реализация и тестирование программного обеспечения

4.1 Назначение и описание компонентов программного обеспечения, и их исходные тексты

Разработанная система он-лайн продаж «TStroiShop» была реализована при помощи трехуровневой архитектуры и содержит клиентскую и административную части, которые придерживаются этой архитектуры.

Трехуровневая архитектура подразумевает разделение кода на три уровня:

  1.  уровень представления (presentation layer);
  2.  уровень логики приложения (бизнес-уровень, или business layer);
  3.  уровень данных (data layer).

Взаимодействие уровней в приложении «TStroiShop» показано на рисунке 4.1.

Рисунок 4.1 – Взаимодействие уровней в приложении «TStroiShop» с трехуровневой архитектурой

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

Функциональность данного уровня достигается с помощью компонентных шаблонов Smarty – дизайн-шаблонов Smarty (файлов .tpl с тегами HTML и тегами, специфичными для Smarty) и соответствующими им подключаемыми файлами Smarty (файлы .php с кодом, взаимодействующим с шаблоном). 

Для этого был создан обобщенный подключаемый файл application.php, который интегрируется со всеми дизайн-шаблонами, загружая необходимые объекты представления, и генерируется с помощью шаблона store_front.php. В нем находится класс Application, наследующий Smarty. В конструкторе этого класса Application содержится процедура инициализации, которая упрощает использование шаблонов Smarty (листинг 4.1):

Листинг 4.1 – Класс, расширяющий Smarty, используется для обработки и отображения файлов Smarty 

class Application extends Smarty {

// Конструктор класса

public function construct() {

// Вызов конструктора Smarty parent::Smarty();

// Изменения папки шаблонов, заданные по умолчанию

$this->template_dir = TEMPLATE_DIR;

$this->compile_dir = COMPILE_DIR;

$this->config_dir = CONFIG_DIR;

К уровню представления также относится и библиотека ссылок, которая, с помощью, специального класса Link, находящегося в файле link.php, генерирует абсолютные ссылки. Наличие такого централизованного механизма упрощает работу сервера с защищенными страницами через соединения HTTPS и предотвращает бесполезное использование его ресурсов.

Уровень представления для административной части представлен главной страницей, которая содержится в файле admin.php, и генерируется с помощью шаблона store_admin.php. Кроме того, для администрирования сайта созданы следующие шаблоны:

  •  admin_menu.tpl используется для навигации в административной части;
  •  admin_login.tpl отвечает за аутентификацию;
  •  admin_products.tpl, admin_categories.tpl, admin_departments.tpl – компонентные шаблоны для администрирования каталога;
  •  admin_orders.tpl используется для администрирования заказов;
  •  admin_carts.tpl отвечает за администрирование данных о кредитной карте.

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

Так же уровень логики приложения запрашивает данные из уровня данных и передает их уровню представления. Работоспособность механизма, открывающего и закрывающего соединение с базой данных, обрабатывающего ошибки и организующего доступ к данным достигается использованием хранимых процедур MySQL, образующих уровень данных. Доступ к этим процедурам из PHF обеспечивают следующие классы:

  •  PDO – класс PHP, в котором содержатся методы для выполнения операций обработки данных, установки соединений с базой данных и решения других типичных задач. Функциональность PDO позволяет устанавливать соединения с сервером MySQL и выполнять SQL-запросы.  За открытие соединения отвечает конструктор класса PDO, который в качестве параметров получает строку соединения с сервером базы данных и аргумент, указывающий, будет ли создаваемое соединение постоянным. В строке соединения содержится вся информация, необходимая для установки соединения с сервером MySQL. Объект PDO создается конструктором, следующим образом (листинг 4.2):

Листинг 4.2 – Создание нового экземпляра PDO

       self::$_mHandler =

         new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD,

                 array(PDO::ATTR_PERSISTENT => DB_PERSISTENCY));

       // настройка PDO на генерацию исключений

       self::$_mHandler->setAttribute(PDO::ATTR_ERRMODE,

                                      PDO::ERRMODE_EXCEPTION);

Конструктор класса PDO возвращает проинициализированный объект соединения с базой данных, если соединение успешно установлено; в противном случае генерируется исключение;

  •  DatabaseHandler хранит общую функциональность, отвечающую за доступ к базе данных. Вызывается из файла database_handler.php;
  •  ErrorHandler обрабатывает ошибки, используя статический определенный пользователем метод Handler (), который вызывается при возникновении ошибок в работе PHP-программы и определяется с помощью функции set_error_handler ().

Метод обработки ошибок Handler (),работает следующим образом:

  •  составление подробного сообщения об ошибке:
  •  отправка сообщения администратору сайта но электронной почте;
  •  запись сообщения в журнал ошибок;
  •  вывод сообщения об ошибке на страницу ответа;
  •  серьезные ошибки приводят к прекращению выполнения приложения, менее серьезные ошибки позволяют приложению продолжить выполнение.

Вызывается из файла error_handler.php.

  •  Catalog содержит функциональность, специфичную для каталога товаров (например, метод GetDepartments (), который  извлекает из базы данных список отделов), вызывается из файла сatalog.php;
  •  Customer, отвечает за функциональность при работе с учетными записями пользователей, вызывается из файла сustomer.php;
  •  ShoppingCart, отвечает за корзину покупателя, из файла shopping_cart.php;
  •  SecureCard содержит представление кредитной карты и функции шифрования/дешифрования данных о ней, вызывается из файла secure_card.php;
  •  OrderProcessor - основной класс конвейера, используется для получения информации о заказах, вызова классов этапов конвейера и аудита заказов, вызывается из файла оrder_рrocessor.php;
  •  Orders применяется для администрирования заказов, вызывается из файла оrders.php;
  •  AdminMenu отвечает за функциональность главного меню администратора, вызывается из файла admin_menu.php;
  •  AdminLogin используется для аутентификации администратора, вызывается из файла admin_login.php;
  •  AdminProducts, AdminDepartments, AdminCategories обеспечивают функциональность администрирования каталога продуктов, вызываются из файлов admin_products.php, admin_departments.php, admin_categories.php, соответственно;

Листинги всех описанных в данном разделе файлов представлены в приложении Б.

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

Так как при первом вызове хранимой процедуры MySQL генерирует план ее выполнения, а затем может его использовать для быстрого выполнения этой процедуры при ее повторных вызовах.

Так же применение хранимых процедур дает и другие преимущества:

  •  упрощение кода для доступа к данным, который хранится централизованно, и упрощение реализации трехуровневой архитектуры (уровень данных как раз и образуется хранимыми процедурами, хранящимися в базе данных);
  •  упрощение обеспечения безопасности. MySQL позволяет задавать настройки безопасности отдельно для каждой процедуры;
  •  SQL-запросы, генерируемые в PHP-коде, более уязвимы к инъекционным атакам. Это серьезный источник угроз;
  •  отделение SQL от РНР делает PHP-код более аккуратным и простым для понимания: вызывать хранимые процедуры проще, чем генерировать SQL-операторы в РНР-сценариях.

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

4.2 Тестирование программного обеспечения

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

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

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

Полное тестирование разработанного приложения будет проводиться в два этапа:

  1.  функциональное тестирование;
  2.  тестирование интерфейса.

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

Критическое тестирование – это процесс поиска ошибок в программе при стандартной ее работе, т.е. при правильной последовательности действий, при верном заполнении полей.

Углубленное тестирование – это процесс поиска ошибок в программе в нестандартных, непредвиденных ситуациях, таких как некорректный ввод данных [21].

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

Тестирование решает несколько основных задач:

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

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

Таблица 4.1 – Тестовые случаи

Название модуля/ экрана

Описание тестового случая

Ожидаемые результаты

Тестовый случай пройден? Да/Нет

Коммен-

тарии

1

2

3

4

5

6

1

Регистрация

Нажатие ссылки «Регистрация» и последующее заполнение регистрационной формы:

1. Заполнить все поля;

2. Заполнить не все поля.

1. Сообщение об удачной регистрации;

2. Сообщение о неудачной регистрации.

Да

2

Авторизация

В поле «Имя пользователя» и «Пароль» ввести данные и нажать «Авторизация»

Вход в систему под определенными правами, в зависимости от введенных данных

Да

3

Навигацион-ное меню

Нажимаем на любой пункт меню

Отображение всех товаров, выбранной категории

Да

4

Подробная информация о товаре

Выбор активной ссылки товара, имя товара

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

Да

5

Добавление в корзину

Нажатие кнопки «Добавить в корзину»

Отображение названия товара в корзине

Да

6

Просмотр корзины

Нажатие на кнопку «Подробнее»

в поле отображения содержания корзины

Отображается таблица с информацией о количестве товаров находящихся в корзине

Да

Продолжение таблицы 4.1

Название модуля/ экрана

Описание тестового случая

Ожидаемые результаты

Тестовый случай пройден? Да/Нет

Коммен-

тарии

1

2

3

4

5

6

7

Поиск товара

  1.  Нажатие на кнопку «Поиск»
  2.  Нажатие на кнопку «Поиск» с установленным флажком «Поиск по всем словам»

1. Отображение списка товаров, в названии которых есть хотя бы одно искомое слово, иначе, вывод сообщения, что поиск не дал результатов

2. Отображение списка товаров, в названии которых есть все искомые слова, иначе, вывод сообщения, что поиск не дал результатов

Да

8

Авторизация администратора

При нажатии ссылки «Страница администратора» в поле «Имя» и «Пароль» ввести данные и нажать «Вход»

Отображение главной формы администратора содержащей панель управления

Да

9

Добавление товара

1. Нажатие на кнопку «Добавить товар» на странице администратора

2. Заполнить необходимые поля и нажать кнопку «Добавить»

1. Отображается форма для занесения нового товара в базу

2. Добавляется товар в базу

Нет

Не происхо-дит добавле-ние товара

10

Администрирование корзин покупателя

Нажатие на ссылку «Администрирование корзин»

Форма получения сведений о корзинах пользователя

Да

11

Администрирование заказов

Нажатие на ссылку « Администрирование заказов »

Форма получения сведений о заказах пользователя

Да

12

Профиль

Нажатие на кнопку «Профиль»

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

Да

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

Таблица 4.2 – Перечень граничных и эквивалентных значений

Название

поля

Формат

данных

Перечень граничных значений

Перечень эквивалентных значений

name_customer

varchar(50)

Текстовое поле с ограничением длины не более 50 символов

Иван Петров

password

varchar(50)

Текстовое поле с ограничением длины не более 50 символов

123

email

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

ivan@example.com

credit_cart

text

Текстовое поле с ограничением 65000 байт

40023424523

address1

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Советская 25-3

address2

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Горького 215

city

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Гродно

region

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Гродненская область

postal_code

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

230030

country

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Беларусь

day_phone

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

8(015)436361

eve_phone

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

8(015)7845981

mob_phone

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

8(029)5899227

name

varchar(100)

Текстовое поле с ограничением длины не более 100 символов

Кирпич шамотный ША-5

unit

varchar(30)

Текстовое поле с ограничением длины не более 30 символов

шт

description

varchar(1000)

Текстовое поле с ограничением длины не более 1000 символов

Характеристики: размеры, мм - 230х114х65 мм; вес/кг. - 3,2;

image

varchar(150)

Текстовое поле с ограничением длины не более 150 символов

kirpich_sha5.jpg

image2

varchar(150)

Текстовое поле с ограничением длины не более 150 символов

kirpich_sha5_2.jpg

thumbnail

varchar(150)

Текстовое поле с ограничением длины не более 150 символов

kirpich_sha5_thumbnail.jpg

price

decimal(10,2)

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

3700

discounted_price

decimal(10,2)

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

3550

display

smallint(6)

Короткое целое число с ограничением длины не более 6 символов

2

Аппаратные средства, которые использованы при тестировании программного обеспечения, приведены в таблице 4.3.

Таблица 4.3 –Перечень аппаратных средств

Роль

Аппаратная конфигурация

Программная конфигурация

1

2

3

4

1

Сервер

Intel Core i7-980X Extreme Edition,  Kingston HyperX T1 KHX1600C9D3T1K2/8G, 2000*2 Gb HDD, GeForce 8600GT 512Mb

Windows XP SP3, apache 2.2.17, mysql 5.5.8, PHP 5.3.5 (VC6 X86 32bit)

2

Клиент

Athlon 5200+, 2Gb RAM, 500 Gb HDD, GeForce 7600 Gt 512 Mb

Windows XP SP3, Internet Explorer

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

Таблица 4.4 – Анализ ошибок

Номер ошибки

Описание ошибки

Гипотеза местонахождения

Гипотеза прошла? Да/Нет

1

2

3

4

1

Не происходит добавление товара

Неправильная обработка событий

Да

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

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

Для тестирования, приложение вызывалось из разных современных браузеров (Mozilla, Firefox, Opera, Internet Explorer) и, как результат, интерфейс выглядел во всех одинаково.

Все страницы приложения оформлены в одном стиле и являются предельно простыми и понятными. Кроме того, в верхней части каждой страницы находиться заголовок сайта, напоминающий о месте нахождения пользователя.

При любом разрешении экрана и цветовой палитре программа работает стабильно. Работоспособность и внешний вид программы не нарушается и при изменении шрифта.

В целом интерфейс сайта достаточно прост и позволяет работать пользователю без специальной подготовки.

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


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

Работа с веб-приложением начинается с ввода в адресной строке браузера адреса, на котором установлено данное приложение. После запуска на экране отображается главная страница Интернет-магазина, содержащая информацию о товарах находящихся на скидке, навигационное меню, поля регистрации/авторизации пользователей, корзины и поиска товаров, изображена на рисунке Г.1.

Главная страница дает возможность произвести регистрацию или авторизацию пользователя, если он зарегистрирован в Интерне-магазине. Если пользователь не авторизирован, он имеет возможность просмотреть каталог товаров, представленный в системе. Для просмотра каталога, необходимо нажать на любой интересующий отдел и выбрать категорию продукции. Нажав, например, на «Блоки», пользователь перейдет на страницу, изображенную на рисунке Г.2. Также есть возможность просмотра подробной информации о товаре, нажав на любой товар либо его изображение, пользователь попадает на страницу, изображенную на рисунке Г.3.

Для регистрации необходимо нажать на кнопку «Регистрация» и перейти к странице, изображенной на рисунке Г.4, на которой пользователь сможет ввести все данные о себе и тем самым зарегистрироваться.

После авторизации перед пользователем появляется ряд возможностей:

  •  изменение своего профиля, осуществляется с помощью нажатия на клавишу «Профиль» и перехода на страницу, изображенную на рисунке Г.5;
  •  изменение сведений о кредитной карте, осуществляется с помощью нажатия на клавишу «Данные о кредитной карте» и перехода на одноименную страницу;
  •  изменение сведений об адресе, осуществляется с помощью нажатия на клавишу «Изменить адрес»;
  •  заказ любого товара, нажав на кнопку «Добавить в корзину». Для детального просмотра количества товаров, которые находятся в корзине необходимо нажать по кнопке «Корзина», и откроется страница, отображенная на рисунке Г.6, в которой появляется возможность просмотра и удаления, находящихся в корзине товаров.

Кроме того, приложение «TStroiShop» снабжено системой поиска. Для того чтобы найти товар необходимо ввести искомое слово в поле поиска и нажать на кнопку «Поиск», для поиска по фразе следует предварительно установить флажок «Поиск по всем словам» (рисунoк Г.7).

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

Администратор может добавить отдел, категорию и товар на продажу, путем нажатия на кнопку «Добавить отдел», «Добавить категорию», «Добавить товар» (рисунок Г.8), соответственно, тем самым система откроет одноименные страницы, на которых администратор заполнит все необходимые поля и нажмет кнопку «Добавить». На страницах добавления отдела, категории и товара, администратор также может удалить или изменить описания соответствующих критериев.

Нажатие на кнопку «Заказы», перед администратором отображается страница, изображенная на рисунке Г.9, которая описывает все заказы, которые произвели пользователи. Администратор может нажать «Удалить», если пользователь вдруг отказался от товара или нажать «Выполнено», если пользователю доставлен товар.

При нажатии на кнопку «Выход» как администратор, так и пользователь покидают страницу своего профиля и переходят на главную страницу системы он-лайн продаж строительных материалов ОАО «Гродненский КСМ».

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


6 Определение экономической эффективности разработки программного обеспечения

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

Годовые эксплуатационные расходы при ручной обработке информации определяются по формуле:

,                                     (6.1)

где - трудоемкость разового решения задачи вручную, чел-ч. (=4);

к - периодичность решения задачи в течение года (к = 255);

- среднечасовая ставка работника, осуществляющего ручной расчет задачи, тыс. руб.;

q - коэффициент, учитывающий процент премий (q = 0.4);

а - коэффициент, учитывающий дополнительную заработную плату (а = 0.15);

b - коэффициент, учитывающий начисления на заработную плату, включая отчисления в фонд социальной защиты населения.(b = 0.34).

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

Согласно Постановлению Совета Министров Республики Беларусь от 20.12.2010 года №1844 «Об установлении размера минимальной заработной платы» среднечасовая ставка работника равна:

руб.                                                          (6.2)

Нормативное количество рабочих часов в мае 2011 – 159.

тыс. руб.                                       (6.3)

тыс. руб.

Готовые текущие затраты, связаны с эксплуатацией задачи, определяются по формуле:

,                           (6.4)

где  - затраты на заработную плату пользователя программы;

- затраты на оплату аренды ЭВМ при решении задачи.

Затраты на заработную плату пользователя программы определяются по формуле:

,                                             (6.5)

где  - время решения задачи на ЭВМ, час;

- среднечасовая ставка пользователя программы, руб. (определяется аналогично ставке работника, осуществляющего ручной расчет, кт  = 2.48).

Время решения задачи на ЭВМ определяется по формуле:

,                                           (6.6)

где  - время ввода в ЭВМ исходных данных, необходимых для решения задачи, мин.(= 0.6);

- время вычислений, мин.( = 0.1);

- время вывода результатов решения задачи (включая время распечатки на принтере и графопостроителе), мин. ( = 1.3);

- коэффициент,  учитывающий  подготовительно-заключительное время (dпз =0.2).

Время ввода в ЭВМ исходных данных может быть определено по формуле:

,                                                      (6.7)

где - среднее количество знаков, набираемых с клавиатуры при вводе исходных данных (=20);

-  норматив набора 100 знаков, мин. (Hz=3).

Время вычислений и время вывода информации может быть определено экспериментальным путем при отладке контрольного примера.

2.71 тыс. руб.

мин.

час.

тыс. руб.

Затраты на оплату аренды ЭВМ для решения задачи определяются по следующей формуле:

,                                                  (6.8)

где  - стоимость одного машино-часа работы ЭВМ, тыс. руб.

Стоимость машино-часа работы ЭВМ определяется по формуле:

,                  (6.9)

где Сэ - расходы на электроэнергию за час работы ЭВМ, тыс. руб.;

- годовая величина амортизационных отчислений на реновацию ЭВМ, тыс. руб.;

- годовые затраты на ремонт и техническое обслуживание ЭВМ тыс. руб.;

- годовая величина амортизационных отчислений на реновацию производственных площадей, занимаемых ЭВМ. тыс. руб.;

- годовые затраты на ремонт и содержание производственных площадей, тыс. руб.;

- годовая величина налога на недвижимость, тыс. руб.;

- годовой фонд времени работы ЭВМ, час.

Расходы на электроэнергию за час работы ЭВМ определяются по формуле:

,                                                   (6.10)

где  - установленная мощность электродвигателя ЭВМ, кВт ( = 0.4),

- коэффициент  использования энергоустановок по мощности (=0.9)

- стоимость 1 кВт-часа электроэнергии, тыс.руб.

- среднечасовое потребление электроэнергии ЭВМ, кВт.

тыс.руб.

Годовая величина амортизационных отчислений на реновацию ЭВМ определяется по формуле:

,              (6.11)

где  - цена ЭВМ на момент ее выпуска, тыс. руб. (= 1600 тыс.руб.);

- коэффициент удорожания ЭВМ (зависит от года выпуска). В том случае, когда в качестве цены используется цена 2011г., коэффициент удорожания = 1;

- коэффициент, учитывающий затраты на монтаж и транспортировку ЭВМ (=1.05);

- норма амортизационных отчислений на ЭВМ,%

- балансовая стоимость ЭВМ, тыс. руб.

=  тыс. руб.

тыс. руб.

Годовые затраты на ремонт и техническое обслуживание ЭВМ укрупнено могут быть определены по формуле:

,                                            (6.12)

где  - коэффициент, учитывающий затраты на ремонт и техническое обслуживание ЭВМ, в том числе затраты на запчасти, зарплату ремонтного персонала и др.( = 0.1).

тыс. руб.

Годовая величина амортизационных отчислений на реновацию производственных площадей, занятых ЭВМ определяется по формуле:

,                     (6.13)

где  - балансовая стоимость площадей, тыс. руб.,

- норма амортизационных отчислений на производственные площади, % ( = 1.2);

— площадь, занимаемая ЭВМ, кв. м. (=2.3);

— коэффициент, учитывающий дополнительную площадь ;

— цена 1 квадратного метра площади, тыс. руб. (= 520).

= ;

= тыс.руб.

Годовые затраты на ремонт и содержание производственных площадей укрупнено могут быть определены по формуле:

                                                    (6.14)

где  - коэффициент, учитывающий затраты на ремонт и эксплуатацию производственных площадей (= 0,05).

= тыс.руб.

Величина налога на недвижимость определяется по формуле:

,                                           (6.15)

где  — ставка налога на недвижимость ( = 0.01).

тыс. руб.

Годовой фонд времени работы ЭВМ определяется исходя из режима ее работы и может быть рассчитан по формуле:

,                                                    (6.16)

где  - среднесуточная фактическая загрузка ЭВМ, час. ( = 8);

- среднее количество дней работы ЭВМ в год (= 255).

час.

тыс.руб.

Прирост условной прибыли в результате внедрения задачи определяется по формуле:

,                                           (6.17)

где - ставка налога на прибыль (= 0.24).

тыс.руб.

тыс.руб.

Для определения годового экономического эффекта от разработанной программы необходимо определить суммарные капитальные затраты на разработку и внедрения программы по формуле:

,                                                  (6.18)

где  - капитальные и приравненные к ним затраты, руб.,

- отпускная цена программы, руб.

Капитальные и приравненные к ним затраты определяются:

а) в случае, если необходимо приобретение новой ЭВМ для решения комплекса задач, в который входит рассматриваемая, по формуле:

,                                         (6.19)

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

б) в случае, если ЭВМ,  на которой предполагается решать рассматриваемую задачу, отслужила к моменту расчета X лет (X = 3), по формуле:

                     (6.20)

тыс.руб.

Отпускная цена программы определяется по формуле:

,                                      (6.21)

где  - оптовая цена программы, руб.,

- затраты на заработную плату разработчиков программы, руб.,

- размер плановой прибыли на программу, руб.,

- ставка налога на добавленную стоимость ( - 0.2).

Затраты на заработную плату разработчиков программы определяются по формуле:

,                                   (6.22)

где  - трудоемкость разработки программы, час,

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

Трудоемкость разработки программы включает время на постановку задачи и время на программирование задачи и определяется по формуле:

,                                         (6.23)

где  - количество этапов разработки программы,

- трудоемкость постановки задачи на i-м этапе разработки программы, дней;

- трудоемкость программирования задачи на i-м этапе разработки программы, дней.

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

,                               (6.24)

где  - трудоемкость подготовки описания задачи и исследования алгоритма решения;

- трудоемкость разработки блок-схемы алгоритма;

- трудоемкость программирования по готовой блок-схеме;

-трудоемкость отладки программы на ЭВМ;

- трудоемкость подготовки документации по задаче в рукописи;

- трудоемкость редактирования, печати и оформления документации по задаче.

Составляющие приведенной формулы определяются, в свою очередь, через условное число операторов Q в разрабатываемом ПП по формуле:

,                                                    (6.25)

где  - число операторов в программе;

- коэффициент сложности программы;

- коэффициент коррекции программы в ходе ее разработки.

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

Коэффициент коррекции программ p характеризует увеличение объема работ за счет внесения изменений в алгоритм и программу, изменения состава и структуры информации, а также уточнений, вносимых разработчиком программы для улучшения ее качества без изменения постановки задачи. Значение p может быть принято равным 0.15...0.5.

Тогда составляющие трудоемкости разработки программы определятся по формулам:

;                                              (6.26)

;                                                 (6.27)

;                                                   (6.28)

;                                                     (6.29)

;                                                     (6.30)

,                                                           (6.31)

где  - коэффициент увеличения затрат труда вследствие недостаточного или некачественного описания задачи ( - 1.2... 1.5);

- коэффициент квалификации разработчика алгоритмов и программ (при стаже работы о трех до пяти лет =1.1…1.2). Получаем:

;

;

;

;

=1.3;

=1.2

;

;

;

;

;

;

;

тыс. руб.;

тыс. руб.

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

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

Предусмотрено четыре степени новизны разрабатываемых задач:

  •  А - разработка задач, предусматривающая применение принципиально новых методов разработки, проведение научно-исследовательских работ;
  •  Б - разработка типовых проектных решений, оригинальных задач и систем, не имеющих аналогов;
  •  В - разработка проекта с использованием типовых проектных решений при условии их изменения, разработка проектов, имеющих аналогичные решения;
  •  Г - привязка типовых проектных решений.

Сложность алгоритма представлена тремя группами:

  1.  алгоритмы оптимизации и моделирования систем и объектов;
  2.  алгоритмы учета, отчетности, статистики и поиска;
  3.  алгоритмы, реализующие стандартные методы решения, а также не предусматривающие применения сложных численных и логических методов.

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

Плановая прибыль на программу определяется по формуле:

,                                                    (6.32)

где  - себестоимость программы, тыс руб.;

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

Себестоимость программы определяется по формуле:

                                             (6.33)

где  - коэффициент накладных расходов проектной организации без учета эксплуатации ЭВМ (при отсутствии данных принять  = 1,16);

- затраты на отладку программы.

Затраты на отладку программы определяются по формуле:

                                                       (6.34)

где - трудоемкость отладки программы, час.( )

тыс. руб.;

тыс. руб.;

Оптовая цена программы определяется по формуле:

;                                                      (6.35)

тыс.руб. ;

тыс. руб.;

тыс. руб.

Ожидаемый годовой экономический эффект от сокращения ручного труда при обработке информации определяется по формуле:

,                              (6.36)

где  - коэффициент эффективности, равный ставке за кредиты на рынке долгосрочных кредитов (= 0.25)

тыс. руб.

Срок возврата инвестиций определяется по формуле:

;                                                    (6.37)

.

Результаты расчета сводятся в таблице 6.1.

Таблица 6.1 - Технико-экономические показатели проекта

Наименование показателя

Базовый вариант

Проектный вариант

1. Трудоемкость решения задачи, час.

4

0.04

2. Периодичность решения задачи, раз/год

255

255

3. Годовые текущие затраты, связанные с решение задачи, тыс. руб.

5963.49

59.630

4. Отпускная цена программы, тыс. руб.

-

1415.69

5. Степень новизны программы

-

В

6. Группа сложности алгоритма

-

3

7. Прирост условной прибыли, тыс. руб.

-

4483.89

8. Ожидаемый годовой экономический     эффект, тыс. руб.

-

4128.65

9. Срок возврата инвестиций, лет

-

0.317

Приложение, реализованное в ходе дипломного проекта на тему «Разработка системы он-лайн продаж строительных материалов на примере ОАО «Гродненский комбинат строительных материалов»» обеспечивает получение годового экономического эффекта в сумме 4128.65 тыс. руб. при отпускной цене программы 1415.69 тыс. руб. Проект обеспечивает возврат инвестиций за 0.317 года.


7 ОХРАНА ТРУДА

7.1 Правовые, нормативные, социально-экономические и организационные вопросы охраны труда

Охрана труда – система обеспечения безопасности жизни и здоровья работников в процессе трудовой деятельности, включающая правовые, социально-экономические, организационные, технические, психофизиологические, санитарно-гигиенические, лечебно-профилактические, реабилитационные и иные мероприятия и средства, согласно ГОСТ 12.0.002 [5].

Правовой основой организации работы по охране труда в республике является Конституция Республики Беларусь (ст. 41, 45), которой гарантируются права граждан на здоровые и безопасные условия труда, охрану их здоровья.

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

Правила обучения безопасным методам и приемам работы, проведения инструктажа и проверки знаний по вопросам охраны труда, утверждены постановлением Министерства труда и социальной защиты Республики Беларусь 30.12.2003г №164.

7.2 Производственная санитария

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

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

7.2.1 Требования к помещениям вычислительного центра

Разработка дипломного проекта велась в помещении, размеры которого – 2,4х3,8 м, высота помещения – 2,7 м. На высоте 0,7 м расположен оконный проем размером 1,6х2,4 м с деревянными двойными рамами, застекленными оконным листовым стеклом.

Потолок побелен известью белого цвета, стены светлых тонов, пол досчатый.

Проведем анализ потенциально опасных и вредных производственных факторов на рабочем месте пользователя системы.

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

Для обеспечения нормальных условий труда санитарные нормы устанавливают на одного работающего объем производственного помещения не менее 20 м3 , а площадь помещения не менее 6 м2   на человека с учетом максимального числа одновременно работающих в смену, согласно СанПиН 9-131 РБ [25].

Так как площадь рассматриваемого помещения составляет 9,12 м2, объем помещения - 24,62 м3, а максимальное число одновременно работающих (тестируемых работников) – 1 человека, таким образом, эти значения соответствуют требуемым параметрам.

7.2.2 Микроклимат в помещениях вычислительного центра

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

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

Концентрация пыли в воздухе составляет не более 0,5 мг/м3.

Условия труда на рабочем месте регламентирует ГОСТ 12.1.005 [9], который определяет оптимальные и допустимые параметры для рабочей зоны производственных помещений.

Выполняемые на рабочем месте работы относятся к категории легких физических с затратой энергии до 120 Ккал/ч (категория I), а рассматриваемое помещение – к помещениям с незначительными избытками явной теплоты (до 23 Вт/м2 ).

Оптимальные параметры микроклимата приведены в таблице 7.1.

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

Период года

Категория работ

Температура, °С

Влажность, %

Скорость воздуха, м/с не более

Холодный

I

21-24

60-40

0,1

Теплый

I

22-25

60-40

0,1; 0,2

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

7.2.3 Шум и вибрация в помещениях вычислительного центра

Шум – любой нежелательный для человека звук. Сильный шум в условиях производства снижает производительность труда до 40 - 60% и может явиться причиной несчастного случая.

В помещении установлено 1 компьютер  и 1 лазерный принтер. Уровень шума, издаваемый компьютером, составляет около 10 дБА, издаваемый принтером - около 15 дБА. Принтер является источником «механического» шума, вызванного бумагоподающим механизмом.

Компьютер генерирует в основном аэродинамический шум, вызванный движением воздуха в системе охлаждения машины. Суммарный уровень шума, получаемый в результате наложения звуковых волн друг на друга, в рассматриваемом помещении составит 30 дБА, что ниже минимального уровня 50 дБА (согласно СанПиН 9-131 РБ [25]).

7.2.4 Электромагнитные излучения

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

На сегодня считается, что кратковременное и длительное воздействие всех видов излучений мониторов, особенно при наличии защитных экранов, не представляют опасности для здоровья оператора. Рекомендуется применение мониторов, удовлетворяющих стандарту безопасности TCO’03.

Максимальная напряженность на кожухе монитора Samsung SyncMaster 765MB, который соответствует стандарту TCO’03, составляет по паспортным данным 2,5 В/м, что соответствует фоновому уровню.

Интенсивность электромагнитного излучения в 5 см от экрана составляет 64 В/м, но на расстоянии 30 см, не превышает 2,4 В/м, что ниже, чем допустимый уровень. Это же можно сказать и об интенсивности ультрафиолетового и инфракрасного излучения.

Таким образом, при работе на настоянии 40 - 50 см от экрана дисплея вредное воздействие исключено.

7.2.5 Производственное освещение

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

В рассматриваемом помещении используется одностороннее естественное фронтальное освещение, осуществляемое через окно общей площадью 3,84 м2. Считается, что при работе с дисплеями площадь световых проемов в помещении должна составлять 25% площади пола. Площадь помещения 9,12 м2, значит, площадь световых проемов должна составлять 2,28 м2. Отсюда следует, что естественное освещение соответствует условиям труда. При недостатке естественного освещения используется искусственное освещение, которое осуществляется с помощью осветительных приборов общего назначения.

Произведем расчет искусственного освещения для рассматриваемого помещения с использованием метода коэффициента использования светового потока по формуле 7.1:

,                                                                       (7.1)

где - световой поток;

- освещенность, лк (=200 лк);

- площадь освещаемого помещения (S=9,12 м2);

- коэффициент запаса;

– коэффициент использования осветительной установки;

– потребное число светильников.

Определяем высоту расположения светильников над освещаемой поверхностью по формуле 7.2:

Hc = Hhchp,                                                                    (7.2)

где H - общая высота помещения (Н = 2,7 м);

hc – высота от потолка до нижней части светильника (hc= 0,4);

hp – высота от пола до освещаемой поверхности (hp = 0,7 м).

Hc = 2,7 – 0,4 – 0,7 = 1,6 м.

Определяем отношение расстояния между светильниками L к высоте их подвеса Нс. В соответствии с рекомендациями, принимаем данное соотношение равным 1,4. Откуда находим L по формуле 7.3:

L = 1,4 * Hc;                                                                    (7.3)

L = 1,4 * 1.6 = 2,24 м.

Найдем потребное число светильников по формуле 7.4:

;                                                                          (7.4)

n = 9,12/2,242= 1,81  2 шт.

Определяем показатель помещения по формуле 7.5:

,                                                               (7.5)

где, a – длина помещения ( a = 3,8 м);

b – ширина помещения ( b = 2,4 м).

.

В соответствии с СНБ 2.04.05 [9] определим значение коэффициента отражения потолка (известь белого цвета) ρпот = 0,7, стен (обои светлых тонов) ρст = 0,5, рабочей поверхности ρр = 0,3.

По найденному показателю i и значениям коэффициента отражения потолка, стен и рабочей поверхности, по соответствующим таблицам СНБ 2.04.05 определим значение коэффициента использования светового потока η=0,47.

Согласно классификации СНБ 2.04.05 [27], помещения вычислительного центра относятся к помещениям общественных и жилых зданий с нормальными условиями среды. В соответствии с этим, значение коэффициента запаса К=1,4.

Величина коэффициента неравномерности z определяется по формуле из отношения:

,                                                                      (7.6)

где Eср – средняя освещенность (Eср = 300 лк);

Emin – наименьшая освещенность (Emin = 200 лк, при освещении помещения вычислительного центра  и экрана дисплея [27].

Подставив полученные значения в формулу (7.1) и, учтя, что в каждом светильнике по две лампы получим:

Исходя из результатов расчета, оптимальными будут варианты люминесцентных  ламп со стандартными значениями светового потока – 2340 лм и мощностью 40 Вт. Согласно СНБ 2.04.05 выбираем марку лампы соответствующую рассчитанному значению F, для данного помещения лампа ЛД 40-4

7.2.6 Организация рабочего места программиста

Рабочее место по ГОСТ 12.1.005 ССБТ – место постоянного или временного пребывания работающих, в процессе трудовой деятельности. При организации рабочих мест необходимо руководствоваться требованиями СанПиН 9-131 РБ-2000 РБ, где особое внимание уделяется гигиеническим требованиям по обеспечению здоровых и безопасных условий при эксплуатации компьютерной техники.

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

  •  имеется возможность поворота дисплея в горизонтальной и вертикальной плоскостях;
  •  нет жесткой связи клавиатуры с дисплеем;
  •  существует возможность регулировки яркости и контрастности на дисплее;
  •  обеспечивается удобное расположение кнопок на панели компьютера;
  •  клавиатура обеспечивает удобный угол наклона к поверхности стола – 150 мм;
  •  мягкость нажатий клавиш на клавиатуре.

Принтер также удовлетворяет ряду эргономических требований:

  •  красивое оформление и окраска мягкого цвета;
  •  удобное расположение кнопок управления;
  •  простота и удобство смены картриджа;
  •  небольшие мускульные усилия при работе.

Рабочие места оборудованы легкими стульями, что соответствует требованиям. Высота сиденья не регулируется, что допускается нормами.

Рабочий стол программиста имеет габариты: длина 2,25 м, ширина 1 м, высота 0,8 м, что соответствует требованиям. Высота поверхности не регулируется, что также допускается нормами.

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

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

Для поддержания нормальной работоспособности работников рекомендуется продолжительность работы с монитором не более 50% рабочего времени, при этом время непрерывной работы не более 1,5-2 часов; время перерыва -15 мин.; и также время перерыв на обед - 40 мин. Все вышеперечисленные мероприятия по режиму работы и отдыха соблюдаются.

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

7.3 Техника безопасности

Техника безопасности - это система организационных мероприятии, защитных мер и методов, предотвращающих воздействие на работающих недопустимого риска [5].

Одним из основных требований техники безопасности при работе на видеодисплейных терминалах является обеспечение электробезопасности.

Согласно ГОСТ 12.1.009 [10] система организационных и технических мероприятий и средств, обеспечивающих защиту людей от вредного и опасного воздействия электрического тока, электрической дуги, электромагнитного поля и статического электричества.

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

Возникновению вышеперечисленных факторов препятствуют:

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

Применяемая техника относятся к электроустановкам напряжением до 1000 В, питание которых осуществляется от сети однофазного переменного тока напряжением 220 В, частотой 50 Гц. Напряжение подается через автоматический выключатель с силовым расцепителем, имеющим ток срабатывания 25 А. В мониторах компьютеров имеются и более высокие напряжения (до 25 кВ), которые надежно изолированы от оператора и не могут представлять опасности, доступ к цепям с таким напряжением возможен лишь при проведении ремонтных работ, которые осуществляются в специализированных ремонтных организациях специально подготовленным персоналом.

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

Согласно ГОСТ 12.1.038 [7] занулением называется преднамеренное электрическое соединение с нулевым защитным проводником металлических нетоковедущих частей оборудования, которые могут оказаться под напряжением.

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

Кроме того, на рабочем месте оператора ЭВМ необходимо обеспечить защиту от статического электричества.

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

Для снижения величины возникающих разрядов статического электричества в ВЦ, покрытие технологических полов следует выполнять из однослойного антистатического линолеума марки АСН. К общим мерам защиты от статического электричества в ВЦ можно отнести увлажнение воздуха (до 75%), ионизацию воздуха. Данные защитные меры регламентирует ГОСТ 12.4.124 [11].

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

7.4 Пожарная безопасность

Пожар – это неконтролируемое горение, развивающееся во времени и пространстве. Понятие пожарной безопасности означает состояние объекта, при котором с установленной вероятностью исключается возможность возникновения и развития пожара с воздействием на людей опасных факторов, а также обеспечивается защита материальных ценностей. Опасными факторами пожара для людей являются:

  •  открытый огонь;
  •  повышенные температуры воздуха и предметов;
  •  токсичные продукты горения;
  •  дым;
  •  пониженная концентрация кислорода;
  •  взрыв и т. д.

Все помещения по пожарной и взрывоопасности делятся на пять категорий:

  •  А, Б - взрывопожароопасные;
  •  В, Г, Д - пожароопасные.

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

Согласно ГОСТ 12.1.004 [8] Пожарная безопасность объекта должна обеспечиваться системами предотвращения пожара и противопожарной защиты, в том числе организационно-техническими мероприятиями.

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

  •  исключать возникновение пожара;
  •  обеспечивать пожарную безопасность людей;
  •  обеспечивать пожарную безопасность материальных ценностей;
  •  обеспечивать пожарную безопасность людей и материальных ценностей одновременно.

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

  •  применением средств пожаротушения и соответствующих видов пожарной техники;
  •  применением автоматических установок пожарной сигнализации и пожаротушения;
  •  применением основных строительных конструкций и материалов, в том числе используемых для облицовок конструкций, с нормированными показателями пожарной опасности;
  •  применением прописки конструкций объектов антипиренами и нанесением на их поверхности огнезащитных красок (составов);
  •  устройствами, обеспечивающими ограничение распространения пожара;
  •  организацией с помощью технических средств, включая автоматические, своевременного оповещения и эвакуации людей;
  •  применением средств коллективной и индивидуальной защиты людей от опасных факторов пожара;

Организационно-технические мероприятия должны включать:

  •  организацию пожарной охраны, организацию ведомственных служб пожарной безопасности;
  •  паспортизацию веществ, материалов, изделий, технологических процессов, зданий и сооружений объектов в части обеспечения пожарной безопасности;
  •  организацию обучения работающих правилам пожарной безопасности на производстве, а населения - в порядке, установленном правилами пожарной безопасности соответствующих объектов пребывания людей;
  •  разработку и реализацию норм и правил пожарной безопасности, инструкций о порядке обращения с пожароопасными веществами и материалами, о соблюдении противопожарного режима и действиях людей при возникновении пожара;
  •  изготовление и применение средств наглядной агитации по обеспечению пожарной безопасности;
  •  порядок хранения веществ и материалов, тушение которых недопустимо одними и теми же средствами, в зависимости от их физико-химических и пожароопасных свойств;
  •  нормирование численности людей на объекте по условиям безопасности их при пожаре;
  •  разработку мероприятий по действиям администрации, рабочих, служащих и населения на случай возникновения пожара и организацию эвакуации людей;

Противопожарная профилактика для  рассматриваемого помещения:

  •  наличие двух ручных порошковых огнетушителей, марки ОП-2М, предназначенных для тушения загорания с расстояния 2 м, при температуре 40-50 °С. Огнетушители хранятся в защищенном от солнечных лучей и нагревательных приборов месте, хорошо доступном при возникновении возгорания;
  •  для отопления помещений используется центральное водяное отопление;
  •  установлена система электрической пожарной сигнализации, два тепловых пожарных излучателя реагируют на повышение температуры окружающей среды до значения 80°С и выше в радиусе 3 м. Для помещений вычислительных центров рекомендуется использовать тепловые пожарные излучатели типа ДТЛ, АТП-ЗМ и др.

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


Заключение

В ходе дипломного проектирования была разработана система он-лайн продаж строительных материалов на примере ОАО «Гродненский комбинат строительных материалов».

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

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

Для реализации поставленной цели наиболее эффективно было использовать смешанный подход программирования.

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

В соответствии с поставленными задачами разработка была разделена на этапы. Для реализации которых использовались следующие программные средства: язык PHP и СУБД MySQL.

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

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

При необходимости возможна модернизация и усовершенствование системы путем расширения базы данных и разработки соответствующих PHP-скриптов.

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

Таким образом, система он-лайн продаж строительных материалов полностью готова к внедрению и эксплуатации.


Список использованных источников

  1.  Боуман, Дж. С. Практическое руководство по SQL / Дж. С. Боуман, С. Л. Эмерсон, М. Дарновски. – М.: Вильямс, 2005. – 311 с.
  2.  Ворошилова, А.В. Введение в информационный бизнес: учеб. пособие для вузов / В.П. Тихомирова, А.В. Ворошилова. – М.: Финансы и статистика, 2006.
  3.  Вин, Дж. Искусство веб-дизайна. Самоучитель. – СПб.: Питер, 2002. – 224 с.
  4.  Горев, А. Эффективная работа с СУБД / А. Горев, Р. Ахаян, С. Макашарипов. – СПб.: Питер, 2007.
  5.  ГОСТ 12.0.002 Система стандартов безопасности труда. Термины и определения.
  6.  ГОСТ 12.1.003 ССБТ Шум и вибрация.
  7.  ГОСТ 12.1.038 Электробезопасность. Предельно допустимые значения напряжений прикосновения и токов.
  8.  ГОСТ 12.1.004 Пожарная безопасность.
  9.  ГОСТ 12.1.005 Общие санитарно-гигиенические требования к воздуху рабочей зоны.
  10.  ГОСТ 12.1.009 Электробезопасность. Термины и определения.
  11.  ГОСТ 12.4.124 Средства защиты от статического электричества. Общие технические требования.
  12.  ГОСТ 2.104–2006 Единая система конструкторской документации. Основные надписи.
  13.  ГОСТ 2.105–95 Единая система конструкторской документации. Общие требования к текстовым документам.
  14.  Грабер, М. SQL. – М.: Лори, 2009. – 643 с.
  15.  Дамашке, Г. PHP и MySQL. Самоучитель. – М.: НТ Пресс, 2008. – 320 с.
  16.  Качанов, А. Букварь по PHP и MySQL / А. Качанов, В. Ткаченко, А. Головин. – М.: Вильямс, 2009.
  17.  Коггзолл, Дж. PHP 5. Полное руководство. – М.: Вильямс, 2006. – 752 с.
  18.  Колисниченко, Д.В. PHP 5/6 и MySQL 6. Разработка веб-приложений. – СПб.: BHV, 2010. – 546 с.
  19.  Маклаков, С.В. Моделирование бизнес-процессов с BPwin 4.0. – М.: ДИАЛОГ-МИФИ, 2002. – 224 с.
  20.  Маторин, С.И., Корзун С.С. Сравнительный анализ технологий моделирования бизнес-систем // Проблеми програмування. – 2006. – № 1. – С.24.
  21.  Методические указания к выполнению дипломного проекта для студентов специальностей 1 40 01 01 «Программное обеспечение информационных технологий», 1 40 01 02 «Информационные системы и технологии», 1 53 01 02 «Автоматизированные системы обработки информации» / Сост. В.И.Лакин, И.А.Бухвалова, Ю.Б.Попова. – Минск.: БНТУ, 2011. – 30 с.
  22.  Парк, Дж. PHP 5 и MySQL. Библия пользователя / Дж. Парк, К. Морган, Т. Конверс. – М.: Вильямс, 2006. – 1216 с.
  23.  Портал по PHP, MySQL и другим веб-технологиям [Электронный ресурс] – 2006. – Режим доступа: http://www. PHP.SU, свободный. – Загл. с экрана.
  24.  Рудикова, Л.В. Проектирование баз данных. – Гродно: ГрГУ,.2007. – 345 с.
  25.  СанПиН 9-131 РБ Гигиенические требования к видеодисплейным терминалам, электронно-вычислительным машинам и организации работы.
  26.  Скотт, Б. Проектирование веб-интерфейсов. Самоучитель / Б. Скотт, Т. Нейл. – СПб.: Символ, 2010. – 352 с.
  27.  СНБ 2.04.05 Естественное и искусственное освещение.
  28.  Учебный центр «Интерфейс» [Электронный ресурс] – 2009. – Режим доступа: http://www.interface.ru, свободный. – Загл. с экрана. – Яз. рус., англ.
  29.  Холзнер, С. PHP в примерах. – М.: Бином, 2009. – 350 с.


Приложение А
Концептуальная, логическая и физическая модели данных    

Рисунок А.1 – Концептуальная модель данных

Рисунок А.2 – Логическая модель данных

Рисунок А.3 – Физическая модель данных


Приложение Б
Листинг программы      

// application.php

<?php

// ссылка на библиотеку Smarty

require_once SMARTY_DIR . 'Smarty.class.php';

/* класс для расширения Smarty */

class Application extends Smarty

{

 // конструктор класса

   public function __construct()

 {

   // вызов конструктора Smarty

   parent::Smarty();

  // меняем папки шаблонов по умолчанию

   $this->template_dir = TEMPLATE_DIR;

   $this->compile_dir = COMPILE_DIR;

   $this->config_dir = CONFIG_DIR;

   $this->plugins_dir[0] = SMARTY_DIR . 'plugins';

   $this->plugins_dir[1] = PRESENTATION_DIR . 'smarty_plugins';

 } } ?>

// store_front.php

<?php

class StoreFront

{  public $mSiteUrl;

 // определяем файл шаблона для содержимого страницы

 public $mContentsCell = 'first_page_contents.tpl';

 // определяем файл шаблона для ячеек категорий

public $mCategoriesCell = 'blank.tpl';

// определяем файл шаблона для ячейки содержимого корзины

public $mCartSummaryCell = 'blank.tpl';

// определяем файл шаблона для полей аутентификации

 public $mLoginOrLoggedCell = 'customer_login.tpl';

 // управление отображением навигационных полей (списка отделов и т.д.)

 public $mHideBoxes = false;

 // заголовок страницы

 public $mPageTitle;

 // ссылка PayPal для возврата в магазин

 public $mPayPalContinueShoppingLink;

 // Конструктор класса

 public function __construct()

 {    $is_https = false;

   // к странице обращаются через HTTPS-соединение?

   if (getenv('HTTPS') == 'on')      $is_https = true;

   // использование HTTPS для доступа к стр. с конфиденциальной инфо

   if ($this->_IsSensitivePage() && $is_https == false &&        USE_SSL != 'no')

   {      $redirect_to = Link::Build(str_replace(VIRTUAL_LOCATION, '', getenv('REQUEST_URI')),        'https');

     header ('Location: '. $redirect_to);

     exit();   }

   // не использование HTTPS для стр., не содержащих конфиденциальной инфо

   if (!$this->_IsSensitivePage() && $is_https == true)

   {      $redirect_to = Link::Build(str_replace(VIRTUAL_LOCATION, '', getenv('REQUEST_URI')));

     header ('Location: '. $redirect_to); exit();    }

        $this->mSiteUrl = Link::Build('');  }

  //инициализация объекта представления

 public function init()

 {   $_SESSION['link_to_store_front'] = Link::Build(str_replace(VIRTUAL_LOCATION, '', etenv('REQUEST_URI')));

    // создание ссылки "continue shopping"      

if (!isset ($_GET['CartAction']) && !isset($_GET['Logout']) &&  !isset($_GET['RegisterCustomer']) && !isset($_GET['AddressDetails']) &&

       !isset($_GET['CreditCardDetails']) &&  !isset($_GET['AccountDetails']) &&    !isset($_GET['Checkout']))

     $_SESSION['link_to_last_page_loaded'] = $_SESSION['link_to_store_front'];

   // создание ссылки "cancel" для стр. с инфо о пользователе

   if (!isset($_GET['Logout']) && isset($_GET['RegisterCustomer']) && !isset($_GET['AddressDetails']) &&

       !isset($_GET['CreditCardDetails']) && !isset($_GET['AccountDetails']))

     $_SESSION['customer_cancel_link'] = $_SESSION['link_to_store_front'];  

   // загрузка подробной инфо об отделе на страницу отдела

if (isset ($_GET['DepartmentId'])) { $this->mContentsCell = 'department.tpl';  $this->mCategoriesCell = 'categories_list.tpl';     }   

      elseif (isset($_GET['ProductId']) &&       isset($_SESSION['link_to_continue_shopping']) &&

           strpos($_SESSION['link_to_continue_shopping'], 'DepartmentId', 0)   !== false)

   {      $this->mCategoriesCell = 'categories_list.tpl';    }

   // загрузка подробной инфо об товаре на страницу товара

   if (isset ($_GET['ProductId'])) $this->mContentsCell = 'product.tpl';    

      // загрузка результата поиска, если выполняется поиск

 elseif (isset ($_GET['SearchResults']))  $this->mContentsCell = 'search_results.tpl';              

   // загрузка шаблона для отображения корзины

 if (isset ($_GET['CartAction'])) $this->mContentsCell = 'cart_details.tpl'; else   $this->mCartSummaryCell = 'cart_summary.tpl';

  if (Customer::IsAuthenticated()) $this->mLoginOrLoggedCell = 'customer_logged.tpl';

   if (isset ($_GET['RegisterCustomer']) ||  isset ($_GET['AccountDetails']))  $this->mContentsCell = 'customer_details.tpl';

elseif (isset ($_GET['AddressDetails'])) $this->mContentsCell = 'customer_address.tpl';

elseif (isset ($_GET['CreditCardDetails']))   $this->mContentsCell = 'customer_credit_card.tpl';

      if (isset ($_GET['Checkout']))    { if (Customer::IsAuthenticated()) $this->mContentsCell = 'checkout_info.tpl';

     else     $this->mContentsCell = 'checkout_not_logged.tpl';   $this->mHideBoxes = true; }

   if (isset($_GET['OrderDone']))  $this->mContentsCell = 'order_done.tpl'; elseif (isset($_GET['OrderError']))

     $this->mContentsCell = 'order_error.tpl';

       // загрузка заголовка стр.

   $this->mPageTitle = $this->_GetPageTitle();   }

    // возврат заголовка страницы

 private function _GetPageTitle()

 {  $page_title = 'TStroiShop: ' .  'Product Catalog KSM Grodno';

   if (isset ($_GET['DepartmentId']) && isset ($_GET['CategoryId']))

   {   $page_title = 'TStroiShop: ' .  Catalog::GetDepartmentName($_GET['DepartmentId']) . ' - ' . Catalog::GetCategoryName($_GET['CategoryId']); if (isset ($_GET['Page']) && ((int)$_GET['Page']) > 1)

       $page_title .= ' - Page ' . ((int)$_GET['Page']);  }

elseif (isset ($_GET['DepartmentId'])) { $page_title = 'TStroiShop: ' .Catalog::GetDepartmentName($_GET['DepartmentId']);

     if (isset ($_GET['Page']) && ((int)$_GET['Page']) > 1)  $page_title .= ' - Page ' . ((int)$_GET['Page']);    }

   elseif (isset ($_GET['ProductId'])) {  $page_title = 'TStroiShop: ' .  Catalog::GetProductName($_GET['ProductId']);  }    

    elseif (isset ($_GET['SearchResults']))   {  $page_title  = 'TStroiShop: "';

     // отображение строки поиска

     $page_title .= trim(str_replace('-', ' ', $_GET['SearchString'])) . '" (';

     // отображение "all-words search " или "any-words search"

     $all_words = isset ($_GET['AllWords']) ? $_GET['AllWords'] : 'off';

     $page_title .= (($all_words == 'on') ? 'all' : 'any') . '-words search';

     // отображение номера стр.

     if (isset ($_GET['Page']) && ((int)$_GET['Page']) > 1) $page_title .= ', page ' . ((int)$_GET['Page']); $page_title .= ')'; }

   else { if (isset ($_GET['Page']) && ((int)$_GET['Page']) > 1)  $page_title .= ' - Page ' . ((int)$_GET['Page']);  }

   return $page_title;  }

 // обращение к защищенной стр.?

 private function _IsSensitivePage()

 {  if (isset($_GET['RegisterCustomer']) ||  isset($_GET['AccountDetails']) || isset($_GET['CreditCardDetails']) ||

       isset($_GET['AddressDetails']) || isset($_GET['Checkout']) ||   isset($_POST['Login']))  return true; return false;  } }?>

// link.php

<?php

class Link

{ public static function Build($link, $type = 'http')

 {    $base = (($type == 'http' || USE_SSL == 'no') ? 'http://' : 'https://') .  getenv('SERVER_NAME');

   // если константа HTTP_SERVER_PORT определена и знаение не равно значению по умолчанию

   if (defined('HTTP_SERVER_PORT') && HTTP_SERVER_PORT != '80' &&  strpos($base, 'https') === false)

   { // добавляем номер порта

     $base .= ':' . HTTP_SERVER_PORT;   }

   $link = $base . VIRTUAL_LOCATION . $link;

   // Escape-символы для html

   return htmlspecialchars($link, ENT_QUOTES);  }

 public static function ToDepartment ($departmentId, $page = 1)  

  {    $link = self::CleanUrlText(Catalog::GetDepartmentName($departmentId)) .   '-d' . $departmentId . '/';

   if ($page > 1)  $link .= 'page-' . $page . '/'; return self::Build($link);  }    

  public static function ToCategory($departmentId, $categoryId, $page = 1)

  {    $link = self::CleanUrlText(Catalog::GetDepartmentName($departmentId)) .  '-d' . $departmentId . '/' .

           self::CleanUrlText(Catalog::GetCategoryName($categoryId)) . '-c' . $categoryId . '/';

   if ($page > 1)      $link .= 'page-' . $page . '/';    return self::Build($link);  }  

   public static function ToProduct($productId)  {    $link = self::CleanUrlText(Catalog::GetProductName($productId)) .

           '-p' . $productId . '/';    return self::Build($link);  }

  public static function ToIndex($page = 1)

 {    $link = '';    if ($page > 1)        $link .= 'page-' . $page . '/';    return self::Build($link);  }

 public static function QueryStringToArray($queryString)

{ $result = array(); if ($queryString != '') { $elements = explode('&', $queryString); foreach($elements as $key => $value)

  { $element = explode('=', $value); $result[urldecode($element[0])] =  isset($element[1]) ? urldecode($element[1]) : ''; } }

   return $result;  }   

// подготовка строки для использования в URL

 public static function CleanUrlText($string)

 {    // удаление всех символов кроме a-z, 0-9, а-я, дефиса, знака подчеркивания и пробела

   $not_acceptable_characters_regex = '#[^-a-zA-Z0-9а-яА-Я_ ]#';

   $string = preg_replace($not_acceptable_characters_regex, '', $string);

   // удаление всех пробелов  в начале и конце строки

   $string = trim($string);

   // замена дефиса, знака подчеркивания и пробела дефисами      

   $string = preg_replace('#[-_ ]+#', '-', $string);

   // возврат полученной строки

   return strtolower($string);  }

  // выполнение перенаправления по корректному URL в случае необходимости

 public static function CheckRequest()

{ $proper_url = ''; if (isset ($_GET['Search']) || isset($_GET['SearchResults']) || isset ($_GET['CartAction']) || isset ($_GET['AjaxRequest']) ||   isset ($_POST['Login']) || isset ($_GET['Logout']) ||  isset ($_GET['RegisterCustomer']) ||

 isset ($_GET['AddressDetails']) ||  isset ($_GET['CreditCardDetails']) || isset ($_GET['AccountDetails']) || isset ($_GET['Checkout']) ||  isset ($_GET['OrderDone']) || isset ($_GET['OrderError']))  {      return ;    }

    // получение правильного URL для стр. категорий

   elseif (isset ($_GET['DepartmentId']) && isset ($_GET['CategoryId']))    {      if (isset ($_GET['Page']))

       $proper_url = self::ToCategory($_GET['DepartmentId'],                        $_GET['CategoryId'], $_GET['Page']);

     else        $proper_url = self::ToCategory($_GET['DepartmentId'],                     $_GET['CategoryId']);    }

   // получение правильного URL для стр. отделов

   elseif (isset ($_GET['DepartmentId']))

   {      if (isset ($_GET['Page']))        $proper_url = self::ToDepartment($_GET['DepartmentId'],        $_GET['Page']);

     else        $proper_url = self::ToDepartment($_GET['DepartmentId']);    }

   // получение правильного URL для стр. товаров

   elseif (isset ($_GET['ProductId']))    {      $proper_url = self::ToProduct($_GET['ProductId']);    }

   // получение правильного URL для главной стр.

   else    {       if (isset($_GET['Page'])) $proper_url = self::ToIndex($_GET['Page']); else $proper_url = self::ToIndex();    }

   // удаление виртуальных локаций из запрошенного URL    для сравнения путей

   $requested_url = self::Build(str_replace(VIRTUAL_LOCATION, '',     $_SERVER['REQUEST_URI']));

   // выполнение перенаправления по корректному URL в случае отсутствия отдела, товара, категории с кодом 404

   if (strstr($proper_url, '/-'))    {      

// очистка буфера вывода  

   ob_clean();

     // выполнение перенаправления  с кодом 404

     include '404.php';

     // очистка буфера вывода и завершение работы

     flush();       ob_flush();       ob_end_clean();       exit();    }

   // выполнение перенаправления по корректному URL в случае необходимости с кодом 301

   if ($requested_url != $proper_url)    {

     // очистка буфера вывода

     ob_clean();

     // выполнение перенаправления  с кодом 301

     header('HTTP/1.1 301 Moved Permanently');      header('Location: ' . $proper_url);

     // очистка буфера вывода и завершение работы

     flush();      ob_flush();      ob_end_clean();      exit();    }  }

  // создание ссылки на стр. поиска

 public static function ToSearch()

 {    return self::Build('index.php?Search');  }

 // создание ссылки на стр. с результатами поиска

 public static function ToSearchResults($searchString, $allWords,       $page = 1)

{ $link = 'search-results/find'; if (empty($searchString))  $link .= '/';  else $link .= '-' . self::CleanUrlText($searchString) . '/';

   $link .= 'all-words-' . $allWords . '/';    if ($page > 1)      $link .= 'page-' . $page . '/';    return self::Build($link);  }

 // создание ссылки стр. админ-я

 public static function ToAdmin($params = '')

 {    $link = 'admin.php';    if ($params != '')      $link .= '?' . $params;    return self::Build($link, 'https');  }

 // создание ссылки для выхода

 public static function ToLogout()

 {    return self::ToAdmin('Page=Logout');  }

  // создание ссылки на стр. админ-я отделов

 public static function ToDepartmentsAdmin()

 {    return self::ToAdmin('Page=Departments');  }

 // создание ссылки на стр. админ-я катеорий

 public static function ToDepartmentCategoriesAdmin($departmentId)

 {    $link = 'Page=Categories&DepartmentId=' . $departmentId;    return self::ToAdmin($link);  }

  // создание ссылки на стр. админ-я атрибута

 public static function ToAttributesAdmin()

 {    return self::ToAdmin('Page=Attributes');  }

 // создание ссылки на стр. админ-я знач. атрибута

 public static function ToAttributeValuesAdmin($attributeId)

 {    $link = 'Page=AttributeValues&AttributeId=' . $attributeId;    return self::ToAdmin($link);  }

 // создание ссылки на стр. админ-я товаров

 public static function ToCategoryProductsAdmin($departmentId, $categoryId)

{ $link = 'Page=Products&DepartmentId=' . $departmentId .  '&CategoryId=' . $categoryId; return self::ToAdmin($link); }

// создание ссылки на стр. админ-я инфо о товарах

 public static function ToProductAdmin($departmentId, $categoryId, $productId)

{$link = 'Page=ProductDetails&DepartmentId=' . $departmentId . '&CategoryId=' . $categoryId . '&ProductId=' . $productId;    return self::ToAdmin($link);  }    

  // создание ссылки для корзины

 public static function ToCart($action = 0, $target = null)

 {    $link = '';    switch ($action)    {

     case ADD_PRODUCT:        $link = 'index.php?CartAction=' . ADD_PRODUCT . '&ItemId=' . $target;        break;

 case REMOVE_PRODUCT:   $link = 'index.php?CartAction=' . REMOVE_PRODUCT . '&ItemId=' . $target;    break;

case UPDATE_PRODUCTS_QUANTITIES:  $link = 'index.php?CartAction=' . UPDATE_PRODUCTS_QUANTITIES;

       break;

case SAVE_PRODUCT_FOR_LATER:  $link = 'index.php?CartAction=' . SAVE_PRODUCT_FOR_LATER . '&ItemId=' . $target;    break;

case MOVE_PRODUCT_TO_CART: $link = 'index.php?CartAction=' . MOVE_PRODUCT_TO_CART . '&ItemId=' . $target;        break;         default:        $link = 'cart-details/';    }    return self::Build($link);  }

// создание ссылки на стр. админ-я корзин

 public static function ToCartsAdmin()

 {    return self::ToAdmin('Page=Carts');  }

 // создание ссылки на стр. админ-я заказов

 public static function ToOrdersAdmin()

 {    return self::ToAdmin('Page=Orders');  }

 // создание ссылки на стр. админ-я деталей заказов

 public static function ToOrderDetailsAdmin($orderId)

 {    $link = 'Page=OrderDetails&OrderId=' . $orderId;    return self::ToAdmin($link);  }

 // создание ссылки на стр. регистрации  пользователей

 public static function ToRegisterCustomer()

 {    return self::Build('register-customer/', 'https');  }

 // создание ссылки на стр. обновления инфо о пользователе

 public static function ToAccountDetails()

 {    return self::Build('account-details/', 'https');  }

 // создание ссылки на стр. обновления инфо о кредитной карте

 public static function ToCreditCardDetails()

 {    return self::Build('credit-card-details/', 'https');  }

 // создание ссылки на стр. обновления инфо об адресе пользователя

 public static function ToAddressDetails()

 {    return self::Build('address-details/', 'https');  }

 // создание ссылки на стр. оплаты

 public static function ToCheckout()

 {    return self::Build('checkout/', 'https');  }

 // создание ссылки на стр. с инфо о размещении заказа

 public static function ToOrderDone()

 {    return self::Build('order-done/'); }

 // создание ссылки на стр. с инфо об ошибке при обработке заказа

 public static function ToOrderError()

 {    return self::Build('order-error/');  }}?>

//admin.php

<?php

// активация сеанса

session_start();

// создание выходного буфера

ob_start();

// включение вспомогательных файлов

require_once 'include/config.php';

require_once BUSINESS_DIR . 'error_handler.php';

// обработчик ошибок

ErrorHandler::SetHandler();

// загрузка шаблона страницы

require_once PRESENTATION_DIR . 'application.php';

require_once PRESENTATION_DIR . 'link.php';

// загрузка дескриптора бд

require_once BUSINESS_DIR . 'database_handler.php';

// загрузка уровня логики приложения

require_once BUSINESS_DIR . 'catalog.php';

require_once BUSINESS_DIR . 'shopping_cart.php';

require_once BUSINESS_DIR . 'orders.php';

require_once BUSINESS_DIR . 'symmetric_crypt.php';

require_once BUSINESS_DIR . 'secure_card.php';

require_once BUSINESS_DIR . 'customer.php';

require_once BUSINESS_DIR . 'i_pipeline_section.php';

require_once BUSINESS_DIR . 'ps_dummy.php';

require_once BUSINESS_DIR . 'order_processor.php';

require_once BUSINESS_DIR . 'ps_initial_notification.php';

require_once BUSINESS_DIR . 'ps_check_funds.php';

require_once BUSINESS_DIR . 'ps_check_stock.php';

require_once BUSINESS_DIR . 'ps_stock_ok.php';

require_once BUSINESS_DIR . 'ps_take_payment.php';

require_once BUSINESS_DIR . 'ps_ship_goods.php';

require_once BUSINESS_DIR . 'ps_ship_ok.php';

require_once BUSINESS_DIR . 'ps_final_notification.php';        

// загрузка файла шаблонов Smarty

$application = new Application();

// отображаем страницу

$application->display('store_admin.tpl');

// закрытие соединения с бд

DatabaseHandler::Close();

// вывод содержимого буфера

flush(); ob_flush(); ob_end_clean();

?>

// store_admin.php

<?php

class StoreAdmin

{  public $mSiteUrl;

 // определяем файл шаблона для меню

 public $mMenuCell = 'blank.tpl';

 // определяем файл шаблона для содержимого страницы

 public $mContentsCell = 'blank.tpl';

 // Конструктор класса

 public function __construct()

 {    $this->mSiteUrl = Link::Build('', 'https');

   // разрешение доступа к стр. только через  HTTPS если USE_SSL = yes

if (USE_SSL == 'yes' && getenv('HTTPS') != 'on') { header ('Location: https://' . getenv('SERVER_NAME') . getenv('REQUEST_URI'));      exit();    }  }

 public function init()

 {    // если аутентификация не выполнялась, загрузка шаблона admin_login

if (!(isset ($_SESSION['admin_logged'])) ||  $_SESSION['admin_logged'] != true)   $this->mContentsCell = 'admin_login.tpl';    else

   {      // если аутентификация выполнялась, загрузка меня стр. админ-я

     $this->mMenuCell = 'admin_menu.tpl';

     // при выходе ...

     if (isset ($_GET['Page']) && ($_GET['Page'] == 'Logout'))

     {     unset($_SESSION['admin_logged']);    header('Location: ' . Link::ToAdmin());   exit();      }

     // если значение Page не задано явно, подразумеваем стр. Departments

     $admin_page = isset ($_GET['Page']) ? $_GET['Page'] : 'Departments';

     // выбор загружаемой стр...

     if ($admin_page == 'Departments')        $this->mContentsCell = 'admin_departments.tpl';

     elseif ($admin_page == 'Categories')        $this->mContentsCell = 'admin_categories.tpl';

        elseif ($admin_page == 'Attributes')        $this->mContentsCell = 'admin_attributes.tpl';

     elseif ($admin_page == 'AttributeValues')        $this->mContentsCell = 'admin_attribute_values.tpl';  

     elseif ($admin_page == 'Products')        $this->mContentsCell = 'admin_products.tpl';

     elseif ($admin_page == 'ProductDetails')        $this->mContentsCell = 'admin_product_details.tpl';

        elseif ($admin_page == 'Carts')        $this->mContentsCell = 'admin_carts.tpl';

       elseif ($admin_page == 'Orders')        $this->mContentsCell = 'admin_orders.tpl';

     elseif ($admin_page == 'OrderDetails')        $this->mContentsCell = 'admin_order_details.tpl';  } } } ?>

// database_handler.php

<?php    

// класс базовой функциональности доступа к данным

class DatabaseHandler

{  // переменная для хранения экземпляра класса PDO

 private static $_mHandler;

  // Private конструктор, не позволяющий напрямую создавать объеты класса

 private function __construct()  {  }

 // возврат проинициализированного дескриптора бд

 private static function GetHandler()

 {    // создание соединения с бд, если его нет

   if (!isset(self::$_mHandler))    {

     // выполнение кода+ перехват исключений

     try      {

       // создание нового экземпляра PDO

       self::$_mHandler =          new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD,

                 array(PDO::ATTR_PERSISTENT => DB_PERSISTENCY));

       // настройка PDO на генерацию исключений

       self::$_mHandler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);      }

     catch (PDOException $e)      {

       // Закрытие дескриптора и генерация ошибки

       self::Close();        trigger_error($e->getMessage(), E_USER_ERROR);      }    }

   // возврат дескриптора бд

   return self::$_mHandler;  }

   // метод закрытия соединения с бд очистка экземпляра класса PDO

 public static function Close()

 {    self::$_mHandler = null;  }

 // метод-обертка для PDOStatement::execute() - выполнение запросов не возвращающих данные

 // для запросов insert, delete, update

 public static function Execute($sqlQuery, $params = null)  {

   // попытка выполнить SQL-запрос  или хранимую процедуру

   try    {

     // получение дескриптора бд

     $database_handler = self::GetHandler();

     // подготовка запроса к выполнению

     $statement_handler = $database_handler->prepare($sqlQuery);

     // выполнение 

     $statement_handler->execute($params);    }

   // если при выполнении запроса возникло исключение - генерация ошибки

   catch(PDOException $e)    {

     // закрытие дескриптора бд и генерация ошибки

     self::Close();      trigger_error($e->getMessage(), E_USER_ERROR);    }  }

 // метод-обертка для  PDOStatement::fetchAll()  - получение всех строк для запроса select

 public static function GetAll($sqlQuery, $params = null,

                               $fetchStyle = PDO::FETCH_ASSOC)

 {    // инициализация возвращаемого значения в null

   $result = null;

   // попытка выполнить SQL-запрос  или хранимую процедуру

   try    {

     // получение дескриптора бд

     $database_handler = self::GetHandler();

     // подготовка запроса к выполнению

     $statement_handler = $database_handler->prepare($sqlQuery);

     // выполнение 

     $statement_handler->execute($params);      

     // получение результата

     $result = $statement_handler->fetchAll($fetchStyle);    }

   // если при выполнении запроса возникло исключение - генерация ошибки

   catch(PDOException $e)    {

     // закрытие дескриптора бд и генерация ошибки

     self::Close();      trigger_error($e->getMessage(), E_USER_ERROR);    }

   // возврат результатов запроса

   return $result;  }

 // метод-обертка для  PDOStatement::fetch()  получение одной строки для запроса select

 public static function GetRow($sqlQuery, $params = null,    $fetchStyle = PDO::FETCH_ASSOC)  {

   // инициализация возвращаемого значения в null

   $result = null;

   // попытка выполнить SQL-запрос  или хранимую процедуру

   try    {

     // получение дескриптора бд

     $database_handler = self::GetHandler();

     // подготовка запроса к выполнению

     $statement_handler = $database_handler->prepare($sqlQuery);

     // выполнение 

     $statement_handler->execute($params);

     // получение результата

     $result = $statement_handler->fetch($fetchStyle);    }

   // если при выполнении запроса возникло исключение - генерация ошибки

   catch(PDOException $e)    {

     // закрытие дескриптора бд и генерация ошибки

     self::Close();      trigger_error($e->getMessage(), E_USER_ERROR);    }

   // возврат результатов запроса

   return $result;  }

 // получение одного значения   (первого столбца из перворй строки) из запроса select

 public static function GetOne($sqlQuery, $params = null)  {

   // инициализация возвращаемого значения в null

   $result = null;

   // попытка выполнить SQL-запрос  или хранимую процедуру

   try    {

     // получение дескриптора бд

     $database_handler = self::GetHandler();

     // подготовка запроса к выполнению

     $statement_handler = $database_handler->prepare($sqlQuery);

     // выполнение 

     $statement_handler->execute($params);

     // получение результата

     $result = $statement_handler->fetch(PDO::FETCH_NUM);

     /* Сохранение первого значения из множества    (первого столбца из перворй строки) в  переменной $result */

     $result = $result[0];    }

   // если при выполнении запроса возникло исключение - генерация ошибки

   catch(PDOException $e)    {

     // закрытие дескриптора бд и генерация ошибки

     self::Close();      trigger_error($e->getMessage(), E_USER_ERROR);    }

   // возврат результатов запроса

   return $result;  }}   ?>

// error_handler.php

<?php

class ErrorHandler

{

 // закрытый конструктор, непозволяющий непосредственно создавать объекты класса

 private function __construct()

 {  }

 /* выбор метода ErrorHandler::Handler в качестве метода обработки ошибок */

 public static function SetHandler($errTypes = ERROR_TYPES)

 {    return set_error_handler(array ('ErrorHandler', 'Handler'), $errTypes);  }

 // метод обработки ошибок

 public static function Handler($errNo, $errStr, $errFile, $errLine)

 {        $backtrace = ErrorHandler::GetBacktrace(2);

   // сообщения об ошибках, кот. выводятся, отправляются по эл. почте, зап в журнал

   $error_message = "\nERRNO: $errNo\nTEXT: $errStr" . "\nLOCATION: $errFile, line " .

                    "$errLine, at " . date('F j, Y, g:i a') . "\nShowing backtrace:\n$backtrace\n\n";

   // отправка сообщения если SEND_ERROR_MAIL = true

   if (SEND_ERROR_MAIL == true) error_log($error_message, 1, ADMIN_ERROR_MAIL, "From: " .

               SENDMAIL_FROM . "\r\nTo: " . ADMIN_ERROR_MAIL);

   // запись в журнал LOG_ERRORS = true

   if (LOG_ERRORS == true)   error_log($error_message, 3, LOG_ERRORS_FILE);

/* выполнение не прекращается при предупреждениях (IS_WARNING_FATAL = false   или E_NOTICE и E_USER_NOTICE) */

 if (($errNo == E_WARNING && IS_WARNING_FATAL == false) || ($errNo == E_NOTICE || $errNo == E_USER_NOTICE))        {   

 // вывод сообщения при DEBUGGING = true , если не фатальная ошибка

     if (DEBUGGING == true)  echo '<div class="error_box"><pre>' . $error_message . '</pre></div>';    }  else    {

     // вывод сообщения  если фатальная ошибка

     if (DEBUGGING == true)   echo '<div class="error_box"><pre>'. $error_message . '</pre></div>';    else         {

       // очистка буфера вывода

       ob_clean();

       // загрузка стр с ошибкой 500

       include '500.php';

       // очистка буфера вывода и остановка выполнения

       flush();         ob_flush();         ob_end_clean();         exit();      }                        

         // остановка обработки запроса

     exit();    }  }

 // составление списка вызовов

 public static function GetBacktrace($irrelevantFirstEntries)

 {    $s = '';    $MAXSTRLEN = 64;    $trace_array = debug_backtrace();

   for ($i = 0; $i < $irrelevantFirstEntries; $i++)      array_shift($trace_array);    $tabs = sizeof($trace_array) - 1;

   foreach ($trace_array as $arr)    {      $tabs -= 1;      if (isset ($arr['class']))        $s .= $arr['class'] . '.';

     $args = array ();      if (!empty ($arr['args']))     foreach ($arr['args']as $v)

       {  if (is_null($v))   $args[] = 'null';   elseif (is_array($v))   $args[] = 'Array[' . sizeof($v) . ']';

         elseif (is_object($v))   $args[] = 'Object: ' . get_class($v);    elseif (is_bool($v))     $args[] = $v ? 'true' : 'false';

 else  {   $v = (string)@$v;   $str = htmlspecialchars(substr($v, 0, $MAXSTRLEN));  if (strlen($v) > $MAXSTRLEN)

             $str .= '...';        $args[] = '"' . $str . '"';       }      }

     $s .= $arr['function'] . '(' . implode(', ', $args) . ')';     $line = (isset ($arr['line']) ? $arr['line']: 'unknown');

     $file = (isset ($arr['file']) ? $arr['file']: 'unknown');     $s .= sprintf(' # line %4d, file: %s', $line, $file);      $s .= "\n";    }

   return $s;  }}?>

// secure_card.php

<?php

// представление кредитной карты

class SecureCard{

 // Private-элементы, содержащие инфо о  кредитной карте

 private $_mIsDecrypted = false;

 private $_mIsEncrypted = false;

 private $_mCardHolder;

 private $_mCardNumber;

 private $_mIssueDate;

 private $_mExpiryDate;

 private $_mIssueNumber;

 private $_mCardType;

 private $_mEncryptedData;

 private $_mXmlCardData;

 // конструктор класса

 public function __construct()  {

   // конструктор пуст

 }

 // расшифровка данных

 public function LoadEncryptedDataAndDecrypt($newEncryptedData)

 {    $this->_mEncryptedData = $newEncryptedData;    $this->DecryptData();  }

 // шифрование данных

 public function LoadPlainDataAndEncrypt($newCardHolder, $newCardNumber,

                                         $newIssueDate, $newExpiryDate,            $newIssueNumber, $newCardType)

 {    $this->_mCardHolder = $newCardHolder;    $this->_mCardNumber = $newCardNumber;

   $this->_mIssueDate = $newIssueDate;    $this->_mExpiryDate = $newExpiryDate;

   $this->_mIssueNumber = $newIssueNumber;    $this->_mCardType = $newCardType;  $this->EncryptData();  }

 // создание XML-документа с данными о карте

 private function CreateXml()  {

   // помещение данных в XML-документ

   $xml_card_data = &$this->_mXmlCardData;    $xml_card_data = new DOMDocument();

   $document_root = $xml_card_data->createElement('CardDetails');

   $child = $xml_card_data->createElement('CardHolder');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mCardHolder);    $value = $child->appendChild($value);

   $child = $xml_card_data->createElement('CardNumber');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mCardNumber);    $value = $child->appendChild($value);

   $child = $xml_card_data->createElement('IssueDate');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mIssueDate);    $value = $child->appendChild($value);

   $child = $xml_card_data->createElement('ExpiryDate');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mExpiryDate);    $value = $child->appendChild($value);

   $child = $xml_card_data->createElement('IssueNumber');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mIssueNumber);    $value = $child->appendChild($value);

   $child = $xml_card_data->createElement('CardType');    $child = $document_root->appendChild($child);

   $value = $xml_card_data->createTextNode($this->_mCardType);    $value = $child->appendChild($value);

   $document_root = $xml_card_data->appendChild($document_root);  }

 // извлечение из XML-документа данных о карте

 private function ExtractXml($decryptedData)

 {    $xml = simplexml_load_string($decryptedData);    $this->_mCardHolder = (string) $xml->CardHolder;

   $this->_mCardNumber = (string) $xml->CardNumber;    $this->_mIssueDate = (string) $xml->IssueDate;

   $this->_mExpiryDate = (string) $xml->ExpiryDate;    $this->_mIssueNumber = (string) $xml->IssueNumber;

   $this->_mCardType = (string) $xml->CardType;  }

 // зашифровка данных о кредитной карте

 private function EncryptData()  {

   // помещение данных в XML-документ

   $this->CreateXml();

   // шифрование данных

   $this->_mEncryptedData =      SymmetricCrypt::Encrypt($this->_mXmlCardData->saveXML());

   // установка флага

   $this->_mIsEncrypted = true;  }

 // расшифровка данных о кредитной карте и извлечение из XML-документа

 private function DecryptData()  {

   // расшифровка данных

   $decrypted_data = SymmetricCrypt::Decrypt($this->_mEncryptedData);

   // извлечение из XML-документа

   $this->ExtractXml($decrypted_data);

   // установка флага расшифровки

   $this->_mIsDecrypted = true;  }

 public function __get($name)

 {    if ($name == 'EncryptedData')    {      if ($this->_mIsEncrypted)   return $this->_mEncryptedData;      else

       throw new Exception('Data not encrypted');    }    elseif ($name == 'CardNumberX')

  {   if ($this->_mIsDecrypted)        return 'XXXX-XXXX-XXXX-' .    substr($this->_mCardNumber, strlen($this->_mCardNumber) - 4, 4);      else        throw new Exception('Data not decrypted');    }

   elseif (in_array($name, array ('CardHolder', 'CardNumber', 'IssueDate',    'ExpiryDate', 'IssueNumber', 'CardType')))

{ $name = '_m' . $name; if ($this->_mIsDecrypted)   return $this->$name; else   throw new Exception('Data not decrypted');    }    else    {   throw new Exception('Property ' . $name . ' not found');    }  }}?>

// оrder_рrocessor.php

<?php

/* основной класс конвейера, используется для получения инфо о заказах,

вызова классов этапов конвейера, аудита заказов и прочего*/

class OrderProcessor{

 // Public-переменные доступные в шаблоне Smarty

 public  $mOrderInfo;

 public  $mOrderDetailsInfo;

 public  $mCustomerInfo;

 public  $mContinueNow;

 // Private-элементы

 private $_mCurrentPipelineSection;

 private $_mOrderProcessStage;

 // конструктор класса

 public function __construct($orderId)  {

   // получение заказа

   $this->mOrderInfo = Orders::GetOrderInfo($orderId);

   if (empty ($this->mOrderInfo['shipping_id']))     $this->mOrderInfo['shipping_id'] = -1;

   if (empty ($this->mOrderInfo['tax_id']))      $this->mOrderInfo['tax_id'] = -1;

   //  получение инфо о заказе

   $this->mOrderDetailsInfo = Orders::GetOrderDetails($orderId);

   // получение идентификатора покупателя, разместившего заказ

   $this->mCustomerInfo = Customer::Get($this->mOrderInfo['customer_id']);

   $credit_card = new SecureCard();    $credit_card->LoadEncryptedDataAndDecrypt(

     $this->mCustomerInfo['credit_card']);   $this->mCustomerInfo['credit_card'] = $credit_card;  }

 /* метод Process() вызывается из файлов presentation/checkout_info.php и

    presentation/admin_orders.php для обработки заказа */

 public function Process()  {

   // настройка обработки заказа

   $this->mContinueNow = true;

   // фиксирование в журнале начала обработки

   $this->CreateAudit('Order Processor started.', 10000);

   // вызов этапа конвейера

   try    {      while ($this->mContinueNow)      {        $this->mContinueNow = false;

       $this->_GetCurrentPipelineSection();        $this->_mCurrentPipelineSection->Process($this);      }    }

catch(Exception $e)    {   $this->MailAdmin('Order Processing error occurred.',   'Exception: "' . $e->getMessage() . '" on ' .

                      $e->getFile() . ' line ' . $e->getLine(),     $this->_mOrderProcessStage);

     $this->CreateAudit('Order Processing error occurred.', 10002);   throw new Exception('Error occurred, order aborted. ' .

                         'Details mailed to administrator.');    }  $this->CreateAudit('Order Processor finished.', 10001);  }

 // добавление сообщения аудита

 public function CreateAudit($message, $code)

 {    Orders::CreateAudit($this->mOrderInfo['order_id'], $message, $code);  }

 // составление сообщения эл. почты

 public function MailAdmin($subject, $message, $sourceStage)  {    $to = ADMIN_EMAIL;

   $headers = 'From: ' . ORDER_PROCESSOR_EMAIL . "\r\n";    $body = 'Message: ' . $message . "\n" .

           'Source: ' . $sourceStage . "\n" . 'Order ID: ' . $this->mOrderInfo['order_id'];

   $result = mail($to, $subject, $body, $headers);    if ($result === false)    {

     throw new Exception ('Failed sending this mail to administrator:' .   "\n" . $body);    }  }

 // возврат текущего этапа конвейера

 private function _GetCurrentPipelineSection()  {    switch($this->mOrderInfo['status'])    {

     case 0:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsInitialNotification();        break;

     case 1:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsCheckFunds();        break;

     case 2:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsCheckStock();        break;

     case 3:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsStockOk();        break;

     case 4:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsTakePayment();        break;

     case 5:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsShipGoods();        break;

     case 6:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsShipOk();        break;

     case 7:        $this->_mOrderProcessStage = $this->mOrderInfo['status'];

       $this->_mCurrentPipelineSection = new PsFinalNotification();       break;

     case 8:        $this->_mOrderProcessStage = 100;

       throw new Exception('Order already been completed.');        break;

     default:        $this->_mOrderProcessStage = 100;  throw new Exception('Unknown pipeline section requested.'); }  }

 // задание статуса заказа

 public function UpdateOrderStatus($status)

 {    Orders::UpdateOrderStatus($this->mOrderInfo['order_id'], $status);    $this->mOrderInfo['status'] = $status;  }

 // задание кода авторизации заказа

 public function SetAuthCodeAndReference($authCode, $reference)  {

   Orders::SetOrderAuthCodeAndReference($this->mOrderInfo['order_id'],                $authCode, $reference);

   $this->mOrderInfo['auth_code'] = $authCode;    $this->mOrderInfo['reference'] = $reference;  }

 // задание даты отправки заказа

 public function SetDateShipped()  {  Orders::SetDateShipped($this->mOrderInfo['order_id']);

   $this->mOrderInfo['shipped_on'] = date('Y-m-d');  }     

 // отправка e-mail покупателю

 public function MailCustomer($subject, $body)

 {    $to = $this->mCustomerInfo['email'];    $headers = 'From: ' . CUSTOMER_SERVICE_EMAIL . "\r\n";

   $result = mail($to, $subject, $body, $headers);    if ($result === false)  {

     throw new Exception ('Unable to send e-mail to customer.');   }  }

 // отправка e-mail поставщику

 public function MailSupplier($subject, $body)

 {    $to = SUPPLIER_EMAIL;    $headers = 'From: ' . ORDER_PROCESSOR_EMAIL . "\r\n";

   $result = mail($to, $subject, $body, $headers);    if ($result === false)

   {      throw new Exception ('Unable to send e-mail to supplier.');   }  }

 // возврат адреса покупателя в виде строки

 public function GetCustomerAddressAsString()

 {    $new_line = "\n";    $address_details = $this->mCustomerInfo['name'] . $new_line .

$this->mCustomerInfo['address_1'] . $new_line;    if (!empty ($this->mOrderInfo['address_2']))

     $address_details .= $this->mCustomerInfo['address_2'] . $new_line;

   $address_details .= $this->mCustomerInfo['city'] . $new_line .

                       $this->mCustomerInfo['region'] . $new_line .  $this->mCustomerInfo['postal_code'] . $new_line .

                       $this->mCustomerInfo['country'];    return $address_details;  }

 // возврат строки со сведениями о заказе

 public function GetOrderAsString($withCustomerDetails = true)

 {    $total_cost = 0.00;    $order_details = '';    $new_line = "\n";    if ($withCustomerDetails)

{ $order_details = 'Customer address:' . $new_line .  $this->GetCustomerAddressAsString() .  $new_line . $new_line;

$order_details .= 'Customer credit card:' . $new_line . $this->mCustomerInfo['credit_card']->CardNumberX .

$new_line . $new_line;    }   foreach ($this->mOrderDetailsInfo as $order_detail)

   {      $order_details .= $order_detail['quantity'] . ' ' . $order_detail['product_name'] . '(' .   $order_detail['attributes'] . ') $' .

  $order_detail['unit_cost'] . ' each, total cost $' .    number_format($order_detail['subtotal'],         2, '.', '') . $new_line;

     $total_cost += $order_detail['subtotal'];    }

   // добавление стоимости доставки

   if ($this->mOrderInfo['shipping_id'] != -1)    {

  $order_details .= 'Shipping: ' . $this->mOrderInfo['shipping_type'] .   $new_line;    

 $total_cost += $this->mOrderInfo['shipping_cost'];    }

   // добавление налогов

   if ($this->mOrderInfo['tax_id'] != -1 &&     $this->mOrderInfo['tax_percentage'] != 0.00)

   {      $tax_amount = round((float)$total_cost *    (float)$this->mOrderInfo['tax_percentage'], 2)    / 100.00;

     $order_details .= 'Tax: ' . $this->mOrderInfo['tax_type'] . ', $' .    number_format($tax_amount, 2, '.', '') .   $new_line;

$total_cost += $tax_amount; }  $order_details .= $new_line . 'Total order cost: $' .   number_format($total_cost, 2, '.', '');

   return $order_details;  } } ?>

// admin_menu.php

<?php

class AdminMenu

{  public $mLinkToStoreAdmin;

 public $mLinkToAttributesAdmin;

 public $mLinkToCartsAdmin;

 public $mLinkToOrdersAdmin;

 public $mLinkToStoreFront;

 public $mLinkToLogout;

 public function __construct()

 {    $this->mLinkToStoreAdmin = Link::ToAdmin();     $this->mLinkToAttributesAdmin = Link::ToAttributesAdmin();

     $this->mLinkToCartsAdmin = Link::ToCartsAdmin();      $this->mLinkToOrdersAdmin = Link::ToOrdersAdmin();

   if (isset ($_SESSION['link_to_store_front']))      $this->mLinkToStoreFront = $_SESSION['link_to_store_front'];

   else      $this->mLinkToStoreFront = Link::ToIndex();    $this->mLinkToLogout = Link::ToLogout();  } }?>

// admin_login.php

<?php

// класс аутентификации админа

class AdminLogin {

 // Public-переменные доступные в шаблоне Smarty 

 public $mUsername;

 public $mLoginMessage = '';

 public $mLinkToAdmin;

 public $mLinkToIndex;

 // конструктор класса

 public function __construct()  {

   // проверка правильности ввода  идентификатора пользователя и пароля

if (isset ($_POST['submit']))  { if ($_POST['username'] == ADMIN_USERNAME  &&

$_POST['password'] == ADMIN_PASSWORD)      {   $_SESSION['admin_logged'] = true;

       header('Location: ' . Link::ToAdmin());        exit();      }

     else        $this->mLoginMessage = 'Login failed. Please try again:';   }

   $this->mLinkToAdmin = Link::ToAdmin();    $this->mLinkToIndex = Link::ToIndex();  } } ?>

// admin_products.php

<?php

// класс обеспечивающий функциональность админ-я товаров категории

class AdminProducts {

 // Public-переменные доступные в шаблоне Smarty 

 public $mProductsCount;

 public $mProducts;

 public $mErrorMessage;

 public $mDepartmentId;

 public $mCategoryId;

 public $mCategoryName;

 public $mLinkToDepartmentCategoriesAdmin;

 public $mLinkToCategoryProductsAdmin;

 // Private-элементы

 private $_mAction;

 private $_mActionedProductId;

 // конструктор класса

 public function __construct()

 {    if (isset ($_GET['DepartmentId']))      $this->mDepartmentId = (int)$_GET['DepartmentId'];

   else      trigger_error('DepartmentId not set');

   if (isset ($_GET['CategoryId']))      $this->mCategoryId = (int)$_GET['CategoryId'];    else

     trigger_error('CategoryId not set');    $category_details = Catalog::GetCategoryDetails($this->mCategoryId);

   $this->mCategoryName = $category_details['name'];    foreach ($_POST as $key => $value)

     // если нажата кнопка отправки ...

     if (substr($key, 0, 6) == 'submit')      {

       /* получение позиции последнего символа '_' из имени кнопки

          например strtpos('submit_edit_prod_1', '_') is 17 */

       $last_underscore = strrpos($key, '_');

       /* получение области действия  из имени кнопки

          (например 'edit_dep' from 'submit_edit_prod_1') */

       $this->_mAction = substr($key, strlen('submit_'),            $last_underscore - strlen('submit_'));

       /* получение идентификатора отдела к которому относится нажатая кнопка

                  например '1' from 'submit_edit_prod_1' */

       $this->_mActionedProductId = (int)substr($key, $last_underscore + 1);        break;      }

   $this->mLinkToDepartmentCategoriesAdmin =    Link::ToDepartmentCategoriesAdmin($this->mDepartmentId);

$this->mLinkToCategoryProductsAdmin = Link::ToCategoryProductsAdmin($this->mDepartmentId, $this->mCategoryId);  }

 public function init()  {

   // при добавлении нового товара ...

   if ($this->_mAction == 'add_prod')

   {      $product_name = $_POST['product_name'];       $product_unit = $_POST['product_unit'];

     $product_description = $_POST['product_description'];      $product_price = $_POST['product_price'];

     if ($product_name == null)        $this->mErrorMessage = 'Product name is empty';

       if ($product_unit == null)        $this->mErrorMessage = 'Product unit is empty';

     if ($product_description == null)        $this->mErrorMessage = 'Product description is empty';

     if ($product_price == null || !is_numeric($product_price))  $this->mErrorMessage = 'Product price must be a number!';

     if ($this->mErrorMessage == null)      {

 Catalog::AddProductToCategory($this->mCategoryId, $product_name, $product_unit,

 $product_description, $product_price); header('Location: ' . htmlspecialchars_decode( $this->mLinkToCategoryProductsAdmin));      }    }  

   // для просмотра сведений  о товаре

   if ($this->_mAction == 'edit_prod')    {

     header('Location: ' . htmlspecialchars_decode(Link::ToProductAdmin($this->mDepartmentId,  $this->mCategoryId,

 $this->_mActionedProductId)));      exit();    }

   $this->mProducts = Catalog::GetCategoryProducts($this->mCategoryId);

   $this->mProductsCount = count($this->mProducts); } } ?>


Приложение В
Листинг хранимых процедур базы данных    

-- Change DELIMITER to $$

DELIMITER $$

-- Create catalog_get_departments_list stored procedure       

CREATE PROCEDURE catalog_get_departments_list()

BEGIN  SELECT department_id, name FROM department ORDER BY department_id; END$$

-- Create catalog_get_department_details stored procedure

CREATE PROCEDURE catalog_get_department_details(IN inDepartmentId INT)

BEGIN  SELECT name, description  FROM   department  WHERE  department_id = inDepartmentId; END$$

-- Create catalog_get_categories_list stored procedure

CREATE PROCEDURE catalog_get_categories_list(IN inDepartmentId INT)

BEGIN  SELECT   category_id, name  FROM     category  WHERE    department_id = inDepartmentId

 ORDER BY category_id; END$$

-- Create catalog_get_category_details stored procedure  

CREATE PROCEDURE catalog_get_category_details(IN inCategoryId INT)

BEGIN  SELECT name, description  FROM   category  WHERE  category_id = inCategoryId; END$$

-- Create catalog_count_products_in_category stored procedure   

CREATE PROCEDURE catalog_count_products_in_category(IN inCategoryId INT)

BEGIN  SELECT     COUNT(*) AS categories_count  FROM       product p

 INNER JOIN product_category pc               ON p.product_id = pc.product_id

 WHERE      pc.category_id = inCategoryId; END$$

-- Create catalog_get_products_in_category stored procedure

CREATE PROCEDURE catalog_get_products_in_category(

 IN inCategoryId INT, IN inShortProductDescriptionLength INT,

 IN inProductsPerPage INT, IN inStartItem INT)

BEGIN

 -- Prepare statement

 PREPARE statement FROM   "SELECT     p.product_id, p.name,  p.unit,

              IF(LENGTH(p.description) <= ?,                  p.description,

                 CONCAT(LEFT(p.description, ?),   '...')) AS description,     p.price, p.discounted_price, p.thumbnail

   FROM       product p    INNER JOIN product_category pc

                ON p.product_id = pc.product_id    WHERE      pc.category_id = ?

   ORDER BY   p.display DESC    LIMIT      ?, ?";

 -- Define query parameters

 SET @p1 = inShortProductDescriptionLength;   SET @p2 = inShortProductDescriptionLength;

 SET @p3 = inCategoryId;  SET @p4 = inStartItem;   SET @p5 = inProductsPerPage;

 -- Execute the statement

 EXECUTE statement USING @p1, @p2, @p3, @p4, @p5; END$$

-- Create catalog_count_products_on_department stored procedure  7

CREATE PROCEDURE catalog_count_products_on_department(IN inDepartmentId INT)

BEGIN  SELECT DISTINCT COUNT(*) AS products_on_department_count

 FROM            product p  INNER JOIN      product_category pc    ON p.product_id = pc.product_id

 INNER JOIN      category c       ON pc.category_id = c.category_id

 WHERE           (p.display = 2 OR p.display = 3)   AND c.department_id = inDepartmentId; END$$

-- Create catalog_get_products_on_department stored procedure  

CREATE PROCEDURE catalog_get_products_on_department(

 IN inDepartmentId INT, IN inShortProductDescriptionLength INT,

 IN inProductsPerPage INT, IN inStartItem INT) BEGIN

 PREPARE statement FROM    "SELECT DISTINCT p.product_id, p.name,  p.unit,

                    IF(LENGTH(p.description) <= ?,          p.description,

                       CONCAT(LEFT(p.description, ?),    '...')) AS description,

                    p.price, p.discounted_price, p.thumbnail  FROM    product p

    INNER JOIN      product_category pc    ON p.product_id = pc.product_id

    INNER JOIN      category c    ON pc.category_id = c.category_id

    WHERE           (p.display = 2 OR p.display = 3)     AND c.department_id = ?

    ORDER BY        p.display DESC LIMIT           ?, ?";

 SET @p1 = inShortProductDescriptionLength;  SET @p2 = inShortProductDescriptionLength;

 SET @p3 = inDepartmentId;  SET @p4 = inStartItem;  SET @p5 = inProductsPerPage;

 EXECUTE statement USING @p1, @p2, @p3, @p4, @p5; END$$

-- Create catalog_count_products_on_catalog stored procedure   

CREATE PROCEDURE catalog_count_products_on_catalog()

BEGIN  SELECT COUNT(*) AS products_on_catalog_count

 FROM   product  WHERE  display = 1 OR display = 3; END$$

-- Create catalog_get_products_on_catalog stored procedure    

CREATE PROCEDURE catalog_get_products_on_catalog(

 IN inShortProductDescriptionLength INT,  IN inProductsPerPage INT, IN inStartItem INT)

BEGIN  PREPARE statement FROM    "SELECT   product_id, name,  unit,

             IF(LENGTH(description) <= ?,    description,   CONCAT(LEFT(description, ?),   '...')) AS description,

             price, discounted_price, thumbnail    FROM     product    WHERE    display = 1 OR display = 3

    ORDER BY display DESC  LIMIT    ?, ?";

 SET @p1 = inShortProductDescriptionLength;  SET @p2 = inShortProductDescriptionLength;

 SET @p3 = inStartItem;  SET @p4 = inProductsPerPage;

 EXECUTE statement USING @p1, @p2, @p3, @p4; END$$

-- Create catalog_get_product_details stored procedure    

CREATE PROCEDURE catalog_get_product_details(IN inProductId INT)

BEGIN  SELECT product_id, name, unit, description,

        price, discounted_price, image, image_2

 FROM   product  WHERE  product_id = inProductId; END$$

-- Create catalog_get_product_locations stored procedure     

CREATE PROCEDURE catalog_get_product_locations(IN inProductId INT)

BEGIN  SELECT c.category_id, c.name AS category_name, c.department_id,

        (SELECT name    FROM   department  WHERE  department_id = c.department_id) AS department_name

         -- Subquery returns the name of the department of the category

 FROM   category c  WHERE  c.category_id IN

          (SELECT category_id            FROM   product_category          WHERE  product_id = inProductId);

           -- Subquery returns the category IDs a product belongs to

END$$

-- Create catalog_get_product_attributes stored procedure  

CREATE PROCEDURE catalog_get_product_attributes(IN inProductId INT)

BEGIN  SELECT     a.name AS attribute_name,

            av.attribute_value_id, av.value AS attribute_value

 FROM       attribute_value av  INNER JOIN attribute a   ON av.attribute_id = a.attribute_id

 WHERE      av.attribute_value_id IN   (SELECT attribute_value_id  FROM   product_attribute

               WHERE  product_id = inProductId) ORDER BY   a.name; END$$

-- Create catalog_get_department_name stored procedure  

CREATE PROCEDURE catalog_get_department_name(IN inDepartmentId INT)

BEGIN  SELECT name FROM department WHERE department_id = inDepartmentId; END$$

-- Create catalog_get_category_name stored procedure   

CREATE PROCEDURE catalog_get_category_name(IN inCategoryId INT)

BEGIN  SELECT name FROM category WHERE category_id = inCategoryId; END$$

-- Create catalog_get_product_name stored procedure  

CREATE PROCEDURE catalog_get_product_name(IN inProductId INT)

BEGIN  SELECT name FROM product WHERE product_id = inProductId; END$$

-- Create catalog_count_search_result stored procedure  

CREATE PROCEDURE catalog_count_search_result(

 IN inSearchString TEXT, IN inAllWords VARCHAR(3))

BEGIN  IF inAllWords = "on" THEN   PREPARE statement FROM

     "SELECT   count(*)  FROM     product

      WHERE    MATCH (name, description) AGAINST (? IN BOOLEAN MODE)";

 ELSE    PREPARE statement FROM    "SELECT   count(*)

      FROM     product   WHERE    MATCH (name, description) AGAINST (?)";  END IF;

 SET @p1 = inSearchString;  EXECUTE statement USING @p1; END$$

-- Create catalog_search stored procedure      

CREATE PROCEDURE catalog_search(  IN inSearchString TEXT, IN inAllWords VARCHAR(3),

 IN inShortProductDescriptionLength INT,  IN inProductsPerPage INT, IN inStartItem INT) BEGIN

 IF inAllWords = "on" THEN    PREPARE statement FROM  "SELECT   product_id, name, unit,

               IF(LENGTH(description) <= ?,   description,  CONCAT(LEFT(description, ?),  '...')) AS description,

               price, discounted_price, thumbnail      FROM     product

      WHERE    MATCH (name, description)   AGAINST (? IN BOOLEAN MODE)

      ORDER BY MATCH (name, description)  AGAINST (? IN BOOLEAN MODE) DESC

      LIMIT    ?, ?"; ELSE    PREPARE statement FROM   "SELECT   product_id, name, unit,

               IF(LENGTH(description) <= ?,  description,   CONCAT(LEFT(description, ?),   '...'))

AS description,  price, discounted_price, thumbnail     FROM     product

WHERE MATCH (name, description) AGAINST (?)  

ORDER BY MATCH (name, description) AGAINST (?) DESC     LIMIT    ?, ?";  END IF;

 SET @p1 = inShortProductDescriptionLength;  SET @p2 = inSearchString;

 SET @p3 = inStartItem;  SET @p4 = inProductsPerPage;

 EXECUTE statement USING @p1, @p1, @p2, @p2, @p3, @p4; END$$

-- Create catalog_get_departments stored procedure  

CREATE PROCEDURE catalog_get_departments()

BEGIN  SELECT   department_id, name, description  FROM     department

 ORDER BY department_id; END$$

-- Create catalog_add_department stored procedure

CREATE PROCEDURE catalog_add_department(

 IN inName VARCHAR(100), IN inDescription VARCHAR(1000))

BEGIN  INSERT INTO department (name, description)  VALUES (inName, inDescription); END$$

-- Create catalog_update_department stored procedure

CREATE PROCEDURE catalog_update_department(IN inDepartmentId INT,

 IN inName VARCHAR(100), IN inDescription VARCHAR(1000))

BEGIN  UPDATE department  SET    name = inName, description = inDescription

 WHERE  department_id = inDepartmentId; END$$

-- Create catalog_delete_department stored procedure     

CREATE PROCEDURE catalog_delete_department(IN inDepartmentId INT)

BEGIN  DECLARE categoryRowsCount INT;

 SELECT count(*)  FROM   category  WHERE  department_id = inDepartmentId

 INTO   categoryRowsCount;    IF categoryRowsCount = 0 THEN

   DELETE FROM department WHERE department_id = inDepartmentId;

   SELECT 1;  ELSE    SELECT -1;  END IF; END$$

-- Create catalog_get_department_categories stored procedure  

CREATE PROCEDURE catalog_get_department_categories(IN inDepartmentId INT)

BEGIN  SELECT   category_id, name, description  FROM     category

 WHERE    department_id = inDepartmentId  ORDER BY category_id; END$$

-- Create catalog_add_category stored procedure   

CREATE PROCEDURE catalog_add_category(IN inDepartmentId INT,

 IN inName VARCHAR(100), IN inDescription VARCHAR(1000))

BEGIN  INSERT INTO category (department_id, name, description)

        VALUES (inDepartmentId, inName, inDescription); END$$

-- Create catalog_update_category stored procedure  

CREATE PROCEDURE catalog_update_category(IN inCategoryId INT,

 IN inName VARCHAR(100), IN inDescription VARCHAR(1000))

BEGIN    UPDATE category    SET    name = inName, description = inDescription

   WHERE  category_id = inCategoryId; END$$

-- Create catalog_delete_category stored procedure      

CREATE PROCEDURE catalog_delete_category(IN inCategoryId INT)

BEGIN  DECLARE productCategoryRowsCount INT;

 SELECT      count(*)  FROM        product p  INNER JOIN  product_category pc

               ON p.product_id = pc.product_id  WHERE       pc.category_id = inCategoryId

 INTO        productCategoryRowsCount;  IF productCategoryRowsCount = 0 THEN

   DELETE FROM category WHERE category_id = inCategoryId;

   SELECT 1;  ELSE    SELECT -1;  END IF; END$$

-- Create catalog_get_attributes stored procedure  

CREATE PROCEDURE catalog_get_attributes()

BEGIN  SELECT attribute_id, name FROM attribute ORDER BY attribute_id; END$$

-- Create catalog_add_attribute stored procedure  

CREATE PROCEDURE catalog_add_attribute(IN inName VARCHAR(100))

BEGIN  INSERT INTO attribute (name) VALUES (inName); END$$

-- Create catalog_update_attribute stored procedure

CREATE PROCEDURE catalog_update_attribute(  IN inAttributeId INT, IN inName VARCHAR(100))

BEGIN  UPDATE attribute SET name = inName WHERE attribute_id = inAttributeId; END$$

-- Create catalog_delete_attribute stored procedure

CREATE PROCEDURE catalog_delete_attribute(IN inAttributeId INT)

BEGIN  DECLARE attributeRowsCount INT;  SELECT count(*)  FROM   attribute_value

 WHERE  attribute_id = inAttributeId  INTO   attributeRowsCount;  IF attributeRowsCount = 0 THEN

   DELETE FROM attribute WHERE attribute_id = inAttributeId;    SELECT 1;

 ELSE    SELECT -1;  END IF; END$$

-- Create catalog_get_attribute_details stored procedure     

CREATE PROCEDURE catalog_get_attribute_details(IN inAttributeId INT)

BEGIN  SELECT attribute_id, name  FROM   attribute  WHERE  attribute_id = inAttributeId; END$$

-- Create catalog_get_attribute_values stored procedure   

CREATE PROCEDURE catalog_get_attribute_values(IN inAttributeId INT)

BEGIN  SELECT   attribute_value_id, value  FROM     attribute_value

 WHERE    attribute_id = inAttributeId  ORDER BY attribute_id; END$$

-- Create catalog_add_attribute_value stored procedure  

CREATE PROCEDURE catalog_add_attribute_value(  IN inAttributeId INT, IN inValue VARCHAR(100))

BEGIN  INSERT INTO attribute_value (attribute_id, value)   VALUES (inAttributeId, inValue); END$$

-- Create catalog_update_attribute_value stored procedure    

CREATE PROCEDURE catalog_update_attribute_value(

 IN inAttributeValueId INT, IN inValue VARCHAR(100)) BEGIN

  UPDATE attribute_value    SET    value = inValue    WHERE  attribute_value_id = inAttributeValueId; END$$

-- Create catalog_delete_attribute_value stored procedure   

CREATE PROCEDURE catalog_delete_attribute_value(IN inAttributeValueId INT)

BEGIN  DECLARE productAttributeRowsCount INT;  SELECT      count(*)

 FROM        product p  INNER JOIN  product_attribute pa

               ON p.product_id = pa.product_id  WHERE       pa.attribute_value_id = inAttributeValueId

 INTO        productAttributeRowsCount;  IF productAttributeRowsCount = 0 THEN

   DELETE FROM attribute_value WHERE attribute_value_id = inAttributeValueId;

   SELECT 1;  ELSE    SELECT -1;  END IF; END$$

-- Create catalog_get_category_products stored procedure      

CREATE PROCEDURE catalog_get_category_products(IN inCategoryId INT)

BEGIN  SELECT     p.product_id, p.name, p.unit, p.description, p.price,

            p.discounted_price  FROM       product p  INNER JOIN product_category pc

              ON p.product_id = pc.product_id  WHERE      pc.category_id = inCategoryId

 ORDER BY   p.product_id; END$$

-- Create catalog_add_product_to_category stored procedure     

CREATE PROCEDURE catalog_add_product_to_category(IN inCategoryId INT,

 IN inName VARCHAR(100), IN inUnit VARCHAR(30), IN inDescription VARCHAR(1000),

 IN inPrice DECIMAL(10, 2)) BEGIN  DECLARE productLastInsertId INT;

 INSERT INTO product (name, unit, description, price)   VALUES (inName, inDescription, inPrice);

 SELECT LAST_INSERT_ID() INTO productLastInsertId;

 INSERT INTO product_category (product_id, category_id)

        VALUES (productLastInsertId, inCategoryId); END$$

-- Create catalog_update_product stored procedure   

CREATE PROCEDURE catalog_update_product(IN inProductId INT,

 IN inName VARCHAR(100), IN inUnit VARCHAR(30), IN inDescription VARCHAR(1000),

 IN inPrice DECIMAL(10, 2), IN inDiscountedPrice DECIMAL(10, 2))

BEGIN  UPDATE product  SET    name = inName, unit = inUnit, description = inDescription, price = inPrice,

        discounted_price = inDiscountedPrice  WHERE  product_id = inProductId; END$$

-- Create catalog_delete_product stored procedure   

CREATE PROCEDURE catalog_delete_product(IN inProductId INT)

BEGIN  DELETE FROM product_attribute WHERE product_id = inProductId;

 DELETE FROM product_category WHERE product_id = inProductId;

 DELETE FROM product WHERE product_id = inProductId; END$$

-- Create catalog_remove_product_from_category stored procedure  

CREATE PROCEDURE catalog_remove_product_from_category(

 IN inProductId INT, IN inCategoryId INT) BEGIN

 DECLARE productCategoryRowsCount INT;  SELECT count(*)  FROM   product_category

 WHERE  product_id = inProductId  INTO   productCategoryRowsCount;

 IF productCategoryRowsCount = 1 THEN    CALL catalog_delete_product(inProductId);

   SELECT 0;  ELSE    DELETE FROM product_category

   WHERE  category_id = inCategoryId AND product_id = inProductId;    SELECT 1;  END IF; END$$

-- Create catalog_get_categories stored procedure   

CREATE PROCEDURE catalog_get_categories()

BEGIN  SELECT   category_id, name, description  FROM     category  ORDER BY category_id; END$$

-- Create catalog_get_product_info stored procedure       

CREATE PROCEDURE catalog_get_product_info(IN inProductId INT)

BEGIN  SELECT product_id, name, unit, description, price, discounted_price,

        image, image_2, thumbnail, display  FROM   product  WHERE  product_id = inProductId; END$$

-- Create catalog_get_categories_for_product stored procedure    

CREATE PROCEDURE catalog_get_categories_for_product(IN inProductId INT)

BEGIN  SELECT   c.category_id, c.department_id, c.name

 FROM     category c  JOIN     product_category pc       ON c.category_id = pc.category_id

 WHERE    pc.product_id = inProductId  ORDER BY category_id; END$$

-- Create catalog_set_product_display_option stored procedure

CREATE PROCEDURE catalog_set_product_display_option(

 IN inProductId INT, IN inDisplay SMALLINT) BEGIN

 UPDATE product SET display = inDisplay WHERE product_id = inProductId;   END$$

-- Create catalog_assign_product_to_category stored procedure   

CREATE PROCEDURE catalog_assign_product_to_category(

 IN inProductId INT, IN inCategoryId INT) BEGIN

 INSERT INTO product_category (product_id, category_id)  VALUES (inProductId, inCategoryId); END$$

-- Create catalog_move_product_to_category stored procedure

CREATE PROCEDURE catalog_move_product_to_category(IN inProductId INT,

 IN inSourceCategoryId INT, IN inTargetCategoryId INT) BEGIN

 UPDATE product_category  SET    category_id = inTargetCategoryId

 WHERE  product_id = inProductId   AND category_id = inSourceCategoryId; END$$

-- Create catalog_get_attributes_not_assigned_to_product stored procedure   

CREATE PROCEDURE catalog_get_attributes_not_assigned_to_product(

 IN inProductId INT) BEGIN  SELECT     a.name AS attribute_name,

            av.attribute_value_id, av.value AS attribute_value  FROM       attribute_value av

 INNER JOIN attribute a   ON av.attribute_id = a.attribute_id

 WHERE      av.attribute_value_id NOT IN    (SELECT attribute_value_id

             FROM   product_attribute    WHERE  product_id = inProductId)

 ORDER BY   attribute_name, av.attribute_value_id; END$$

-- Create catalog_assign_attribute_value_to_product stored procedure   

CREATE PROCEDURE catalog_assign_attribute_value_to_product(

 IN inProductId INT, IN inAttributeValueId INT) BEGIN

INSERT INTO product_attribute (product_id, attribute_value_id)

VALUES (inProductId, inAttributeValueId); END$$

-- Create catalog_remove_product_attribute_value stored procedure      

CREATE PROCEDURE catalog_remove_product_attribute_value(

 IN inProductId INT, IN inAttributeValueId INT) BEGIN

 DELETE FROM product_attribute  WHERE       product_id = inProductId AND

             attribute_value_id = inAttributeValueId; END$$

-- Create catalog_set_image stored procedure      

CREATE PROCEDURE catalog_set_image(  IN inProductId INT, IN inImage VARCHAR(150))

BEGIN  UPDATE product SET image = inImage WHERE product_id = inProductId; END$$

-- Create catalog_set_image_2 stored procedure  

CREATE PROCEDURE catalog_set_image_2(  IN inProductId INT, IN inImage VARCHAR(150))

BEGIN  UPDATE product SET image_2 = inImage WHERE product_id = inProductId; END$$

-- Create catalog_set_thumbnail stored procedure  

CREATE PROCEDURE catalog_set_thumbnail(  IN inProductId INT, IN inThumbnail VARCHAR(150))

BEGIN  UPDATE product  SET    thumbnail = inThumbnail  WHERE  product_id = inProductId; END$$

-- Create shopping_cart_add_product stored procedure

CREATE PROCEDURE shopping_cart_add_product(IN inCartId CHAR(32),

 IN inProductId INT, IN inAttributes VARCHAR(1000)) BEGIN  DECLARE productQuantity INT;

 -- Obtain current shopping cart quantity for the product

 SELECT quantity  FROM   shopping_cart  WHERE  cart_id = inCartId   AND product_id = inProductId

        AND attributes = inAttributes  INTO   productQuantity;

 -- Create new shopping cart record, or increase quantity of existing record   

 IF productQuantity IS NULL THEN   INSERT INTO shopping_cart(cart_id, product_id, attributes,

           quantity, added_on)     VALUES (inCartId, inProductId, inAttributes, 1, NOW());

 ELSE    UPDATE shopping_cart    SET    quantity = quantity + 1, buy_now = true

   WHERE  cart_id = inCartId           AND product_id = inProductId

          AND attributes = inAttributes;  END IF; END$$

-- Create shopping_cart_update_product stored procedure     

CREATE PROCEDURE shopping_cart_update(IN inItemId INT, IN inQuantity INT)

BEGIN  IF inQuantity > 0 THEN    UPDATE shopping_cart

   SET    quantity = inQuantity, added_on = NOW()   WHERE  item_id = inItemId;

 ELSE    CALL shopping_cart_remove_product(inItemId);  END IF; END$$

-- Create shopping_cart_remove_product stored procedure   

CREATE PROCEDURE shopping_cart_remove_product(IN inItemId INT)

BEGIN  DELETE FROM shopping_cart WHERE item_id = inItemId; END$$

-- Create shopping_cart_get_products stored procedure

CREATE PROCEDURE shopping_cart_get_products(IN inCartId CHAR(32))

BEGIN  SELECT     sc.item_id, p.name, p.unit, sc.attributes,

            COALESCE(NULLIF(p.discounted_price, 0), p.price) AS price,         sc.quantity,

            COALESCE(NULLIF(p.discounted_price, 0),      p.price) * sc.quantity AS subtotal

 FROM       shopping_cart sc  INNER JOIN product p  ON sc.product_id = p.product_id

 WHERE      sc.cart_id = inCartId AND sc.buy_now; END$$

-- Create shopping_cart_get_saved_products stored procedure

CREATE PROCEDURE shopping_cart_get_saved_products(IN inCartId CHAR(32))

BEGIN  SELECT     sc.item_id, p.name, p.unit, sc.attributes,

            COALESCE(NULLIF(p.discounted_price, 0), p.price) AS price  FROM       shopping_cart sc

 INNER JOIN product p           ON sc.product_id = p.product_id

 WHERE      sc.cart_id = inCartId AND NOT sc.buy_now; END$$

-- Create shopping_cart_get_total_amount stored procedure   

CREATE PROCEDURE shopping_cart_get_total_amount(IN inCartId CHAR(32))

BEGIN  SELECT     SUM(COALESCE(NULLIF(p.discounted_price, 0), p.price) * sc.quantity) AS total_amount

 FROM       shopping_cart sc  INNER JOIN product p      ON sc.product_id = p.product_id

 WHERE      sc.cart_id = inCartId AND sc.buy_now; END$$

-- Create shopping_cart_save_product_for_later stored procedure  

CREATE PROCEDURE shopping_cart_save_product_for_later(IN inItemId INT)

BEGIN  UPDATE shopping_cart  SET    buy_now = false, quantity = 1  WHERE  item_id = inItemId; END$$

-- Create shopping_cart_move_product_to_cart stored procedure     

CREATE PROCEDURE shopping_cart_move_product_to_cart(IN inItemId INT)

BEGIN UPDATE shopping_cart  SET buy_now = true, added_on = NOW() WHERE item_id = inItemId; END$$

-- Drop the old catalog_delete_product stored procedure

DROP PROCEDURE catalog_delete_product$$

-- Create catalog_delete_product stored procedure  

CREATE PROCEDURE catalog_delete_product(IN inProductId INT)

BEGIN  DELETE FROM product_attribute WHERE product_id = inProductId;

 DELETE FROM product_category WHERE product_id = inProductId;

 DELETE FROM shopping_cart WHERE product_id = inProductId;

 DELETE FROM product WHERE product_id = inProductId; END$$

-- Create shopping_cart_count_old_carts stored procedure

CREATE PROCEDURE shopping_cart_count_old_carts(IN inDays INT)

BEGIN  SELECT COUNT(cart_id) AS old_shopping_carts_count  FROM   (SELECT   cart_id

         FROM     shopping_cart          GROUP BY cart_id

         HAVING   DATE_SUB(NOW(), INTERVAL inDays DAY) >= MAX(added_on)) AS old_carts; END$$

-- Create shopping_cart_delete_old_carts stored procedure 63

CREATE PROCEDURE shopping_cart_delete_old_carts(IN inDays INT)

BEGIN  DELETE FROM shopping_cart  WHERE  cart_id IN

         (SELECT cart_id           FROM   (SELECT   cart_id FROM     shopping_cart GROUP BY cart_id

 HAVING   DATE_SUB(NOW(), INTERVAL inDays DAY) >= MAX(added_on)) AS sc); END$$

-- Create shopping_cart_empty stored procedure   

CREATE PROCEDURE shopping_cart_empty(IN inCartId CHAR(32))

BEGIN  DELETE FROM shopping_cart WHERE cart_id = inCartId; END$$

-- Create shopping_cart_create_order stored procedure

CREATE PROCEDURE shopping_cart_create_order(IN inCartId CHAR(32),

 IN inCustomerId INT, IN inShippingId INT, IN inTaxId INT) BEGIN  DECLARE orderId INT;

 -- Insert a new record into orders and obtain the new order ID

 INSERT INTO orders (created_on, customer_id, shipping_id, tax_id) VALUES

        (NOW(), inCustomerId, inShippingId, inTaxId);

 -- Obtain the new Order ID

 SELECT LAST_INSERT_ID() INTO orderId;

 -- Insert order details in order_detail table

 INSERT INTO order_detail (order_id, product_id, attributes,     product_name, quantity, unit_cost)

 SELECT      orderId, p.product_id, sc.attributes, p.name, sc.quantity,

             COALESCE(NULLIF(p.discounted_price, 0), p.price) AS unit_cost FROM        shopping_cart sc

 INNER JOIN  product p   ON sc.product_id = p.product_id WHERE       sc.cart_id = inCartId AND sc.buy_now;

 -- Save the order's total amount

 UPDATE orders  SET    total_amount = (SELECT SUM(unit_cost * quantity)

                        FROM   order_detail   WHERE  order_id = orderId)  WHERE  order_id = orderId;

 -- Clear the shopping cart

 CALL shopping_cart_empty(inCartId);

 -- Return the Order ID

 SELECT orderId; END$$

-- Create orders_get_most_recent_orders stored procedure

CREATE PROCEDURE orders_get_most_recent_orders(IN inHowMany INT)

BEGIN  PREPARE statement FROM

   "SELECT     o.order_id, o.total_amount, o.created_on,                o.shipped_on, o.status, c.name

    FROM       orders o     INNER JOIN customer c                  ON o.customer_id = c.customer_id

    ORDER BY   o.created_on DESC     LIMIT      ?";  SET @p1 = inHowMany;

 EXECUTE statement USING @p1; END$$

-- Create orders_get_orders_between_dates stored procedure

CREATE PROCEDURE orders_get_orders_between_dates(

 IN inStartDate DATETIME, IN inEndDate DATETIME) BEGIN

 SELECT     o.order_id, o.total_amount, o.created_on,   o.shipped_on, o.status, c.name

 FROM       orders o  INNER JOIN customer c ON o.customer_id = c.customer_id

 WHERE      o.created_on >= inStartDate AND o.created_on <= inEndDate

 ORDER BY   o.created_on DESC; END$$

-- Create orders_get_orders_by_status stored procedure   

CREATE PROCEDURE orders_get_orders_by_status(IN inStatus INT)

BEGIN  SELECT     o.order_id, o.total_amount, o.created_on,

            o.shipped_on, o.status, c.name  FROM       orders o

 INNER JOIN customer c               ON o.customer_id = c.customer_id

 WHERE      o.status = inStatus  ORDER BY   o.created_on DESC; END$$

-- Create orders_get_order_info stored procedure   

CREATE PROCEDURE orders_get_order_info(IN inOrderId INT)

BEGIN  SELECT     o.order_id, o.total_amount, o.created_on, o.shipped_on,

o.status, o.comments, o.customer_id, o.auth_code, o.reference, o.shipping_id, s.shipping_type, s.shipping_cost,

            o.tax_id, t.tax_type, t.tax_percentage  FROM       orders o

 INNER JOIN tax t            ON t.tax_id = o.tax_id  INNER JOIN shipping s    ON s.shipping_id = o.shipping_id

 WHERE      o.order_id = inOrderId; END$$

-- Create orders_get_order_details stored procedure

CREATE PROCEDURE orders_get_order_details(IN inOrderId INT)

BEGIN  SELECT order_id, product_id, attributes, product_name,

        quantity, unit_cost, (quantity * unit_cost) AS subtotal  FROM   order_detail

 WHERE  order_id = inOrderId; END$$

-- Create orders_update_order stored procedure    

CREATE PROCEDURE orders_update_order(IN inOrderId INT, IN inStatus INT,

 IN inComments VARCHAR(255), IN inAuthCode VARCHAR(50),

 IN inReference VARCHAR(50)) BEGIN  DECLARE currentDateShipped DATETIME;

 SELECT shipped_on  FROM   orders  WHERE  order_id = inOrderId  INTO   currentDateShipped;

 UPDATE orders  SET    status = inStatus, comments = inComments,

        auth_code = inAuthCode, reference = inReference  WHERE  order_id = inOrderId;

 IF inStatus < 7 AND currentDateShipped IS NOT NULL THEN

   UPDATE orders SET shipped_on = NULL WHERE order_id = inOrderId;

 ELSEIF inStatus > 6 AND currentDateShipped IS NULL THEN

   UPDATE orders SET shipped_on = NOW() WHERE order_id = inOrderId;  END IF; END$$

-- Create catalog_get_recommendations stored procedure   

CREATE PROCEDURE catalog_get_recommendations(

 IN inProductId INT, IN inShortProductDescriptionLength INT)

BEGIN  PREPARE statement FROM    "SELECT   od2.product_id, od2.product_name,

   IF(LENGTH(p.description) <= ?, p.description, CONCAT(LEFT(p.description, ?), '...')) AS description

    FROM     order_detail od1   JOIN     order_detail od2 ON od1.order_id = od2.order_id

    JOIN     product p ON od2.product_id = p.product_id     WHERE    od1.product_id = ? AND

             od2.product_id != ?     GROUP BY od2.product_id   ORDER BY COUNT(od2.product_id) DESC

    LIMIT 5";  SET @p1 = inShortProductDescriptionLength;  SET @p2 = inProductId;

 EXECUTE statement USING @p1, @p1, @p2, @p2; END$$

-- Create shopping_cart_get_recommendations stored procedure    

CREATE PROCEDURE shopping_cart_get_recommendations(

 IN inCartId CHAR(32), IN inShortProductDescriptionLength INT)

BEGIN  PREPARE statement FROM

   "-- Returns the products that exist in a list of orders

    SELECT   od1.product_id, od1.product_name,      IF(LENGTH(p.description) <= ?, p.description,

                CONCAT(LEFT(p.description, ?), '...')) AS description     FROM     order_detail od1

    JOIN     order_detail od2   ON od1.order_id = od2.order_id     JOIN     product p

 ON od1.product_id = p.product_id     JOIN     shopping_cart ON od2.product_id = shopping_cart.product_id

    WHERE    shopping_cart.cart_id = ?

       -- Must not include products that already existin the visitor's cart

             AND od1.product_id NOT IN

             (-- Returns the products in the specified shopping cart

              SELECT product_id     FROM   shopping_cart      WHERE  cart_id = ?)

    -- Group the product_id so we can calculate the rank

    GROUP BY od1.product_id

    -- Order descending by rank

    ORDER BY COUNT(od1.product_id) DESC     LIMIT    5";

 SET @p1 = inShortProductDescriptionLength;  SET @p2 = inCartId;

 EXECUTE statement USING @p1, @p1, @p2, @p2; END$$

-- Create customer_get_login_info stored procedure    

CREATE PROCEDURE customer_get_login_info(IN inEmail VARCHAR(100))

BEGIN  SELECT customer_id, password FROM customer WHERE email = inEmail; END$$

-- Create customer_add stored procedure     

CREATE PROCEDURE customer_add(IN inName VARCHAR(50),

 IN inEmail VARCHAR(100), IN inPassword VARCHAR(50))

BEGIN  INSERT INTO customer (name, email, password)  VALUES (inName, inEmail, inPassword);

 SELECT LAST_INSERT_ID(); END$$

-- Create customer_get_customer stored procedure  

CREATE PROCEDURE customer_get_customer(IN inCustomerId INT)

BEGIN  SELECT customer_id, name, email, password, credit_card,

 address_1, address_2, city, region, postal_code, country,

shipping_region_id, day_phone, eve_phone, mob_phone

 FROM   customer  WHERE  customer_id = inCustomerId; END$$

-- Create customer_update_account stored procedure  

CREATE PROCEDURE customer_update_account(IN inCustomerId INT,

 IN inName VARCHAR(50), IN inEmail VARCHAR(100),

 IN inPassword VARCHAR(50), IN inDayPhone VARCHAR(100),

 IN inEvePhone VARCHAR(100), IN inMobPhone VARCHAR(100))

BEGIN  UPDATE customer  SET    name = inName, email = inEmail,

        password = inPassword, day_phone = inDayPhone,  eve_phone = inEvePhone, mob_phone = inMobPhone

 WHERE  customer_id = inCustomerId; END$$

-- Create customer_update_credit_card stored procedure  

CREATE PROCEDURE customer_update_credit_card(

 IN inCustomerId INT, IN inCreditCard TEXT) BEGIN  UPDATE customer  SET    credit_card = inCreditCard

 WHERE  customer_id = inCustomerId; END$$

-- Create customer_get_shipping_regions stored procedure

CREATE PROCEDURE customer_get_shipping_regions()

BEGIN  SELECT shipping_region_id, shipping_region FROM shipping_region; END$$

-- Create customer_update_address stored procedure   

CREATE PROCEDURE customer_update_address(IN inCustomerId INT,

 IN inAddress1 VARCHAR(100), IN inAddress2 VARCHAR(100),

 IN inCity VARCHAR(100), IN inRegion VARCHAR(100),

 IN inPostalCode VARCHAR(100), IN inCountry VARCHAR(100),

 IN inShippingRegionId INT) BEGIN  UPDATE customer

 SET  address_1 = inAddress1, address_2 = inAddress2, city = inCity,

region = inRegion, postal_code = inPostalCode,

        country = inCountry, shipping_region_id = inShippingRegionId

 WHERE  customer_id = inCustomerId; END$$

-- Create orders_get_by_customer_id stored procedure

CREATE PROCEDURE orders_get_by_customer_id(IN inCustomerId INT)

BEGIN  SELECT     o.order_id, o.total_amount, o.created_on,    o.shipped_on, o.status, c.name

 FROM       orders o  INNER JOIN customer c  ON o.customer_id = c.customer_id

WHERE      o.customer_id = inCustomerId  ORDER BY   o.created_on DESC; END$$

-- Create orders_get_order_short_details stored procedure  

CREATE PROCEDURE orders_get_order_short_details(IN inOrderId INT)

BEGIN  SELECT      o.order_id, o.total_amount, o.created_on,            o.shipped_on, o.status, c.name

 FROM        orders o  INNER JOIN  customer c   ON o.customer_id = c.customer_id

 WHERE       o.order_id = inOrderId; END$$

-- Create customer_get_customers_list stored procedure

CREATE PROCEDURE customer_get_customers_list()

BEGIN  SELECT customer_id, name FROM customer ORDER BY name ASC; END$$

-- Create orders_get_shipping_info stored procedure

CREATE PROCEDURE orders_get_shipping_info(IN inShippingRegionId INT)

BEGIN  SELECT shipping_id, shipping_type, shipping_cost, shipping_region_id

 FROM   shipping  WHERE  shipping_region_id = inShippingRegionId; END$$

-- Create orders_create_audit stored procedure  

CREATE PROCEDURE orders_create_audit(IN inOrderId INT,

 IN inMessage TEXT, IN inCode INT) BEGIN  INSERT INTO audit (order_id, created_on, message, code)

        VALUES (inOrderId, NOW(), inMessage, inCode); END$$

-- Create orders_update_status stored procedure   

CREATE PROCEDURE orders_update_status(IN inOrderId INT, IN inStatus INT)

BEGIN  UPDATE orders SET status = inStatus WHERE order_id = inOrderId; END$$

-- Create orders_set_auth_code stored procedure  

CREATE PROCEDURE orders_set_auth_code(IN inOrderId INT,

 IN inAuthCode VARCHAR(50), IN inReference VARCHAR(50))

BEGIN  UPDATE orders  SET    auth_code = inAuthCode, reference = inReference

 WHERE  order_id = inOrderId; END$$

-- Create orders_set_date_shipped stored procedure  

CREATE PROCEDURE orders_set_date_shipped(IN inOrderId INT)

BEGIN  UPDATE orders SET shipped_on = NOW() WHERE order_id = inOrderId; END$$

-- Create orders_get_audit_trail stored procedure   

CREATE PROCEDURE orders_get_audit_trail(IN inOrderId INT)

BEGIN  SELECT audit_id, order_id, created_on, message, code

 FROM   audit  WHERE  order_id = inOrderId; END$$

-- Create catalog_get_product_reviews stored procedure

CREATE PROCEDURE catalog_get_product_reviews(IN inProductId INT)

BEGIN  SELECT     c.name, r.review, r.rating, r.created_on

 FROM       review r  INNER JOIN customer c            ON c.customer_id = r.customer_id

 WHERE      r.product_id = inProductId  ORDER BY   r.created_on DESC; END$$

-- Create catalog_create_product_review stored procedure

CREATE PROCEDURE catalog_create_product_review(IN inCustomerId INT,

 IN inProductId INT, IN inReview TEXT, IN inRating SMALLINT)

BEGIN  INSERT INTO review (customer_id, product_id, review, rating, created_on)

        VALUES (inCustomerId, inProductId, inReview, inRating, NOW()); END$$

-- Change back DELIMITER to ; DELIMITER ;


Приложение Г
Примеры пользовательского интерфейса
   

Рисунок Г.1 – Главная страница

Рисунок Г.2 – Страница категорий

Рисунок Г.3 – Подробное описание товара

Рисунок Г.4 – Страница регистрации

Рисунок Г.5 – Страница изменения профиля

Рисунок Г.6 – Страница просмотра корзины

Рисунок Г.7 – Страница поиска

Рисунок Г.8 – Страница администрирования

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


Приложение Д
Опись листов графической части дипломного проекта    

Лист 1 – Цель и функции проекта.

Лист 2 – Задачи дипломного проекта.

Лист 3 – Технологии и средства разработки.

Лист 4 – Концептуальная модель данных.

Лист 5 – Логическая модель данных.

Лист 6 – Диаграмма вариантов использования для гостя, клиента и администратора.

Лист 7 – Диаграмма состояний для гостя, клиента и администратора

Лист 8 – Физическая модель данных.

Лист 9 – Диаграмма компонентов Интернет-магазина строительных материалов.

Лист 10 – Главная страница.

Лист 11 – Страница регистрации.

Лист 12 – Страница просмотра информации о товаре.

Лист 13 – Страница просмотра корзины.

Лист 14 – Страница администратора.

Лист 15 – Выводы по проекту.


КАТАЛОГ

ТОВАРОВ

ВХОД/КОРЗИНА

ЛОГОТИП

 ПОЛЕ

ПОИСКА

СОДЕРЖИМОЕ СТРАНИЦ

ОТДЕЛЫ

АТЕГО-       РИИ


 

А также другие работы, которые могут Вас заинтересовать

36607. Облік податків і податкова звітність 591.5 KB
  Загальність оподаткування кожна особа зобов’язана сплачувати встановлені цим Кодексом законами з питань митної справи податки та збори платником яких вона є згідно з положеннями цього Кодексу; 2. презумпція правомірності рішень платника податку в разі якщо норма закону чи іншого нормативноправового акта виданого на підставі закону або якщо норми різних законів чи різних нормативноправових актів припускають неоднозначне множинне трактування прав та обов’язків платників податків або контролюючих органів внаслідок чого є можливість...
36609. Логіка. Курс лекцій 1.34 MB
  Знання які здобуває людина на цій стадії пізнання виникають на основі даних органів чуттів опосередковуються ними і знаходять своє відображення в логічних формах поняттях судженнях та умовиводах. Основними логічними формами мислення є поняття судження умови. є: вчення про понятт; вчення про судження; логіка висловлювань з логікою предикатів; вчення про закони Л. Судження Логічна природа суджень.
36610. Проект создания системы контроля качества производства пакетов полиэтиленовых на ООО «Пластик» 728.5 KB
  Отрасль упаковки – одна из наиболее молодых в нашей стране, и это понятно, т.к. еще 10-15 лет назад никого не волновало, во что упакован товар, главное его купить, а завернуть можно было и в газету. Несколько десятилетий отрасль упаковки у нас совершенно не развивалась...
36611. Операційне числення 1.43 MB
  5 Поняття функції комплексної змінної. Множина комплексних чисел w що відповідають усім називається множиною значень функції fz. Оскільки кожне комплексне число характеризується парою дійсних чисел то завдання комплексної функції w =uiv комплексної змінної z = х iу еквівалентно завданню двох дійсних функцій двох дійсних змінних що може бути записане у вигляді wz =их у ivx у. Функції uху і vxy визначені в області G площини дійсних змінних x y що відповідає області G комплексної площини z.
36612. Поставка товаров, работ и услуг для органов внутренних дел 294.5 KB
  Сфера применения института поставки разнообразна и велика. Она включает отношения, связанные с поставкой товаров, как для коммерческих целей, так и для государственных нужд, в том числе нужд Органов внутренних дел. Тема моей дипломной работы «Поставка товаров, работ и услуг для нужд ОВД»
36613. ІНЖЕНЕРНА ГІДРАВЛІКА. Рух рідини в закритих руслах 752.5 KB
  Рух рідини в закритих руслах. Також в конспекті розглянуті питання виникнення гідравлічних опорів поняття гідравлічного удару витікання рідини через отвори та насадки вільні гідравлічні струмені. ОСНОВНІ ПОНЯТТЯ І ВИЗНАЧЕННЯ КУРСУ ІНЖЕНЕРНА ГІДРАВЛІКА Гідравліка це наука яка вивчає закони рівноваги і руху рідини а також взаємодію між рідиною і твердими тілами в стані спокою і щодо їх руху.
36614. ПРОЕКТУВАННЯ ПЛАСТИЧНОЇ ФОРМИ ОДЯГУ 762 KB
  ПРИЙОМИ ТВОРЧОГО ПОШУКУ ПЛАСТИЧНОЇ ФОРМИ ОДЯГУ. Створення одягу це мистецтво. Тому пластична композиція форми одягу вирішується не лініями і площинами а обємами і просторами певної конфігурації і величини.
36615. РЕГІОНАЛЬНЕ УПРАВЛІННЯ 584.5 KB
  Регіональне управління [конспект лекцій для студентів спеціальності 6. Конспект лекцій з дисципліни Регіональне управління призначений для студентів спеціальності 6. Конспект лекцій з дисципліни Регіональне управління складено на підставі відповідних нормативних вимог Міністерства освіти і науки молоді та спорту України.