/
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
Государственное образовательное учреждение
Высшего профессионального образования
РОССИЙСКИЙ
ГОСУДАРСТВЕННЫЙ ГУМАНИТАРНЫЙ УНИВЕРСИТЕТ
ИНСТИТУТ ИНФОРМАЦИОННЫХ НАУК И ТЕХНОЛОГИЙ БЕЗОПАСНОСТИ
ФАКУЛЬТЕТ ИНФОРМАТИКИ
Кафедра Программной инженерии
Дипломная работа студента 5 курса очной формы обучения
РАЗРАБОТКА WEB-САЙТА И ИНТЕРНЕТ-МАГАЗИНА ДЛЯ КОМПЬЮТЕРНОГО САЛОНА 'СТОИК'
Колесников Алексей Олегович
Москва 2009
Оглавление
Введение
Актуальность темы
Тема данной дипломной работы носит актуальный характер в современных условиях, об этом свидетельствует частое изучение поднятых вопросов. Вопросам дипломной работы посвящено множество работ, однако, требуется учет современных условий при исследовании проблематики обозначенной темы.
Актуальность настоящей работы обусловлена, с одной стороны, большим интересом к теме 'Интернет-магазин', с другой стороны, ее недостаточной разработанностью с использованием различных технологических подходов. Рассмотрение вопросов, связанных с данной тематикой, носит как теоретическую, так и практическую значимость.
Теоретическое значение изучения проблемы 'Интернет-магазин' заключается в том, что избранная для рассмотрения проблематика находится на стыке сразу нескольких научных дисциплин.
На сегодняшний день успешное развитие современного бизнеса практически невозможно без информационных технологий. С каждым годом они все больше вливаются в повседневную жизнь и касаются всех направлений жизнедеятельности человека.
В России постоянно растет количество пользователей Internet, поэтому, необходимо понимать, что в современном мире, предприятию для успешной торговли в настоящее время желательно иметь представительство в Сети. Оно не только позволит поднять на уровень выше количество сбываемых товаров, но так же повысит престиж компании, станет ее 'лицом' в 'Мировой паутине'. И насколько это представительство в виде Интернет-магазина будет удачно исполненным и удобным для потенциального покупателя, от этого будет зависеть, какое количество потенциальных покупателей превратиться в покупателей реальных.
интернет магазин компьютерный салон
На практике, при одинаковом ассортименте, покупатель выберет магазин с более приятным дизайном или удобной навигацией и системой заказа, зачастую закрыв глаза на небольшую разницу в цене, посчитав, что лучше исполненный, а значит и более дорогой сайт принадлежит более серьезной и крупной фирме, а значит получить некачественный товар или испытать проблемы с доставкой шансов меньше.
Для осуществления покупки в Интернет-магазине потребуется компьютер (персональный, мобильный или карманный персональный), а порой и мобильный телефон с возможностью выхода во 'Всемирную паутину'. Покупатель может ознакомиться с перечнем товаров, а так же с их описанием. Иногда предоставляется возможность сравнения двух или более товаров между собой. Покупки поочередно заносятся в корзину, после чего производится заказ всей добавленной в корзину продукции.
Интернет-магазины существенно уменьшают затраты предприятия. Содержание обыкновенного магазина, оплата труда нескольким продавцам и консультантам заменяются лишь на содержание Интернет-сайта и короткого штата. Можно разместить сколько угодно товаров и не беспокоиться за физическую площадь помещения. Покупатель может заказывать товар в любое время суток и в любой день недели, выбор и ознакомление с товаром производится, не выходя из дома. Все это безусловные преимущества Интернет-магазинов.
Следовательно, электронная торговля может существенно увеличить эффективность работы предприятия в целом.
Интернет-магазин обладает следующими преимуществами по сравнению с обычным магазином:
а) Интернет-магазин работает круглосуточно и каждый день, без перерыва на обед, без выходных и праздничных дней;
б) доступ к товарам магазина имеет возможность получить любой покупатель, находящийся в любой точке планеты;
в) в Интернет-магазин не требуется нанимать продавцов-консультантов, покупателю доступна вся подробная информация о товаре;
г) Интернет магазин не имеет ограничений на площадь. Можно разместить сколь угодно много товаров или описать любое количество услуг;
д) срок и стоимость создания Интернет-магазина намного ниже, чем обычного магазина;
е) для создания Интернет-магазина не требуется получения различных разрешений и лицензий. Его не будет проверять пожарный инспектор, санэпидемстанция и другие службы;
Интернет-магазин сделает имя компании более узнаваемым.
Часто Интернет-магазин создается на основе уже имеющегося реального магазина, который уже продает определенную продукцию. Создавая Интернет-магазин у предпринимателя появляется как бы еще одна торговая точка. Это позволяет при незначительных вложениях построить систему, которая преследует следующие цели: расширение каналов сбыта продукции, захват новых приоритетных регионов, привлечение большего количества потенциальных покупателей с помощью планирования активной рекламной кампании в Сети, информационное обслуживание клиентов, автоматизированная обработка заказов, проведение платежей, а также сбор и анализ статистической маркетинговой информации. Введение в эксплуатацию такого Интернет-магазина позволит покупателям непосредственно общаться с электронным магазином и его виртуальными продавцами, получать консультации и оплачивать товар. Организации коммерческих операций посредством сети Интернет позволяет сократить затраты на оформление и обработку заказов в несколько раз. Для тех, кто не имеет реального магазина, Интернет-магазин - отличный способ начать свое дело.
В калужском регионе система продаж через Интернет пока не развита и является достаточно привлекательной сферой деятельности. Помимо этого, в небольших муниципальных образованиях, зачастую бывает проблематично приобрести некоторые определенные товары, а цены, как правило, выше, чем в областном центре, поэтому, иногда покупка через Интернет-магазин, базирующийся в Калуге, будет более выгодна, особенно для ближайших городских и сельских поселений.
Из всего выше сказанного следует, что вложение денежных средств в разработку такого плана систем является довольно-таки привлекательным. Несомненно, в будущем почти все компании в России перейдут на онлайновый бизнес, но, скорей всего, традиционная форма организации коммерческих операций все же сохранится.
Дипломная работа 'Разработка сайта и Интернет-магазина для компьютерного салона Стоик' ставила целью перед собой создать еще одну дополнительную, виртуальную торговую точку помимо существующего магазина, находящегося по юридическому адресу, подняв тем самым рейтинг магазина и увеличив его товарооборот, и, соответственно, прибыль, дать информацию об услугах, оказываемых компанией, сделать магазин более узнаваемым.
Цель
Разработать Web-сайт и Интернет-магазин для компьютерного салона 'Стоик'.
Задачи
В рамках достижения цели были сформулированы следующие задачи:
проанализировать опыт применения Интернет-технологий для ведения бизнеса;
изучить типы решений и подходы при создании Интернет-магазинов;
осуществить проектирование базы данных и Интернет-магазина для компьютерного салона 'Стоик';
реализовать базу данных и Интернет-магазин для компьютерного салона 'Стоик';
внедрить и проанализировать эффективность Интернет-магазина;
Объект исследования
Объектом исследования является информатизация бизнес-процессов.
Предмет исследования
Предметом исследования являются возможности Интернет-магазина для ведения бизнеса.
Дипломная работа состоит из трех глав. Для осуществления поставленных целей в первом разделе был проведен анализ предметной области, рассмотрение Интернета, как средства ведения электронной коммерции, построения информационных систем для торговли через Интернет, анализ опыта применения, рассмотрение и сравнение нескольких Интернет-магазинов по продаже техники. Во втором разделе было произведено проектирование электронного магазина, интерфейсов и базы данных, в третьем разделе описывается программная реализация Интернет-магазина, интерфейсов и базы данных. В заключении подводятся итоги проделанной работы.
Во время ведения дипломной работы были использованы следующие основные материалы.
Для изучения принципов электронной торговли была использована книга 'Электронная коммерция и маркетинг в Интернете', В. Алексунин, В. Родигина, Изд.: Дашков и Ко, 2007г. Для изучения основ языка программирования Perl был использован 'Самоучитель Perl', Матросов А.В., Чаунин М.П., Изд.: BHV, 2003г. Для изучения основ языка программирования JavaScript был испольован 'Самоучитель JavaScript - подробное руководство', Д. Флэнаган, Изд.: Символ, 2008г. Комплексный набор технологий для Web-разработки был изучен по книге 'HTML, JavaScript, PHP и MySQL. Джентельменский набор Web-мастера', Прохоренок Н., Изд.: БХВ-Петербург, 2008 г. Для оформлении Web-страниц была использована технология описания внешнего вида документа CSS, которая была изучена по книге 'CSS - каскадные таблицы стилей. Подробное руководство. 3-е издание.', Э.А. Мейер, Изд.: Символ, Символ-Плюс, 2008г.
Глава 1. Анализ предметной области
1.1 Интернет, как современная бизнес-среда
Торговля в Интернете - это коммерческая деятельность в Интернете, когда процесс покупки/продажи товаров или услуг (весь цикл коммерческой/финансовой транзакции или ее часть) осуществляется электронным образом с применением Интернет-технологий.
На сегодняшний день успешное развитие современного бизнеса практически невозможно без информационных технологий. С каждым годом они все больше вливаются в повседневную жизнь и касаются всех направлений жизнедеятельности человека.
В России постоянно растет количество пользователей Internet, поэтому, в современном мире, предприятию для успешной торговли желательно иметь представительство в Сети.
Для осуществления покупки в Интернет потребуется компьютер (персональный, мобильный или карманный персональный), а порой и мобильный телефон с возможностью выхода во 'Всемирную паутину'.
Развитие информационных технологий привело к изменению способов ведения бизнеса. В наши дни считается современным вести дела с помощью Интернет. Тысячи компаний, больших и маленьких, все чаще используют его в качестве средства ведения бизнеса, организуя свой сайт и развивая деятельность, которая была бы невозможной при использовании традиционных способов продвижения товаров. В качестве средства маркетинга Интернет имеет массу уникальных характеристик:
интерактивный доступ по требованию для клиентов, находящихся в любой точке земного шара;
возможность хранения огромных объемов информации по различным виртуальным адресам и доступность эффективных средств поиска, систематизации и распространения такой информации, причем все это не требует больших затрат;
возможность дать человеку более полные представления о товаре или услуге, чем при просмотре печатного каталога;
возможность использования сети для осуществления деловых операций, а иногда и для доставки некоторых товаров (например, программного обеспечения);
относительно невысокие расходы на организацию и регистрацию компании-продавца.
Интернет неизбежно будет наращивать вес в качестве средства ведения бизнеса, а возможности рынка почти неограниченны, особенно в свете растущей глобализации мировой экономики. Крупные компании давно пользуются традиционными средствами сбыта и продвижения товаров на мировом рынке, так что большинство из них может использовать Web-сайты в качестве дополнительного средства, особенно в первое время. Мелкие и средние предприятия могут (или вынуждены) проводить электронные маркетинговые мероприятия и заниматься электронной коммерцией в Интернете.
Интернет-маркетинг - электронный маркетинг
Основа электронного маркетинга - электронные публикации. Компании могут размещать маркетинговые материалы, от обычной рекламы до виртуальных брошюр, на серверах, входящих в Интернет. В современных условиях глобального рынка оперативная и надежная информация становится насущной необходимостью для получения большинством компаний каких-либо конкурентных преимуществ. Например, компания может создать виртуальный рынок, где и будет продавать свои товары. Никто не может посягнуть на этот рынок, и он может быть доступен миллионам пользователей Интернета круглые сутки. Эти товары могут быть более дорогостоящими, чем их физический эквивалент, могут обладать преимуществами, которые дает использование средств мультимедиа, и могут быть адаптированы к особенностям конкретного зарегистрированного пользователя. Более того, с помощью Интернета могут делаться и выполняться заказы (например, на такие товары, как программное обеспечение). Наиболее часто упоминающиеся преимущества электронного маркетинга включают в себя его мировой масштаб, высокую эффективность по сравнению с другими средствами маркетинга и возможность предоставления новых услуг на основе использования Интернет-технологий.
Электронная коммерция
Электронной коммерцией называется покупка и продажа товаров, услуг или информации посредством компьютерных сетей, преимущественно Интернета. Являясь наиболее быстро развивающейся составляющей Интернет-технологий и других информационных технологий, электронная коммерция обеспечивает функциональность и новые способы ведения бизнеса, которыми невозможно пренебречь. Электронная коммерция, безусловно, имеет большое будущее, так как электронные рынки более эффективны при создании новых товаров и услуг на основе поступающей информации, незаменимы в поиске клиентов и партнеров по всему земному шару. Электронная коммерция посредством Интернета или следующая модификация Интернет-протокола изменит привычный для нас сегодня мир бизнеса, деловые операции и товары (услуги), точно так же, как телефон, телевидение, факс и электронная почта изменили стиль взаимодействия между фирмами и потребителями. Электронная коммерция обладает многими преимуществами и поэтому становится все более популярной. Эти преимущества включают в себя лучшие возможности для продвижения товара, снижение издержек, своевременность информации, сокращение времени перевода денежных средств, единообразие информации, повышение уровня обслуживания клиентов, улучшение взаимоотношений с клиентом, ориентирование товаров на потребителя, конкурентные преимущества и удобство ведения бизнеса.
Своей необыкновенной популярностью в последние годы сеть Интернет в значительной степени обязана реальной перспективе ведения бизнеса с помощью сети. Все большее число компаний организуют собственные корпоративные локальные сети посредством интрасетей и применяют экстрасети и Интернет для того, чтобы работать в сотрудничестве со своими клиентами, поставщиками и партнерами. Интернет может ликвидировать все физические препятствия коммерции, потому что даже самой маленькой компании почти мгновенно предоставляется доступ к новым рынкам в любой точке земного шара. Наряду с этим потребители могут заключать сделки и совершать покупки у таких компаний, которые раньше были им недоступны. Однако широкому распространению электронной коммерции в Интернете препятствуют проблемы безопасности. Наряду с положительными сторонами использования Интернета, заключающимися в облегчении ведения бизнеса, существует значительный риск, связанный с открытостью, которая является неотъемлемым свойством сети.
Современные подходы
Cуществуют два подхода к электронному маркетингу: как к дополнительному средству и как к виртуальному бизнесу. Подход к электронному маркетингу как к дополнительному средству ведения бизнеса подразумевает, что компании не ограничиваются маркетинговыми мероприятиями только в Интернете. Фактически для выполнения деловых задач и достижения целей маркетинга они должны уделять внимание другим, традиционным средствам рекламы и маркетинга, а Web-маркетинг при этом рассматривается как еще одно средство в маркетинговом арсенале компании. Подход к электронному маркетингу как к дополнительному средству является обычным подходом в наши дни. Нет сомнения в том, что дополнительные мероприятия по продвижению товаров в Интернете могут значительно повысить уровень продаж в некоторых сферах бизнеса. Например, только 1% продаж Insight Direct (составителя каталога компьютеров, продающихся со скидкой), предлагающей свой товар преимущественно организациям, приходится на продажи посредством онлайнового каталога, но более 50% ее новых клиентов появилось благодаря функционированию сайта.
Виртуальный бизнес - это то, на что рассчитывает большинство сторонников Интернет-маркетинга. Несмотря на существование подводных камней (например, недостаточной безопасности операций), похоже, что многие компании, особенно средние и мелкие, склонны извлекать выгоду непосредственно из маркетинга в Интернете.
Существует большое количество моделей получения прибыли с помощью Интернета. Чаще всего компании используют более одной модели. Существует несколько наиболее популярных моделей получения прибыли. Тем временем в Интернете появляются все новые и новые модели. Однако никто не может предсказать, какая же из них в конце концов будет иметь успех.
Тенденции будущего
Есть основания считать, что Интернет станет мощным средством. Есть основания считать, что Интернет станет мощным средством электронной коммерции. Чтобы это произошло, необходимо было наличие таких систем электронной коммерции и проведения расчетов, которые были бы безопасными, надежными и лишенными риска. Для достижения этих целей нужно решить два важных вопроса - вопрос о технологиях для создания необходимой инфраструктуры и вопрос о предоставлении пользователям безопасности.
Первым шагом является создание инфраструктуры, необходимой для безопасного совершения операций и управления электронной коммерцией и, что особенно важно, совершения электронных платежей. Движение в этом направлении будет сопровождаться ростом числа Интернет-приложений и аппаратного обеспечения для безопасных платежей, а также дальнейшим усовершенствованием технологий цифровой сертификации, цифровой подписи, шифрования и т.п.
Кроме того, существует потребность в совершенно безопасном стандарте, который можно использовать во всех отраслях экономики. Это сделало бы возможным взаимодействие между различными видами аппаратного обеспечения и платформ. Широкомасштабное принятие безопасных протоколов поможет достижению более высокого уровня безопасности и удобства онлайновых деловых операций.
1.2 Интернет-магазин, как одно из перспективных средств ведения бизнеса
Интернет-магазин - интерактивный Web-сайт, рекламирующий товар или услугу, принимающий заказы на покупку, предлагающий пользователю выбор варианта расчета и выписывающий счет на оплату.
В классическом понимании, то есть, в том смысле, в каком он понимается в наиболее развитых странах, 'Интернет-магазин' (иногда его называют 'Электронный магазин', 'Сетевой магазин', 'Internet shop', 'E-shop'), - интерактивный сайт, в котором:
рекламируются товары и услуги;
принимаются заказы на товары и услуги;
посетителю предлагаются различные варианта оплаты заказанных товаров и услуг;
возможна мгновенная оплата через Интернет заказанных товаров и услуг;
посетитель имеет возможность зарегистрироваться с помощью логина и пароля и в дальнейшем использовать уже введенные им данные при входе в разделы сайта;
посетитель имеет возможность выписать счет на оплату товаров и услуг, служащий одновременно подтверждением принятия заказа;
осуществляется оперативная доставка заказанных товаров и услуг;
предоставляется гарантия и страхование заказанных и оплаченных товаров и услуг;
обеспечивается соблюдение конфиденциальности совершаемых сделок;
сделки могут совершать как физические, так и юридические лица.
Интернет-магазин, в его трактовании с учетом российской действительности, - частный случай бизнес-сайта.
В российском Интернете понятие 'Интернет-магазин' сильно отличается от классического трактования. Объясняется это рядом причин: протяженностью расстояний, климатом, экономикой, традициями, степенью развития банковской системы и т.д.
Чтобы российский бизнес-сайт можно было с уверенностью назвать Интернет-магазином, на нем обязательно должны присутствовать:
рекламируемые товары и услуги;
прайс-лист;
контактная информация, необходимая для заказа товаров и услуг (телефон, факс, e-mail, почтовый адрес и др.);
предложение посетителю различных вариантов оплаты заказанных товаров и услуг;
предоставление посетителю возможности получить счет на оплату товаров и услуг;
информация о возможности совершения сделок как физическими, так и юридическими лицами.
Практически все российские бизнес-сайты содержат в себе подобные составляющие. Практически любой российский бизнес-сайт, по своей сути, - Интернет-магазин и, наоборот.
Под бизнес-сайтом подразумевается сайт, предназначенный для решения конкретных задач бизнеса, в частности, для извлечения прибыли его владельцем, за счет привлечения потенциальных клиентов из конкретной целевой аудитории.
работа Интернет-магазина во многом похожа на работу обычного магазина;
товар в Интернет-магазин поступает со склада и продаётся. Ассортимент постоянно обновляется и расширяется;
если представленный для продажи товар временно отсутствует на складе, и требуется дополнительное время для исполнения заказа, то покупателю может быть предложена система предварительных заказов;
о дате поступления товара на склад и сроке возможной доставки выбранного товара покупатель информируется дополнительно. Возможно, ему предложат замену товара из нового ассортимента, который ещё не успели разместить на виртуальных витринах Интернет-магазина.
Наряду со схожестью с работой обычного магазина работа любого Интернет-магазина имеет и ряд принципиальных особенностей:
1. Существует разница во времени между заказом товара, оплатой товара и его получением.
2. В РФ система электронных платежей развита слабо. Цифровая подпись только начинает внедряться. После получения счёта от продавца, покупатель оплачивает выписанный товар через банк. И только в ряде случаев, при стоимости выписанного товара менее 15-20 $, покупатель может расплатиться с Интернет-магазином по электронной системе платежей. Системы электронных платежей берут комиссионные. При этом большими суммами, при отсутствии законодательства, регламентирующего данную область взаимоотношений между продавцом и покупателем, покупатель вряд ли будет рисковать.
3. В подавляющем большинстве случаев товар, представленный в Интернет-магазине, нельзя посмотреть, в натуральную величину.
4. Цветопередача товаров, представленных на витрине Интернет-магазина, несколько искажает реальные цвета, поскольку зависит как от качества исходных фотографий, так и от настроек монитора.
5. В большинстве случаев у покупателя не хватает объемной информации о товарах, представленных в Интернет-магазине.
6. Технически затруднительно и экономически нецелесообразно производить частое обновление товаров, представленных в Интернет-магазине, по сравнению с заменой товаров в обычных магазинах.
7. Психологически российские покупатели пока настороженно относятся к возможности приобретения крупных партий товаров через Интернет-магазин.
Преимущества, которые даёт Интернет-магазин:
Интернет-магазин работает 24 часа в сутки, 365 дней в году, без перерыва на обед, без выходных и праздничных дней;
доступ к виртуальным витринам магазина может получить любой покупатель, находящийся в любой точке планеты на любом континенте;
профессионально грамотно созданный Интернет-магазин может работать полностью автономно. Практически без обслуживания;
Интернет-магазин не имеет ограничений на виртуальную площадь. Можно разместить сколь угодно много товаров или описать любое количество услуг;
владелец Интернет-магазина может сдавать в аренду свои виртуальные торговые площади так же, как и владелец обычного магазина;
Интернет-магазин позволяет общаться с потенциальными клиентами, находящимися сколь угодно далеко, в режиме реального времени;
срок и стоимость создания Интернет-магазина несоизмеримо ниже, чем обычного магазина;
для создания Интернет-магазина не требуется получения многочисленных разрешений и лицензий. Его не проверяет пожарный инспектор, санэпидемстанция и другие хорошо знакомые вам службы;
развитие мобильных устройств для доступа в Интернет (мобильный телефон, КПК и т.д.) позволяет получить доступ к Интернет-магазину из любой точки. Вне зависимости от месторасположения потенциального клиента;
Сравнение затрат на создание Интернет-магазина с затратами на обычный магазин
Вести свой бизнес с помощью Интернета хотят все большее число россиян. Но мало кто представляет реальные затраты, которые нужны для того, чтобы с помощью сайта решать конкретные задачи бизнеса. Т.е. мало кто реально знает, сколько надо вложить в сайт, чтобы с его помощью заработать запланированную сумму денег.
На начало 2009 года в России более 2 000 000 доменов второго уровня. Общее число сайтов, с учетом доменов второго и третьего уровня, более 6 000 000.
Это означает жесточайшую конкуренцию среди сайтов (Интернет-магазинов), желающих пробиться в первые позиции по своим направлениям деятельности.
Понять, сколько надо вложить в сайт для достижения планируемых показателей, легче, если сравнить затраты на создание, поддержку и раскрутку Интернет-магазина с затратами на содержание и рекламу обычного магазина с тем же ассортиментом.
No |
Сайт (Интернет-магазин) |
Обычный магазин |
|
1. |
Сайт - 'визитная карточка' |
||
1.1 |
начального уровня |
Размещение объявлений в газете или журнале от частного лица о предоставлении какой-либо услуги. Пример: предложение услуг частного фотографа. |
|
1.2 |
среднего уровня |
Размещение объявлений в газете или журнале от частных лиц или небольшой фирмы о предоставлении какой-либо услуги. Пример: предложение о циклевке паркета двумя мастерами, работающими в паре. |
|
1.3 |
высокого уровня |
Затраты на содержание и рекламу фирмы, арендующей небольшую торговую площадь в более крупном магазине, например, супермаркете, или отдельно стоящую торговую палатку. |
|
2. |
Корпоративный сайт |
||
2.1 |
начального уровня |
Затраты на содержание и рекламу небольшого магазина, специализирующегося на продаже товаров одной товарной группы. Пример: магазин по продаже гидромассажных ванн и душевых кабин. |
|
2.2 |
среднего уровня |
Затраты на содержание и рекламу магазина, специализирующегося на продаже товаров определенного назначения. Пример: магазин сантехники. |
|
2.3 |
высокого уровня |
Затраты на содержание и рекламу магазина, специализирующегося на продаже широкого ассортимента товаров определенного назначения. |
|
3. |
Интернет-портал |
||
3.1 |
начального уровня |
Затраты на содержание и рекламу крупного магазина, специализирующегося на продаже широкого ассортимента товаров определенного назначения. Пример: магазин по продаже бытовой техники. |
|
3.2 |
среднего уровня |
Затраты на содержание и рекламу крупного универсального магазина. |
|
3.3 |
высокого уровня |
Затраты на содержание и рекламу крупного универсального магазина с филиалами по России. |
|
4. |
Интернет-'стартап' |
||
4.1 |
отраслевой, тематический |
Затраты на содержание и рекламу крупного торговой сети с филиалами по России. |
|
4.2 |
общего пользования |
Затраты на содержание крупной торговой сети с филиалами по России и за рубежом. |
Для того чтобы создать, поддерживать и раскрутить Интернет-магазин по популярным тематикам по России, в 2009 году нужен годовой бюджет не менее 3 000 000 долларов.
Если указанной суммы денег нет, то от амбиций по созданию Интернет-магазина, который бы занял лидирующие позиции по популярным тематикам, надо отказаться. Стоимость самых дорогих сайтов Рунета в 2009 году составляет от несколько сот миллионов долларов до нескольких миллиардов долларов.
Закон Мура гласит, что число транзисторов на кристалле удваивается каждые два года. Применительно к созданию сайтов, веб-дизайну и редизайну в целом, можно сказать, что средний объём программного кода веб-сайтов будет удваиваться каждые полтора-два года. Затраты фирмы на создание и поддержку сайта (Интернет-магазина) будут удваиваться каждые два года.
Создание Интернет-магазина обходится значительно дешевле, чем обыкновенного магазина с тем же ассортиментом. Но не стоит рассчитывать на то, что создание популярного Интернет-магазина обойдется дешево.
На практике, при одинаковом ассортименте, покупатель выберет магазин с более приятным дизайном или удобной навигацией и системой заказа, зачастую закрыв глаза на небольшую разницу в цене, посчитав, что лучше исполненный, а значит и более дорогой сайт принадлежит более серьезной и крупной фирме, а значит получить некачественный товар или испытать проблемы с доставкой шансов меньше.
Интернет-магазины существенно уменьшают затраты предприятия. Содержание обыкновенного магазина, оплата труда нескольким продавцам и консультантам заменяются лишь на содержание Интернет-сайта и короткого штата. Можно разместить сколько угодно товаров и не беспокоиться за физическую площадь помещения. Покупатель может заказывать товар в любое время суток и в любой день недели, выбор и ознакомление с товаром производится, не выходя из дома. Все это безусловные преимущества Интернет-магазинов
Следовательно, Интернет-магазин может существенно увеличить эффективность работы предприятия в целом.
1.3 Анализ опыта применения Интернет-магазинов
Интернет-торговля - это только часть электронной коммерции, но очень хорошо развивающаяся часть. Торговые операции через Интернет могут осуществлять многие организации - и производители товаров/услуг, и дистрибьюторы, и розничные торговые компании.
При рассмотрении имеющихся на рынке Интернет-магазинов, можно увидеть, что их организационные структуры схожи.
Но полностью, эта структура реализована только в крупных организациях. В маленьких компаниях терминалы структуры берут на себя функции различных отделов. К примеру, Генеральный Директор выполняет функции бухгалтера и менеджера по рекламе и маркетингу, а менеджер отдела продаж выполняет функции менеджера-консультанта и кассира.
Очень важно при создании или изменении организационной структуры учитывать этап развития компании, чтобы даже при минимальной структуре добиться максимальной прибыли.
Что бы Интернет-магазин стал действительно успешным, необходимо, что бы главная страница заинтересовала потенциального покупателя, а не заставляла своим дизайном сразу же закрыть сайт, отпугивая некачественной реализации проекта, заставить его сомневаться в серьезности компании.
Хороший проект с соответствующей реализацией своих функций (продажей товара и т.д.) заставит покупателя вернуться к нему еще и еще раз для совершения новых приобретений.
Обладатель нового устройства мог искать свою будущую покупку через 'централизованные Интернет-услуги поиска товаров по каталогам Интернет-магазинов' - CommerceML, являющейся единым стандартом обмена коммерческой информацией в формате XML (Стандартом предусматривается использование схем XML, в частности, для обмена:
каталогами товаров
коммерческими предложениями (заказами)
документами
Компании, инициировавшие стандарт:
1С;
Port.ru;
Price.ru;
Extra.ru;
Microsoft;
московское представительство компании Intel;
И, воспользовавшись, например, услугами сайта price.ru, мог видеть не только наличие и цены искомого товара в конкретных магазинах определенного города, но и рейтинг, составленный на основе контрольных обзвонов и жалоб покупателей для соответствия наличия товаров на складе, цены, указанной на сайте. Довольный покупатель не только не оставит жалобы, но и напишет отзыв с выбором положительной оценки конкретного Интернет-магазина, с помощью которых, посетители price.ru могут собрать определенную информацию о том, как быстро менеджеры фирм реагируют ответным телефонным звонком на поступающие online-заказы, за какой период времени товар будет доставлен в вашу квартиру или офис и насколько достоверна информация на сайте. А это будет более существенной рекламой, чем советы друзей и знакомых, ведь количество посетителей price.ru несоизмеримо больше, и, отзывы реальных людей, совершивших покупки, будут одним из главных критериев выбора магазина.
Что увидит пользователь, зашедший на среднестатистический Интернет-магазин? Как правило, в левой или правой части страницы, будет список товаров, выполненный в виде древовидной структуры с группами и подгруппами, как в наличии, так и на заказ, которым торгует фирма. В 'шапке' или чуть ниже будет располагаться меню с дополнительной информацией о доставке, способах оплаты и другими информационными ссылками, средства связи, такие как номер телефона, адрес электронной почты и, иногда, уникальный идентификационный номер самой распространенной в России службы мгновенных сообщений в Интернете ICQ, который снизит психологический барьер, позволит иногородним пользователям не платить за междугороднюю связь, узнать про интересующий их товар, а так же, проконсультироваться с менеджером, какой товар для них подойдет больше. Ниже, в середине страницы, будет отображаться выбранный товар из древовидного списка, возможно 'новинки' и дополнительные услуги, которые оказывает фирма.
Зарегистрировавшись и заполнив о себе контактную информацию в виде фамилии, имени, отчества, номеров телефонов, адреса доставки, дополнительной информации, пользователь может переходить к добавлению необходимой продукции в корзину с возможностью указать ее количество. Далее, покупатель выбирает в меню 'Оформить заказ'. Также возможен вариант первоначального добавления товара в Корзину без регистрации, затем оформления заказа и указания имени, контактной информации, желаемого времени доставки товара и варианта оплаты.
Наиболее распространенные формы оплаты товара: наличный расчет курьеру при доставке товара, банковским переводом, электронные платежи (WebMoney, Яндекс. Деньги и др.), безналичный платёж, почтовый перевод.
Товар обычно доставляется курьерскими службами (такими, например, как ООО 'Грузовозофф'), почтой, самовывозом и др.
Принцип построения Интернет-магазина 'AV Cafй' и сравнение с конкурентами
Адрес в Интернет: avcafe.ru
Юридический адрес: Россия, г. Москва, Мичуринский проспект, д.5
Салон 'AV Cafй' (Рис.1.1) занимается продажей электронной техники. Имеет представительство как в виде салона, размером 100 кв. м. по юридическому адресу, так и представительство в виде Интернет-магазина.
Можно обнаружить использование таких технологий, как HTML, PHP, JavaScript, элементы ActiveX.
Первоначально регистрация не требуется. Выбрав из каталога слева тип и подтип товара, в середине страницы мы можем выбрать производителя и модель, кликнув на которую отобразиться подробное описание с характеристиками и фотографией. Здесь же сразу можно добавить товар в 'корзину', выбрав кнопку 'Купить'. Появляется окно с подтверждением добавления товара в 'корзину', выводятся все позиции, находящиеся в ней. Необходимо указать имя и контактные данные, после чего оформить заказ. Перед оформлением заказа можно удалить из 'корзины' любой товар, изменить его количество.
Информация заносится в базу данных и вам выдается уникальное имя пользователя и пароль для последующего упрощения вашей идентификации и будущих покупок.
Интернет-магазин выделяется своим дизайном, разработанным студией 'InsVisions', среди торгующих схожим товаром фирм. Хороший дизайн, удобная навигация ставят его на ступеньку выше многих конкурентов.
Рис.1.1 Интернет-магазин avcafe.ru
Проведем небольшой анализ среди конкурентов AV Cafй. Воспользовавшись услугами сайта price.ru проведем поиск интересующего нас усилителя NAD C355 по Интернет-магазинам Москвы.
Рассмотрим несколько результатов поиска: pult.ru, 1080hd.ru, crystalsound.ru, tvmag.ru, hifimir.ru, bigsale.ru, avcafe.ru.
Pult.ru. Безусловно, это один из крупнейших Интернет-магазинов России. Хороший дизайн, удобная система покупки с расширенной функциональностью корзины, форум с возможностью задать вопросы консультантам и обсудить товар, известность фирмы и огромный ассортимент делают этот магазин одним из лидеров по продаже техники (Рис.1.2).
Рис.1.2 Интернет-магазин pult.ru
1080hd.ru (Рис.1.3), hifimir.ru (Рис.1.4) и crystalsound.ru (Рис.1.5). Имеют абсолютно идентичный дизайн, отличающийся лишь логотипом и цветом меню. На лицо, приобретенный фирмами, торгующими схожим товаром, заранее готовый Интернет-магазин. Слабо отработанный средний дизайн, не самая полная информации о товаре, средняя навигация - только по категориям товара или только по производителю без групп и подгрупп, выводя все товары производителя или группы одним списком, пожалуй, отпугнут некоторое количество покупателей. Зачастую такие проекты говорят о малом бюджете фирмы, а значит и о меньшем количеством товара в наличии и более длительных сроках доставки.
Рис.1.3 Интернет-магазин 1080hd.ru
Рис.1.4 Интернет-магазин hifimir.ruъ
Рис.1.5 Интернет-магазин crystalsound.ru
Рис.1.6 Интернет-магазин tvmag.ru
tvmag.ru (Рис.1.6). Очень пестрый дизайн вызывает раздражение: переизбыток товаров на 'витрине' вкупе с яркими цветами. Функциональность выше среднего, удобство навигации среднее, но достаточно много информации о товаре.
Рис.1.7 Интернет-магазин bigsale.ru
bigsale.ru (Рис.1.7). Строгий, ничем не выделяющийся дизайн производит нейтральное впечатление, не вызывающий дискомфорта. функциональность выше среднего при поиске и заказа товара. Корзина и система заказа товара имеет стандартные пункты, как имя, адрес, средства связи, желаемое время доставки, информации о товаре не так много.
При выборе товаров в Интернет-магазинах не последнее место имеет цена. Самыми дешевыми оказались 1080hd.ru, tvmag.ru, hifimir.ru. Возьмем их за 'точку отчисления'.
В среднем на 4% выше цены у crystalsound.ru.
На 17% выше цены у bigsale.ru, avcafe.ru
Price.ru - самый крупный и известный Интернет-магазин из представленных, выставил цену на 40% выше чем 1080hd.ru, tvmag.ru и hifimir.ru
Таблица сравнения Интернет-магазинов по 5и бальной системе
Интернет-магазин |
pult |
1080hd |
crystalsound |
tvmag |
hifimir |
bigsale |
avcafe |
|
Дизайн |
5 |
2 |
2 |
2 |
2 |
4- |
5 |
|
Удобство навигации |
5 |
3 |
3 |
3 |
3 |
4 |
5 |
|
Функциональность |
5 |
3 |
3 |
4 |
3 |
4 |
5 |
|
Информационное наполнение |
5 |
4- |
4- |
4 |
4- |
4- |
5 |
|
Цена |
2 |
5 |
5- |
5 |
5 |
4- |
4- |
Салон AV Cafe со своим теплым приятным и удобным дизайном, сделанным под стилистику магазина-салона, адекватными ценами, удобной навигацией и системой заказа, показал, каким должен быть Интернет-магазин, внушающий доверие у покупателей, с хорошим соотношением цена товара - качество сервиса.
1.4 Обзор технологических подходов и решений, применяемых при построении Интернет-магазина
Интернет-магазин обычно состоит из тела главной страницы, каталога товаров, поисковой системы, информационных страниц, регистрационной формы, корзины, формы отправки заказа.
На теле главной страницы возможно расположение в различном порядке всех блоков сайта, таких как меню, ссылок, каталога, корзины и прочей информации.
Каталог товаров может представлять собой как список товаров древовидного вида из нескольких ветвей, так и просто список, например, по производителю или типу товара. Так же часто используются 'горячие' товары, располагаемые обычно по середине страницы с постоянно изменяемым списком товаров, и, в зависимости от типа скрипта, появляются самые дешевые товары, самые популярные и т.д. Так же возможен вариант выставления на 'витрину горячих товаров' не генерируемого списка, а исключительно неизменяемой продукции, выгодной для продажи конкретным магазином. В зависимости от дизайна сайта и количества продаваемых товаров возможно выставление полного списка товаров на 'витрину'.
Поисковая система может дать возможность сортировки товара по определенным свойствам, такими как производитель, тип товара и других. Также возможен вариант системы с поиском по всем категориям товара, содержащих в себе введенные пользователем символы.
Информационные страницы о фирме зачастую отсутствуют в Интернет-магазинах не имеющих представительства по юридическому адресу в виде офисов и магазинов. Информация ограничивается лишь контактным телефоном и, возможно, идентификационным номером одной из систем общения коротких сообщений (ICQ, Jabber и подобными). Информационные страницы со способами доставки и оплаты должны присутствовать в любом магазине. В Интернет-магазинах имеющих представительство в реальном мире обычно существует подробное описание фирмы, способах проезда и прочей информацией, потому как такие компании создают электронные магазины также и для рекламы своего представительства по юридическому адресу.
Регистрационные формы могут содержать в себе различные вопросы в зависимости от того, какие цели преследует Интернет-магазин, то могут быть лишь вопросы связанные с контактами с пользователем, если магазин рассчитывает на моментальную выгоду по продаже, либо содержать дополнительные вопросы для изучения спроса и сбора информации о потенциальных покупателях.
Корзина может представлять из себя дополнительно открываемое окно со списком товаров и полной информацией о них, сумме товаров, цене и стоимости с регистрационной формой, а так же существовать как постоянно отображаемый информационный блок. Так же зачастую используется такой способ вывода информации из корзины, когда, например, количество товаров и их стоимость являются постоянно отображаемым небольшим блоком, а по нажатию дополнительной ссылки открывается подробная информация о добавленных позициях.
Форма отправки заказа, в зависимости от структуры сайта, может быть включена как в корзину, существовать в виде блока на главной странице, так и открываться по ссылке заказа товара. Может содержать регистрационную или заполняемую информационную форму при условии, что регистрация не была реализована отдельным меню или включена в корзину.
При разработке Интернет-магазинов используют различные технологии, но самым популярным языком разработки стал PHP за свою простоту и эффективность. Абсолютное большинство Интернет-магазинов основано и успешно функционирует именно на нем. Но у PHP есть недостаток. Не такая большая база готовых модулей, как, например, у Perl.
Скриптовый язык программирования Perl является интерпретируемым и переносимым языком. Он является образчиком для обработки и работы с текстом. Он построен на абсолютно бесплатной платформе OpenSource, что является безусловным плюсом при небольшом бюджете. Для Perl ежедневно пишется большое количество новых программных модулей, поэтому практически не существует проблемы, которую нельзя было бы решить при использовании этого языка с подключением одного из большого множества модулей.
1.5 Выводы
Итак, мы выяснили, что современные Интернет-технологии могут способствовать успешному развитию бизнеса. Повсеместное увеличение пользователей Интернет, делает это направление с каждым днем все более перспективным и прибыльным. Приобрести товар в Интернет возможно в любой день, в любое время суток, при этом использовав не только персональный компьютер, но так же КПК и мобильный телефон.
Интернет-магазин существенно уменьшает издержки предприятия на рекламу, оплату труда сотрудникам, аренду помещения. Покупатель имеет возможность, не выходя из дома, приобрести товар, получив при этом достаточно подробную информацию о нем и при необходимости пообщаться с консультантом.
Интернет-магазин должен быть информативен и рассчитан на широкий круг пользователей, не содержать лишней или ненужной информации, при этом быть достаточно простым для обзора товаров и вариантов заказа.
Необходимо учесть различную степень знаний пользователя о компьютере, Интернет и online-покупках, поэтому нужно иметь подробное описание способов поиска, заказа, доставки, оплаты товара, иметь разделы с контактной информацией и сведениями о магазине, информацией о доставке, прочей полезной информацией, удобной системой поиска по прайс-листам, предоставлять для изучения четко распределенный товар по разделам с подробным описанием и, если понадобиться, фотографией, попробовать заинтересовать покупателя еще какой-то другой позицией прайса в виде ненавязчивой рекламы, кратким описанием достоинств другого товара, просмотром 'новинок', 'часто покупаемых товаров'
Глава 2. Проектирование базы данных и Интерент-магазина для компьютерного салона 'Стоик'
2.1 Постановка задачи
Интернет-магазин компьютерного салона 'Стоик' ориентирован как на юридические лица, так и физические составляют определенную долю потенциальных покупателей.
Необходимо реализовать как функцию Интернет-магазина, так и функцию информационного сайта о компании 'Стоик”, на котором помимо данных о фирме, способов связи, доставки и оплаты должна быть информация об услугах, оказываемых компанией.
Заказчик потребовал реализовать максимально возможную автоматизированность сайта и интеграцию с ресурсами фирм-поставщиков товара. Прайс-листы фирм-поставщиков в автоматическом режиме и по желанию должны загружатся с серверов компаний 'НИКС” и 'OLDI” в zip-архиве, затем будет происходить распакова архивов и загрузка определенных товаров из прайс-листов поставщиков в базу данных. При чем из прайс-листа компании 'OLDI” необходимо выбирать и загружать в базу данных лишь те товары, которые находятся в магазине по адресу г. Москва, ул. Малая Калужская, дом 15, стр.1, потому как оптовые закупки компании 'Стоик' происходят лишь в этом одном из трех магазинов 'OLDI”. Отображение цен на товар необходимо предоставлять в рублях по свежему курсу.
Потенциальный покупатель может выбирать одного из известных поставщиков, либо воспользовавшись поиском, найти необходимый товар, и, если таковой будет иметься у обоих поставщиков, выбрать более выгодный по цене, либо отдать предпочтение одному из поставщиков.
Подробная информация о товарах из прайс-листа должна быть всегда свежей, а так как рынок компьютерных комплектующих - это постоянно обновляемая сфера, то по нажатию на товар из прайс-листа 'Стоик”, будет открываться страница с новейшей информацией о нем с портала поставщика.
Сайт должен предоставлять новости и информацию о новинках в компьютерном мире, обзоры новейших устройств. Данная функция будет реализована на основе RSS-лент известных новостных и компьютерных сайтов.
2.2 Проектирование интерфейса и механизмов навигации
Механизмами навигации обычно служат различного вида меню (текстового, графического, ниспадающего и т.п.), располагаемые как вверху по центру страницы, так и сверху слева. Иногда меню, располагаемое сверху по центру дублируется по центру внизу страницы. Редко встречается меню, расположенное справа. Так же к механизмам навигации относятся кнопки управления страницами 'вперед', 'назад', 'наверх', 'вниз'.
Интернет-магазин обычно состоит из следующих типовых частей:
каталог товаров;
поисковая система;
контактная информация информация о фирме;
регистрационная форма;
корзина;
форма отправки заказа.
Каталог является многоуровневым средством упорядочивания товаров, чаще всего имеющий древовидную структуру данных, которое должно в самой удобной форме предоставлять пользователю максимум информации. Обычно дерево имеет от одного до трех подкаталогов, показывающий такую информацию, например, как тип товара, подтип товара, производитель. Располагается обычно с левой или правой стороны страницы.
Поисковая система, в отличие от каталога, дает возможность быстрого поиска товара, если пользователь уже точно определился с будущей покупкой или если каталог представляет собой дерево с большим количеством групп и подгрупп с широким ассортиментом, а так же, если пользователь не знает, в каком разделе находится товар.
Контактная информация информация о фирме предоставляется в отдельном меню. Там обычно располагаются пункты:
'О фирме' - необязательный пункт. Рассказывается про товары, которыми торгует фирма, как давно она существует и прочая рекламная информация.
'Контактная информация' - номера телефонов, адрес электронной почты, другие средства связи, график работы обычного магазина, график работы приема online заказов, юридический адрес, схема проезда.
'Способы оплаты' - пункт меню, в котором рассказывается, какой валютой можно оплатить товар, подробно раскрываются варианты с безналичным расчетом, банковским переводом, банковскими картами, электронными деньгами.
'Доставка' - рассказывается о возможных регионах доставки товара, о ценах доставки в каждый их них, указывается разница в стоимости, в зависимости от габаритов приобретенного товара, сведения о выдачи гарантии на товар.
И другие возможные пункты.
Регистрационная форма включает в себя заполнение пунктов с входным именем и паролем, именем покупателя, региона, контактной информацией и дополнительных сведений. В дальнейшем храниться в базе данных фирмы и в Cookie-файлах браузера пользователя для упрощения последующей идентификации покупателя и произведения будущих операций с заказами. Часто имеются пункты обязательные для заполнения и e-mail-подтверждение регистрации, которое может отпугнуть пользователя лишними действиями.
Корзина содержит информацию о добавленных товарах, их количество, цену и стоимость. Часто включает в себя регистрационную форму, описанную выше, иногда, с отличием от оной в том, что после ввода информации о себе, система сама сгенерирует ваше входное имя и пароль для последующих приобретений.
Форма отправки заказа существует как часть корзины или как генерируемая страница, на которую пользователь попадает после подтверждения товаров из 'корзины' и служит для отправки заказа на электронный ящик фирмы, а так же отправки контактной информации, в случае отсутствия в 'корзине' регистрационной формы и регистрационной формы в виде отдельного пункта меню.
Карта сайта
/
2.3 Проектирование базы данных
База данных - это совокупность связанных данных, организованных по определенным правилам, предусматривающим общие принципы описания, хранения и манипулирования, независимая от прикладных программ. База данных является информационной моделью предметной области. Обращение к базам данных осуществляется с помощью системы управления базами данных (СУБД). СУБД обеспечивает поддержку создания баз данных, централизованного управления и организации доступа к ним различных пользователей.
Организация структуры БД формируется исходя из следующих соображений:
1. Адекватность описываемому объекту/системе - на уровне концептуальной и логической модели.
2. Удобство использования для ведения учёта и анализа данных - на уровне так называемой физической модели.
Виды концептуальных (инфологических) моделей БД: 'сущность-связь', семантические, графовые
Виды логических (даталогических) моделей БД:
1. Документальные (архивы) - ориентированные на формат документа, дескрипторные, тезаурусные.
2. Фактографические (картотеки).
теоретико-графовые: иерархическая модель, сетевая модель.
теоретико-множественные: реляционная модель (ER-модель), многомерная модель.
объектно-ориентированные: объектная модель.
основанные на инвертированных файлах.
Таким образом, по модели представления данных БД классифицируются:
картотеки;
иерархические;
сетевые;
реляционные;
многомерные;
объектные;
На уровне физической модели электронная БД представляет собой файл или их набор в формате TXT, CSV, Excel, DBF, XML либо в специализированном формате конкретной СУБД. Также в СУБД в понятие физической модели включают специализированные виртуальные понятия, существующие в её рамках - таблица, табличное пространство, сегмент, куб, кластер и т.д.
Наиболее популярные модели представления данных - объектная и реляционная модели данных. Картотеками пользовались до появления электронных баз данных. Сетевые и иерархические базы данных считаются устаревшими, но некоторое возрождение получили иерархические в связи с появлением и распространением XML.
Реляционная база данных представляет собой набор таблиц, связанных между собой, доступ к которым осуществляется с помощью языка запросов SQL.
Примеры реляционных СУБД: MySql, PostgreSql.
В основу объектной модели положена концепция объектно-ориентированного программирования, в которой данные представляются в виде набора объектов и классов, связанных между собой родственными отношениями, а работа с объектами осуществляется с помощью скрытых (инкапсулированных) в них методов.
Примеры объектных СУБД: Cache, GemStone (от Servio Corporation), ONTOS (ONTOS).
В последнее время производители СУБД стремятся соединить два этих подхода и проповедуют объектно-реляционную модель представления данных. Примеры таких СУБД - IBM DB2 for Common Servers, Oracle8.
Лидером среди баз данных, применяемых для разработки WEB-приложений, на сегодняшний день, безусловно, является MySQL.
MySQL - свободно распространяемая система, т.е. платить за ее применение не нужно. Кроме того, это достаточно быстрая, надежная и, главное, простая в использовании СУБД, вполне подходящая для не слишком глобальных проектов.
Работать с MySQL можно не только в текстовом режиме, но и в графическом. Существует очень популярный визуальный интерфейс для работы с этой СУБД. Называется он PhpMyAdmin. Этот интерфейс позволяет значительно упростить работу с базами данных в MySQL.
В текстовом режиме работа с базой данных выглядит просто как ввод команд в командную строку, а результаты выборок возвращаются в виде своеобразных таблиц, поля в которых налезают друг на друга, если данные не помещаются на экран.
Среди других баз данных, применяемых для WEB-разработок, можно отметить Oracle и PostgreSQL.
PostgreSQL - свободно распространяемая СУБД с открытым исходным кодом, ориентированная главным образом на работу в UNIX-подобных системах.
Oracle - явный лидер рынка мощных коммерческих, корпоративных баз данных в последнее время все активнее заявляет о себе и во всемирной сети.
Этапы проектирования базы данных
1. Концептуальное проектирование - сбор, анализ и редактирование требований к данным. Для этого осуществляются следующие мероприятия:
обследование предметной области, изучение ее информационной структуры;
выявление всех фрагментов, каждый из которых характеризуется пользовательским представлением, информационными объектами и связями между ними, процессами над информационными объектами;
моделирование и интеграция всех представлений;
По окончании данного этапа получаем концептуальную модель, инвариантную к структуре базы данных. Часто она представляется в виде модели 'сущность-связь'.
2. Логическое проектирование - преобразование требований к данным в структуры данных. На выходе получаем СУБД-ориентированную структуру базы данных и спецификации прикладных программ. На этом этапе часто моделируют базы данных применительно к различным СУБД и проводят сравнительный анализ моделей.
3. Физическое проектирование - определение особенностей хранения данных, методов доступа и т.д.
Различие уровней представления данных на каждом этапе проектирования реляционной базы данных:
Концептуальный уровень - Представление аналитика (используется инфологическая модель 'сущность-связь')
сущности;
атрибуты;
связи;
Логический уровень - Представление программиста
записи;
элементы данных;
связи между записями;
Физический уровень - Представление администратора
группирование данных;
индексы;
методы доступа;
Инфологическая модель
Даталогическая модель
2.4 Выбор средств разработки
Интернет-магазин реализуется и на стороне сервера и на стороне клиента. Данные вводятся в HTML-формы и заносятся в базу данных через промежуточные модули, называемые сценариями или скриптами, реализуемыми на стороне сервера.
Может понадобиться и проверка правильности вводимых данных, например, если вы считаете необходимым, чтобы в данных, вводимых пользователем, обязательно указывался его E-mail. В этом случае, проверка вводимых данных может выполняться сценариями на стороне сервера. Но это не эффективно, так как в случае неправильного набора данных клиент ждет ответа о неполном вводе от сервера, а затем, вводит данные вновь. С целью уменьшения времени ожидания от сервера, целесообразно ввести проверку правильности вводимых данных в сценарий, выполняемый на стороне клиента. Такой сценарий сообщит клиенту о неправильном вводе данных без обращения к серверу. Вы также, возможно захотите, чтобы страничка ввода меняла свой внешний вид. Например, в зависимости от отдела, в котором находится заказчик, менялся бы перечень товаров, и опять же, вам понадобятся сценарии, которые бы выполнялись на стороне клиента без обращения на сервер.
Для составления сценариев на стороне клиента обычно используются языки JavaScript или VBScript, а изменения внешнего вида достигается с помощью фреймов или слоев. Для сценариев на стороне сервера может быть использован один из языков PHP, ASP, Perl, Pascal, C ++ и другие. В качестве баз данных может быть использована одна из баз данных MsSQL, MsAccess.
Перед началом проектирования сайта необходимо решить для себя: На какой платформе будет работать сайт на Microsoft или Open Source? На первой, к настоящему моменту, существуют более удобные системы проектирования, на второй - у вас будут меньшие затраты на лицензионное программное обеспечение и возможность при желании добавить в них то, что нужно именно в данном магазине для данного товара, т.е. учесть многие нюансы, которые, несомненно привлекут своего клиента.
Для платформы Microsoft вам лучше выбрать VBScript, ASP, Pascal, C ++, MsAccess, MsSQL. Для платформы Open Source - JavaScript, Perl, Pascal, C ++, MySQL.
Интернет - магазин разрабатывается с использованием технологий Perl, JavaScript, MySQL, PHP, CSS.
Perl
Обоснование выбора языка Perl таково, что Perl является переносимым, интерпретируемым языком, идеально приспособленным для многочисленных приложений по обработке текста. А в Интернет-магазине компьютерного салона 'Стоик' одной из важнейших особенностей системы будет являться парсинг прайсов поставщиков и форматирование их в удобный для заказа пользователем товаров вид.
Так же Perl предназначен для выполнения задач командных сценариев Unix в тех случаях, когда они слишком трудны, плохо переносимы или сложны для программирования на другом языке, например на Cи. Perl поддерживает структурированные программные конструкции, и предоставляет разработчику широкий спектр возможностей для создания кратких и эффективных программ.
Perl был разработан Ларри Уоллом в 1986 году. Он создал этот язык, когда пытался формировать отчеты из иерархии файлов системы оповещения об ошибках, похожей на Usenet-новости, а возможности применявшегося в то время обработчика потоков данных awk оказались исчерпанными. Решил вырвать данную проблему с корнем, применив для этого какой-нибудь универсальный инструмент, который он надеялся использовать и в дальнейшем. В результате появилась первая версия языка Perl. В дальнейшем сам Ларри Уолл позаимствовал у Генри Спенсера пакет для работы с регулярными выражениями и модифицировал его для языка Perl. Поиграв немного с этой версией, добавив кое-что, Ларри предложил ее сообществу читателей материалов телеконференций Usenet. Пользователи, имеющие доступ к входящим в систему Usenet компьютерам, разбросанным по всему свету (а их в то время было несколько десятков тысяч), обеспечили для создателя Perl эффективную 'обратную связь', спрашивая, как делать одно, другое, третье. Многие из этих задач Ларри даже и не собирался ставить перед своим маленьким новым языком программирования. Perl вырос, выросли его возможности, повысилась переносимость. То, что когда-то было компактным языком, теперь сопровождается сотнями страниц документации, в состав которых входят десятки man-страниц. Perl стал языком программирования, который сочетает в себе возможности обработки текстовых файлов, генерации отчётов, решения системных задач и низкоуровневое программирование, доступное на языке C. Он и по настоящее время продолжает интенсивно развиваться за счет разработки пакетов, реализующих новые применения языка к развивающимся информационным технологиям.
Я считаю, что за этим языком большое будущее. Причин тому не мало. Во-первых, огромное кол-во программистов постоянно дописывает к Perl новые модули, расширяющие возможности языка. Во-вторых, за скриптовыми языками будущее, так как стремительно растущие мощности железа позволяют не чувствовать существенной разницы между исполнением скриптовой и откомпилированной программы, а Perl прекрасный представитель скриптовых языков.
JavaScript
Преимущества JavaScript.
- оперативность, скрипт обрабатывается на браузере и пользователь тут же видит результат без загрузки на сервер.
PHP
В данном Интернет-магазине на языке PHP был написан всего один скрипт. Он служит для отправки формы с данными о пользователе и позициями, добавленными в корзину на контактный e-mail для заказов товаров.
Преимущества PHP
обработка происходит на сервере не зависимо от браузера и настроек пользователя. В почтовых формах отсутствуют проблемы с кодировками, потому что письмо всегда идет с вашего сервера на вашу почту. На javascript крайне сложно настроить скрипт, чтобы форма корректно обрабатывалась всякой почтовой программой. Главная проблема при этом кодировка. Еще один плюс PHP - легкость загрузки, вся большая формула может быть на сервере, а пользователь получит только результат.
2.5 Выводы
Поставленная задача разработки Интернет-магазина заключалась в максимальной автоматизации процессов обновления прайс-листов товаров и работы с ними, тесно взаимосвязанная с серверами поставщиков. Покупатель ни в чем не ограничен и может сам выбирать более выгодного для него одного из поставщиков товара в зависимости от определенных предпочтений, либо исходя из цены на товар. Для увеличения информативности сайта используется технология RSS, с помощью которой отображаются последние новости компьютерного мира, обзоры и ссылки на новые версии программного обеспечения.
Для создания Интернет-магазина салона 'Стоик' выбор пал на Perl, JavaScript, MySQL.
Perl является переносимым, интерпретируемым языком, идеально приспособленным для многочисленных приложений по обработке текста, поддерживает структурированные программные конструкции, и предоставляет разработчику широкий спектр возможностей для создания кратких и эффективных программ, имеет огромное количество постоянно дописываемых к нему новых модулей, расширяющие возможности языка.
JavaScript являет собой оперативность, скрипт обрабатывается на браузере и пользователь тут же видит результат без загрузки на сервер.
Также они поддерживается подавляющим большинством платных хостингов, что является несомненным плюсом.
При проектировании базы данных выбор пал на СУБД MySQL, являющейся реляционной базой данных, одной из самых популярных моделей представления данных. Реляционная база данных представляет собой набор таблиц, связанных между собой, доступ к которым осуществляется с помощью языка запросов SQL. MySQL - это свободно распространяемая система, т.е. платить за ее применение не нужно, является простой в использовании СУБД, вполне подходящей для не слишком глобальных проектов.
На начальном этапе в проекте Интернет-магазина будут реализованы такие способы оплаты, как оплата банковским переводом и оплата курьеру наличными. Доставка курьером будет нацелена на работающее население города, имеющего возможность выхода в Интернет, но не имеющего времени посетить салон 'Стоик' в связи с неудобным для них графиком работы магазина.
Глава 3. Реализация базы данных и Интернет-магазина
3.1 Реализация интерфейса и механизмов навигации
Разработанный Интернет-магазин достаточно информативен, не содержит лишней или ненужной информации, при этом имеет такой способ представления товаров, который позволяет покупателю с легкостью найти то, что его интересует.
Заходя на сайт Интернет-магазина открывается главная страница (Рис.2.0).
Рис.2.0 Интернет-магазин компьютерного салона 'Стоик'. Главная страница
Клиенту представляется возможность выбрав поставщика, перейти к определенной категории товара, либо задать параметры для поиска среди всех поставщиков, так же представлены 'горячие' товары магазина. Выбрав категорию товара или отсортировав определенный товар с помощью поиска, клиент имеет возможность, кликнув на любую из позиций списка, получить самую последнюю и постоянно обновляемую информацию об устройстве с информационного сайта одного из поставщиков. Реализация поиска и отображение категорий товара происходит при помощи подпрограмм search и showgoods входящих в программу stoik. pl (см. код в приложении 1).
Пройдя процесс регистрации, у пользователя в списке отсортированных товаров появляются дополнительные функции 'добавить в корзину', реализованные с помощью функции addGoods ()
function addGoods (id,pid,seller,number) {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['myaccountgoodsFrame']. document. all.comForm;
}
else
{
var ifrm = NlsGetElementById ('myaccountgoodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. id. value=id;
frm. pid. value=pid;
frm. seller. value=seller;
frm. number. value=number;
frm. submit ();
}
Ссылающуюся на подпрограмму addGoods программы stoik. pl
sub addGoods {
my $pid = shift;
my $list_ref = shift;
my $count;
my $sth;
$list_ref-> [3] =~ s/,/. /;
$sth = $c->prepare ('update $tables:: oldi set pid=?,name=?,cost=?, isGoods=1 where id=?');
$count = $c->execute ($sth,$pid,$list_ref-> [2],$list_ref-> [3],$list_ref-> [1]);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: oldi (id,pid,name,cost, isGoods) values (?,?,?,?,1)');
$c->execute ($sth,$list_ref-> [1],$pid,$list_ref-> [2],$list_ref-> [3]);
}
}
и 'добавить несколько товаров в корзину', реализованной с помощью функции addGoods2 ()
function addGoods2 (id,pid,seller) {
s = prompt ('Введите количество товара','2');
if (! isNaN (s)) {
addGoods (id,pid,seller,s);
}
else
{
alert (s+' - Это не число!');
}
}
Просмотр информации о товаре реализован в подпрограмме showgoods программы stoik. pl (см. код в приложении 1). При нажатии на ссылку открывается постоянно обновляемая страница с информацией о товаре с сайта поставщика.
Рис.2.1 Интернет-магазин компьютерного салона 'Стоик'. Страница, отображающая поиск товара по запросу 'WD' и корзину
Основной блок со списком товаров, информацией о фирме и предоставляемых услугах располагается в виде iframe 'goodsFrame”, информация в котором меняется в зависимости от того, какую функцию задается открыть в iframe 'menuhow' из файла stoik_goods. htm или во время поиска товара при выполнении функции GoSearch () (см. код в приложении 1).
Блок авторизации (Рис.2.2) реализован подпрограммой myaccountinfo. Если пользователь неавторизирован, отображаются кнопка 'вход' и 'регистрация'
Рис.2.2 Интернет-магазин компьютерного салона 'Стоик'. Блок авторизации
в обратном случае отображается имя пользователя, меню управления товарами и учетной записью, количество товаров в корзине и их сумма, блок корзины (Рис.2.3).
Рис.2.3 Интернет-магазин компьютерного салона 'Стоик'. Блок авторизации
Функции регистрации, авторизации и выхода реализованы при помощи команд Register (), Login (), Logout ()
<a href='#' class='sblack' onClick='javascript: window. parent. Login (); '>Вход</a><!! clear!! >|<!! /alreadylogin!! ><a href='#' class='sblack' onClick='javascript: window. parent. Logout (); '>Выход</a><!! /clear!! > <!! alreadylogin!! >|<a href='#' class='sblack'onClick='javascript: window. parent. Register (); '>Регистрация</a> <!! /alreadylogin!! >
которые ссылаются на подпрограммы, входящие в состав программы stoik. pl
sub register {
my $info = shift;
my $page = new template ('$paths:: root/reg_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub register2 {
my $user = $c->{cgi}->param ('user');
my $phone = $c->{cgi}->param ('phone');
my $pass = $c->{cgi}->param ('pass');
my $pass1 = $c->{cgi}->param ('pass1');
my $email = $c->{cgi}->param ('email');
if (UserAlreadyExist ($user)) {
register ('Пользователь $user уже зарегистрирован. Выберите другое имя. ');
} elsif (! $user) {
register ('Введите имя пользователя!');
} elsif ($pass ne $pass1 or! $pass) {
register ('Введите одинаковые пароли не пустые пароли!');
} else {
AddUser ($user,$phone,$pass,$email);
login2 ($user,$pass);
}
}
sub login {
my $info = shift;
my $page = new template ('$paths:: root/login_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub login2 {
my $user = shift || $c->{cgi}->param ('user');
my $pass = shift || $c->{cgi}->param ('pass');
my ($id,$admin) = checkPass ($user,$pass);
if (! $id) {
login ('Неверное имя пользователя или пароль!');
return;
} else {
CreateSession ($id);
$c->{admin} = $admin;
$c->{uid} = $id;
$c->{uname} = $user;
myaccountgoods ('window. parent. reloadInfo (); nwindow. parent. Welcome (); n'.' // == $c->{pid} == n');
}
}
sub logout {
$c->clearCookie ();
DeleteSession ();
myaccountgoods ('window. parent. reloadInfo (); nwindow. parent. Welcome (); n');
}
Корзина реализована в подпрограмме myaccountgoods программы stoic. pl (см. код в приложении 1).
И не в виде дополнительно открывающегося окна, а в блоке myaccountgoodsFrame, всегда отображаемом на любой из страниц сайта при условии, что хотя бы один товар добавлен в 'корзину' или при нажатии кнопки 'сменить пароль'. В корзине помимо списка товаров отображаются ссылки на оформление заказа для доставки курьером или на печать счета при оплате банковским переводом.
Оформление и отправка заказа реализована в форме с методом 'post' ссылающимся на скрипт sendmail. php
<? php
$data ='';
foreach ($_POST as $key=>$value)
{
$data. = '$key:'. strip_tags ($value). 'n';
}
mail ('адрес@почты_компании.ru', 'тема_письма', $data, 'From: адрес@от_какого_адреса_будет_приходить_письмо.ru);
echo 'Спасибо! Ваш заказ принят! Можете закрыть страницу';
? >
Формирование счета происходит в подпрограмме checkprint программы stoik. pl (см. код в приложении 1).
Рис.2.4 Интернет-магазин компьютерного салона 'Стоик'. Корзина
Выбор категории товара происходит командой
showGoods (id категории, поставщик).
Рис.2.5 Интернет-магазин компьютерного салона 'Стоик'. Прайс-лист
Блоки 'Новости Hardware', 'файловый архив', 'обзоры' и 'статьи' созданы для большей информативности сайта и реализованы на основе лент RSS новостных сайтов (Рис.2.6).
Рис.2.6 Интернет-магазин компьютерного салона 'Стоик'. Новостные блоки
3.2 Реализация базы данных
База данных реализована при помощи СУБД MySQL. Это быстрая, надежная и простая в использовании СУБД.
База данных состоит из пяти таблиц:
goods - все товары в базе данных
ordergoods - заказанные товары пользователями
sessions - информация о сессиях работы
settings - хранит дату последнего обновления прайс-листа и количество распечатанных счетов
users - информация о пользователях
Таблица goods состоит из семи столбцов:
name - наименование позиции
cost - текущая цена
oldcost - предыдущая цена
isgoods - содержит информацию о том, является ли позиция товаром или категорией товара
id - индентификационный номер позиции
pid - идентификационный номер категории товара
seller - информация о поставщике товара
Таблица ordergoods состоит из восьми столбцов:
id - идентификационный номер товара
uid - идентификационный номер пользователя
gid - артикул товара
pid - идентификационный номер категории товара
seller - информация о поставщике товара
createdate - дата и время добавления товара
number - количество добавленного товара
oldname - наименование товара
Таблица sessions состоит из четырех столбцов:
id - идентификационный номер сессии
uid - идентификационный номер пользователя
createdate - дата и время начала сессии пользователем
accessdate - дата и время доступа пользователем
Таблица settings состоит из трех столбцов:
id - идентификационный номер строки 'настройки”
name - наименование 'настройки”
value - значение 'настройки”
Таблица users состоит из восьми столбцов:
id - идентификационный номер пользователя
name - входное имя пользователя
phone - номер телефона пользователя
password - пароль пользователя
createdate - дата и время создания пользователя
accessdate - дата и время первого доступа пользователя
admin - хранит информацию об администраторских правах пользователя
email - E-mail пользователя
Создание таблиц на сервере:
CREATE TABLE `goods` (`name` varchar (200) NOT NULL default '',
`cost` float NOT NULL default '0',
`oldcost` float NOT NULL default '0',
`isgoods` tinyint (4) NOT NULL default '0',
`id` int (11) NOT NULL default '0',
`pid` int (11) NOT NULL default '0',
`seller` char (1) NOT NULL default '',
PRIMARY KEY (`id`,`pid`,`seller`)
);
CREATE TABLE `ordergoods` (
`id` int (11) NOT NULL auto_increment,
`uid` varchar (64) NOT NULL default '',
`gid` int (11) NOT NULL default '0',
`pid` int (11) NOT NULL default '0',
`seller` char (1) NOT NULL default '',
`createdate` datetime NOT NULL default '0000-00-00 00: 00: 00',
`number` int (11) NOT NULL default '1',
`oldname` varchar (200) NOT NULL default '',
PRIMARY KEY (`id`)
);
CREATE TABLE `sessions` (
`id` varchar (32) NOT NULL default '',
`uid` int (11) NOT NULL default '0',
`createdate` datetime NOT NULL default '0000-00-00 00: 00: 00',
`accessdate` datetime NOT NULL default '0000-00-00 00: 00: 00'
);
CREATE TABLE `settings` (
`id` int (11) NOT NULL auto_increment,
`name` varchar (64) NOT NULL default '',
`value` varchar (128) NOT NULL default '',
PRIMARY KEY (`id`)
);
CREATE TABLE `users` (
`id` int (11) NOT NULL auto_increment,
`name` varchar (32) NOT NULL default '',
`phone` varchar (32) NOT NULL default '',
`password` varchar (32) NOT NULL default '',
`createdate` datetime NOT NULL default '0000-00-00 00: 00: 00',
`accessdate` datetime NOT NULL default '0000-00-00 00: 00: 00',
`admin` char (1) NOT NULL default '',
`email` varchar (64) NOT NULL default '',
PRIMARY KEY (`id`)
);
Добавление пользователя в базу данных осуществлется подпрограммой AddUser, входящей в программу stoik. pl
sub AddUser {
my $user = shift;
my $phone = shift;
my $pass = shift;
my $email = shift;
my $cryptpass = crypt ($pass,substr ($pass,0,2));
my $sth;
$sth = $c->prepare ('insert into $tables:: users (id,name,phone,password,createdate,accessdate,email,admin)
values (null,?,?,?,now (),now (),?,0)');
$c->execute ($sth,$user,$phone,$cryptpass,$email);
}
Добавление товаров в базу данных осуществляется командой LoadPrice () из файла daemon. pl, который запускается с сервера автоматически в установленное время или вручную.
sub LoadPrice {
my $content = get ($loadurl);
}
$loadurl='http://адрес_сайта.ru/? cmd=loadprices&user=имя_пользователя&pass=пароль';
запускается команда loadprices из файла stoik. pl
$func{'loadprices'} = &loadprices;
выполняется подпрограмма loadprices
sub loadprices {
my $user = $c->{cgi}->param ('user');
my $pass = $c->{cgi}->param ('pass');
my ($id,$admin) = checkPass ($user,$pass);
my $zip;
my $status;
print 'Content-type: text/htmln';
print 'n';
if ($admin) {
load_price ('o');
load_price ('n');
my $t = time;
$t += 60*60*3;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime ($t);
$mon++;
$year += 1900;
setSettings ($settings:: pricedate,'$mday/$mon/$year $hour: $min: $sec');
} else {
print 'Only for ADMINISTRATORS! ';
}
}
Подпрограмма loadprices обращается к подпрограмме load_price программы stoik. pl (см. код в приложении 1).
Так же загрузка прайс-листов в базу данных возможна из администраторской части сайта при помощи формы, выполняющих комманды load_oldi, load_nix из подпрограммы load_price файла stoik. pl
Поиск товара по базе данных осуществляется при помощи подпрограммы search
sub search {
showgoods ('search');
}
Которая, в свою очередь, обращается к подпрограмме showgoods программы stoik. pl, осуществляющей выгрузку информации о товарах из базы данных (см. код в приложении 1).
Выгрузка информации о имени пользователя, количестве товаров добавленных в корзину и итоговой сумме осуществляется при помощи подпрограммы myaccountinfo, входящей в состав программы stoik. pl, которая обращается к подпрограммам getSumGoodByUser и getCountGoodByUser для получения информации о итоговой сумме и количестве товаров из базы данных (см. код в приложении 1).
3.3 Реализация сайта и интеграция с БД
При разработке архитектуры Интернет-магазина, для удобства было обозначено несколько частей: администраторская, клиентская и программная.
Администраторская часть содержит инструменты управления прайс-листами Интернет - магазина.
В клиентской части архитектуры разрабатывается максимально удобная и доступная работа потенциального клиента на страницах Интернет - магазина.
Программная часть архитектуры Интернет - магазина рассматривается как взаимосвязь операционной и серверной части.
Серверная часть содержит в себе размещение Интернет - магазина на сайте провайдера, поддерживающие технологии, используемые при создании Интернет - магазина.
В операционной части рассматривается среда разработки Интернет - магазина.
Главная страница объединяет в себе четыре iFrame, прописанных в файле stoik_goods. htm:
myaccountinfoFrame;
menuhowFrame;
myaccountgoodsFrame;
goodsFrame.
Которые отображают в себе страницы myaccountinfo_frame. htm, menuhow. htm, myaccountgoods_frame. htm и goods_frame. htm при помощи комманд myaccountinfo, menuhow, myaccountgoods, welcome, вызываемых из файла stoik. pl
myaccountinfoFrame - iFrame с информацией о пользователе: входное имя, товары добавленные в корзину (количество и стоимость товаров). А так же с возможностью входа и регистрацией, если пользователь не авторизирован или не зарегистрирован
Выгрузка информации о имени пользователя, количестве товаров добавленных в корзину и итоговой сумме осуществляется при помощи подпрограммы myaccountinfo, входящей в состав программы stoik. pl, которая обращается к подпрограммам getSumGoodByUser и getCountGoodByUser для получения информации о итоговой сумме и количестве товаров из базы данных
menuhowFrame - iFrame, который содержит в себе меню сайта со ссылками на информационные страницы ресурса, такие как 'главная', которая содержит в себе 'горячие' товары магазина, 'контакты' с номером телефона, графиком работы, адресом салона, схемой проезда, 'оплата', где описаны способы опаты наличным и безналичным способом, 'доставка' и 'услуги' с дополнительной информацией об оказываемых услугах компьютерной фирмой, помимо продажи товара. Ссылки открываются во фрейме goodsFrame.
myaccountgoodsFrame - iFrame, содержащий в себе, прежде всего блок корзины, всегда отображаемый при условии наличия в корзине товара, а так же блоки регистрации, авторизации, смены пароля.
goodsFrame - iFrame, содержащий в себе список товаров определенной категории, выбираемой из прайс-листа фирмы, также отображающий в себе информационные страницы сайта, открываемые из фрейма с меню menuhowFrame.
Обновление таблицы с товарами goods базы данных и прайс-листа на сайте происходит в автоматическом или полуавтоматическом режиме в зависимости от пожелания администратора сайта.
Обновление прайс-листа с товарами можно настроить на автоматический режим, установив на сервере компании выполение задачи, например, ежедневно в определенное время файла daemon. pl.
daemon. pl осуществляет загрузку постоянно обновляемых прайс-листов компаний-поставщиков 'НИКС” и 'OLDI” с их серверов.
$nixfile = 'd: nix. zip';
$nixprice = 'ftp: // ftp2. nix.ru/download/price/Nix3. ZIP';
$oldifile = 'd: oldi. zip';
$oldiprice = 'http://www.oldi.ru/price/oldipr. zip';
print '-== - Загрузка прайсов - ==-n';
print 'NIX... ';
$res = getstore ($nixprice, $nixfile);
if ($res == RC_OK) {
print 'OK n';
} else {
die 'Загрузка NIXn';
}
print 'OLDI.. ';
$res = getstore ($oldiprice, $oldifile);
if ($res == RC_OK) {
print 'OKn';
} else {
die 'Загрузка OLDIn';
}
В будущем список поставщиков будет расширен и планируется реализовать возможность интеграции сайта, прайс-листа и базы данных с компанией 'Ф-центр”. Так же на данный момент разрабатывается внутренний прайс-лист компании 'Стоик”, после окончания разработки которого он будет интегрирован с сайтом. После загрузки на сервер свежих Excel прайс-листов в zip-архиве происходит их распаковка
$extractpath = 'd: ';
print '-== - Распаковка прайсов - ==-n';
$zipFile = Archive:: Zip->new ();
$status = $zipFile->read ($nixfile);
print 'NIX... ';
if ($status! = AZ_OK) {
die 'Распаковка прайсовn';
} else {
print 'OKn';
}
$zipFile->extractTree ('','',$extractpath);
print 'OLDI.. ';
$zipFile = Archive:: Zip->new ();
$status = $zipFile->read ($oldifile);
if ($status! = AZ_OK) {
die die 'ОШИБКА4n';
} else {
print 'OKn';
}
$zipFile->extractTree ('','',$extractpath);
Затем идет разборка прайс-листов (парсинг) из Excel-формата в txt.
print '-== - Разборка прайсов - ==-n';
ParseNix ();
ParseOldi ();
$olditxt = $extractpath. 'oldi. txt';
$nixtxt = $extractpath. 'nix. txt';
sub ParseNix {
my $oExcel = new Spreadsheet:: ParseExcel;
my $oFmtR = Spreadsheet:: ParseExcel:: FmtUnicode->new (Unicode_Map => 'CP1251');
my $oBook = $oExcel->Parse ($nixxls, $oFmtR);
my ($iR, $iC, $oWkS, $oWkC);
$oWkS = $oBook->Worksheet (0);
$kurs = $oWkS->{Cells} [3] [4] - >{Val};
my $price;
my $price1;
my $id;
my $pid;
my $name;
my $isGood;
my $parent;
open (FILE,'>',$nixtxt);
NEXTL: for (my $iR = 7; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow}; $iR++) {
$pid = $oWkS->{Cells} [$iR] [5] - >{Val};
$price = $oWkS->{Cells} [$iR] [2] - >{Val};
$price1 = $oWkS->{Cells} [$iR] [2] - >Value;
$id = $oWkS->{Cells} [$iR] [0] - >{Val};
$price = $price*$kurs*1.05;
if ($pid) {
$parent = $pid;
$id = $parent;
$pid = 0;
$isGood = 0;
$name = $oWkS->{Cells} [$iR] [0] - >Value;
} else {
$id = $oWkS->{Cells} [$iR] [0] - >{Val};
$isGood = 1;
$pid = $parent;
$name = $oWkS->{Cells} [$iR] [1] - >Value;
}
print FILE '$isGood|$id|$pid|$name|$pricen';
}
close (FILE);
}
sub ParseOldi {
my $oExcel = new Spreadsheet:: ParseExcel;
my $oFmtR = Spreadsheet:: ParseExcel:: FmtUnicode->new (Unicode_Map => 'CP1251');
my $oBook = $oExcel->Parse ($oldixls, $oFmtR);
my ($iR, $iC, $oWkS, $oWkC);
$oWkS = $oBook->Worksheet (0);
open (FILE,'>',$olditxt);
my @parent;
$parent [0] = 0;
my $iParent;
my $isGood;
my $price;
NEXTL: for (my $iR = 2; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow}; $iR++) {
my $colId = $oWkS->{Cells} [$iR] [1];
my $colName = $oWkS->{Cells} [$iR] [2];
my $colPrice = $oWkS->{Cells} [$iR] [7] - >{Val};
my $colStore = $oWkS->{Cells} [$iR] [6];
$colPrice = $colPrice*$kurs;
my $id;
if ($colId) {
$id = $colId->Value;
} else {
next NEXTL;
}
my $name;
if ($colName) {
$name = $colName->Value;
} else {
next NEXTL;
}
my $bgcolor = $oExcel->ColorIdxToRGB ($colName->{Format}->{Fill} [1]);
my $font = $colName->{Format}->{Font};
my $store;
if ($bgcolor eq '000000') {
$iParent = 0;
$isGood = 0;
$parent [1] = $id;
} elsif ($font->{Bold} &&! $font->{Italic}) {
$iParent = 1;
$isGood = 0;
$parent [2] = $id;
} elsif ($font->{Bold} && $font->{Italic}) {
$iParent = 2;
$isGood = 0;
$parent [3] = $id;
} elsif (! $isGood) {
$isGood = 1;
$iParent = $iParent + 1;
}
if ($colStore) {
$store = $colStore->Value;
} else {
$store = 0;
}
if ($isGood &&! $store) {
next NEXTL;
}
if ($colPrice) {
$price = $colPrice;
} else {
$price = 0;
}
print FILE '$isGood|$id|$parent [$iParent] |$name|$pricen';
}
close (FILE);
}
Выгрузка файлов на хостинг
$ftphost = 'u163263. ftp. masterhost.ru';
$ftpuser = 'u163263';
$ftppass = 'unsend4lvi';
print '-== - Выгрузка прайсов - ==-n';
uploadArchive ();
sub uploadArchive {
my $ftp = Net:: FTP->new ($ftphost, Debug => 0) or die 'Cannot connect to some. host. name: $@';
$ftp->login ($ftpuser,$ftppass) or die 'Cannot login', $ftp->message;
$ftp->cwd ('/адрес_сайта.ru/') or die 'Cannot change working directory', $ftp->message;
$ftp->put ($nixtxt);
$ftp->put ($olditxt);
$ftp->quit;
}
Затем происходит выгрузка прайс-листа из txt файла в таблицу с товарами goods базы данных
print '-== - Загрузка прайсов в базу - ==-n';
LoadPrice ();
sub LoadPrice {
my $content = get ($loadurl);
}
sub uploadArchive {
my $ftp = Net:: FTP->new ($ftphost, Debug => 0) or die 'Cannot connect to some. host. name: $@';
$ftp->login ($ftpuser,$ftppass) or die 'Cannot login', $ftp->message;
$ftp->cwd ('/адрес_сайта. /') or die 'Cannot change working directory', $ftp->message;
$ftp->put ($nixtxt);
$ftp->put ($olditxt);
$ftp->quit;
}
sub archivePrice {
my $zip = Archive:: Zip->new ();
$zip->addFile ($nixtxt);
$zip->addFile ($olditxt);
$zip->writeToFileNamed ($archive);
}
происходит обращение к подпрограмме loadprices из файла stoik. pl
$loadurl='http://адрес_сайта.ru/? cmd=loadprices&user=имя_администратора&pass=пароль';
sub loadprices {
my $user = $c->{cgi}->param ('user');
my $pass = $c->{cgi}->param ('pass');
my ($id,$admin) = checkPass ($user,$pass);
my $zip;
my $status;
print 'Content-type: text/htmln';
print 'n';
if ($admin) {
load_price ('o');
load_price ('n');
my $t = time;
$t += 60*60*3;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime ($t);
$mon++;
$year += 1900;
setSettings ($settings:: pricedate,'$mday/$mon/$year $hour: $min: $sec');
} else {
print 'Only for ADMINISTRATORS! ';
}
}
3.4 Внедрение и анализ эффективности
Фирма ООО Компьютерный салон 'Стоик' существует на рынке уже более 15 лет и специализируется по розничной продаже цифровой и компьютерной техники: телевизоры, компьютеры, комплектующие, мониторы, расходные материалы, оргтехника и т.д.
На данный момент у фирмы имеется офис в г. Калуга.
Некоторое время назад у фирмы был сайт, но эффективность его работы была неудовлетворительная. Сайт имел лишь ознакомительную информацию о фирме, ее месторасположении и контактах. В настоящее время сайт закрыт.
Основные задачи, стоящие перед фирмой:
1. Увеличение сбыта продукции.
2. Снижение накладных расходов на рекламу и оплату труда.
3. Расширение региона сбыта товаров от г. Калуги до Калужской области.
Наиболее эффективный и дешёвый способ их решения - создание Интернет-магазина по продаже цифровой и компьютерной техники.
Интернет-магазин представляет собой виртуальную точку продаж в дополнение к реальному магазину, повышает объем сбываемой продукции и при этом намного дешевле в обслуживании без дополнительных затрат на помещение и зарплаты сотрудникам.
Потенциальными потребителями Интернет-магазинов являются различных уровней знаний пользователи компьютеров, что само по себе ставит именно цифровые и компьютерные товары на первую строчку популярности покупок в Интернет.
Компании-поставщики 'НИКС' и 'OLDI' являются одними из самых популярных и известных фирм по продаже техники в Москве, что делает их выбор в роли поставщиков компьютерного салона 'Стоик' очевидным. Пользователь, зайдя в Интернет-магазин фирмы 'Стоик' может выбирать для себя более интересного по определенным причинам поставщика или более выгодного по цене.
Не секрет, что в регионах цены на технику выше столичных и при просмотре информации о товаре, отображаемого с сервера поставщика, потенциальный покупатель имеет возможность увидеть и розничную московскую цену, которая окажется лишь немного ниже предлагаемой салоном 'Стоик', что так же даст дополнительный толчок к приобретению товара в салоне, учитывая тенденцию, наблюдаемую несколько лет назад, когда региональный покупатель, сравнивая цены, ездил за компьютерной техникой в Москву.
3.5 Вывод
Разработанный Интернет-магазин ориентирован на покупателей с различной степенью компьютерной грамотности и является достаточно информативным, не содержащим лишней информации, при этом имеет такой способ представления товаров, который позволяет покупателю с легкостью найти то, что его интересует.
База данных реализована с использованием СУБД MySQL и состоит из пяти таблиц, связанных между собой при помощи скриптов на Perl.
Интернет-магазин реализован как на сервере компании, так и на хостинге. На сервере компании происходит запуск скрипта, скачивающего новые прайс-листы поставщиков, их распаковка и парсинг. На хостинге храниться вся доступная информация сайта, база данных, клиентская и администраторская части Интернет-магазина.
Автоматизированная система по обновлению прайс-листов Интернет-магазина компьютерного салона 'Стоик' путем скачивания последних прайс-листов поставщиков, преобразованию их в требуемый формат с выборкой по определенным параметрам и последующая загрузка товаров в базу данных является одной из главных задач, поставленных заказчиком.
Основными задачами, стоящими перед фирмой являются:
1. Увеличение сбыта продукции.
2. Снижение накладных расходов на рекламу и оплату труда.
3. Расширение региона сбыта товаров от г. Калуги до Калужской области.
Наиболее эффективный и дешёвый способ их решения - Интернет-магазин по продаже цифровой и компьютерной техники, который будет представлять собой виртуальную точку продаж в дополнение к реальному магазину, повысит объем сбываемой продукции и при этом будет намного дешевле в обслуживании без дополнительных затрат на помещение и зарплаты сотрудникам.
Заключение
Проанализировав опыт применения Интернет-технологий для ведения бизнеса можно сделать вывод, что Интернет-торговля - это очень хорошо развивающаяся часть электронной коммерции.
Изучив типы решений и подходы среди Интернет-магазинов, можно увидеть, что их организационные структуры схожи. Что бы Интернет-магазин стал действительно успешным, необходимо, что бы главная страница заинтересовала потенциального покупателя, навигация была простой и удобной, товары были подробно представлены.
Интернет-магазин обычно состоит из следующих типовых частей:
каталог товаров;
поисковая система;
контактная информация информация о фирме;
регистрационная форма;
корзина;
форма отправки заказа.
Самым популярным языком при разработке Интернет-магазинов стал PHP за свою простоту и эффективность. Но у PHP есть недостаток - он включает в себя большое количество самых необходимых модулей, но если программисту понадобятся дополнительные возможности языка, он не всегда сможет ими воспользоваться, потому как у PHP не достаточно много подключаемых программных модулей для расширения своей функциональности, как, например, у Perl.
Perl является интерпретируемым и переносимым языком. Он является образчиком для обработки и работы с текстом и построен на бесплатной платформе OpenSource. Для Perl ежедневно пишется большое количество новых программных модулей, поэтому практически не существует проблемы, которую нельзя было бы решить при использовании этого языка с подключением одного из модулей.
При проектировании базы данных и Интернет-магазина, была выбрала реляционная база данных, как одна из наиболее популярных моделей представления данных - объектной и реляционной. Реляционная база данных представляет собой набор таблиц, связанных между собой, доступ к которым осуществляется с помощью языка запросов SQL. Примером служит СУБД MySQL, являющаяся лидером среди баз данных, применяемых для разработки WEB-приложений на сегодняшний день. Это свободно распространяемая система. Кроме того, она достаточно быстрая, надежная и, главное, простая в использовании, подходящая для не слишком глобальных проектов.
Интернет-магазин реализован как на хостинге, так и на сервере компании. На хостинге храниться администраторская, клиентская части и база данных, на сервере происходит запуск скрипта загружающего новые прайс-листы с серверов поставщиков, их распаковка, обработка, парсинг и загрузка в базу данных.
Реализована база данных из пяти таблиц, хранящих в себе информацию о товарах, пользователях и настройках.
При внедрении Интернет-магазина основными задачами, стоящими перед фирмой являлись:
1. Увеличение сбыта продукции.
2. Снижение накладных расходов на рекламу.
3. Расширение региона сбыта товаров от г. Калуги до Калужской области.
Анализ эффективности показал, что наиболее эффективный и дешёвый способ их решения - создание Интернет-магазина по продаже цифровой и компьютерной техники, представляющего собой виртуальную точку продаж в дополнение к реальному магазину, которая повышает объем сбываемой продукции, расширяет регион потенциальных покупателей и при этом намного дешевле в обслуживании без дополнительных затрат на помещение и зарплаты сотрудникам.
Список использованных источников и литературы
1. Уилсон Р., Планирование стратегии интернет-маркетинга,, Изд.: Издательский дом Гребенникова, 2003г.
2. Успенский И., Интернет как инструмент маркетинга,, Изд.: BHV - Санкт - Петербург, 1999г.
3. Алексунин В., Родигина В., Электронная коммерция и маркетинг в Интернете,, Изд.: Дашков и Ко, 2007г.
4. Вонг Т., 101 способ поднять вашу сетевую торговлю. Как облегчить Интернет-маркетинг, Изд.: Диля, 2004г.
5. Кеглер Т., Доулин П., Тейлор Б., Тестерман Д., Реклама и маркетинг в Интернете,, Изд.: Альпина Паблишер, 2003г.
6. Холмогоров В., Интернет-маркетинг. Краткий курс,, Изд.: Питер, 2001г.
7. Холмогоров В., Интернет-маркетинг. Краткий курс. Второе издание,, Изд.: Питер, 2002г.
8. Костяев Р., Бизнес в Интернете: финансы, маркетинг, планирование, Изд.: BHV - Санкт - Петербург, 2002г.
9. Фэй М.Д., Реклама, маркетинг, дизайн в Интернете, Изд.: Channel Trading Ltd, 1999г.
10. Пирс К., Освой самостоятельно Perl за 24 часа, Изд.: Вильямс, 2001г.
11. Матросов А., Самоучитель Perl, Чаунин М.П., Изд.: BHV, 2003г.
12. Шварц Р.Л., Изучаем Perl, Изд.; BHV - Санкт - Петербург, 2002г
13. Кристиансен Т., Торкингтон Н., Perl. Сборник рецепотов. Для профессионалов, Изд.: Питер, Санкт-Петербург, 2004г.
14. Дунаев В., JavaScript - самоучитель, Изд.: Питер, 2005г.
15. Флэнаган Д., JavaScript - подробное руководство, Изд.: Символ, 2008г.
16. Соколов В., Соколов С., JavaScript в примерах, типовых решениях и задачах, Изд.: Вильямс, 2006 г.
17. Дмитриева М., JavaScript, Изд.: БХВ-Петербург, 2004г.
18. Ломов А., Apache, Perl, MySQL. Практика создания динамических сайтов, Изд.: БХВ-Петербург, 2007 г.
19. Прохоренок Н., HTML, JavaScript, PHP и MySQL. Джентельменский набор Web-мастера,., Изд.: БХВ-Петербург, 2008 г.
20. Мейер Э.А. CSS - каскадные таблицы стилей. Подробное руководство.3-е издание., Изд.: Символ, Символ-Плюс, 2008г.
21. Шмит К., CSS. Рецепты программирования, Изд.: БХВ-Петербург, 2007 г.
22. http://ru. wikipedia.org
23. http://docs.com.ru/
24. http://www.internet-technologies.ru
25. http://webdesign.net-soft.ru
26. http://books.net-soft.ru
27. http://www.amperl.ru/
Приложения
Программный код основных модулей:
stoik. pl;
daemon. pl;
common. pm;
template. pm;
localset. pm;
settings. pm.
stoik_goods. htm
stoik. pl
#! /usr/bin/perl
use POSIX qw (strftime);
use localset;
use settings;
use template;
use Time:: HiRes qw (usleep ualarm gettimeofday tv_interval);
use common;
use vars qw ($c $mainpage);
use strict;
use Archive:: Zip qw (: ERROR_CODES: CONSTANTS);
my $t0 = [gettimeofday];
my @out;
$c = new common ();
$c->do ('set names cp1251');
my %func;
my $cmd = $c->{cgi}->param ('cmd') || 'home';
$func{'home'} = &home;
$func{'admin'} = &admin;
$func{'showtree'} = &showtree;
$func{'showgoods'} = &showgoods;
$func{'addmygoods'} = &addmygoods;
$func{'showmygoods'} = &showmygoods;
$func{'myaccountinfo'} = &myaccountinfo;
$func{'myaccountgoods'} = &myaccountgoods;
$func{'deletemygoods'} = &deletemygoods;
$func{'editmygoods'} = &editmygoods;
$func{'reloadgoodsframe'} = &reloadgoodsframe;
$func{'search'} = &search;
$func{'checkprint'} = &checkprint;
$func{'sendmail'} = &sendmail;
$func{'login'} = &login;
$func{'login2'} = &login2;
$func{'logout'} = &logout;
$func{'register'} = ®ister;
$func{'register2'} = ®ister2;
$func{'changepass'} = &changepass;
$func{'changepass2'} = &changepass2;
$func{'loadprices'} = &loadprices;
$func{'menuhow'} = &menuhow;
$func{'welcome'} = &welcome;
$func{'aboutus'} = &aboutus;
$func{'order'} = ℴ
$func{'buy'} = &buy;
$func{'deliver'} = &deliver;
$func{'uslugi'} = &uslugi;
$func{'basket'} = &basket;
$mainpage = new template ('$paths:: root/stoik_main. htm','ALL');
$mainpage->replaceContent ('rooturl', $paths:: url);
$func{$cmd}-> ();
if ($cmd eq 'home' or $cmd eq 'admin') {
my $elapsed = tv_interval ($t0, [gettimeofday]);
$mainpage->replaceContent ('elapsedtime', $elapsed);
$mainpage->replaceContent ('debug', $c->{pid});
$mainpage->replaceContent ('queries', $c->{queries});
$mainpage->clearAllTags ();
$mainpage->print ();
}
sub loadprices {
my $user = $c->{cgi}->param ('user');
my $pass = $c->{cgi}->param ('pass');
my ($id,$admin) = checkPass ($user,$pass);
my $zip;
my $status;
print 'Content-type: text/htmln';
print 'n';
if ($admin) {
# $zip = Archive:: Zip->new ();
# $status = $zip->read ($files:: archive_file);
# if ($status! = AZ_OK) {
# print 'prices read archive.. FAILEDn $status';
# } else {
# print 'prices read archive.. OKn';
# $zip->extractMember ('oldi. txt');
# $zip->extractMember ('nix. txt');
# #$zip->extractTree ('','',$paths:: root);
#
# }
load_price ('o');
load_price ('n');
my $t = time;
$t += 60*60*3;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime ($t);
$mon++;
$year += 1900;
setSettings ($settings:: pricedate,'$mday/$mon/$year $hour: $min: $sec');
} else {
print 'Only for ADMINISTRATORS! ';
}
}
sub myaccountinfo {
my $script = shift;
my $page = new template ('$paths:: root/myaccountinfo_frame. htm','ALL');
my $uid = $c->{uid};
if ($uid) {
my $goodscount = getCountGoodByUser ($uid);
my $goodssum = getSumGoodByUser ($uid);
$goodssum = sprintf ('%.2f', $goodssum);
$page->clearLoopTags ('alreadylogin');
if (! $c->{admin}) {
$page->clearLoopTags ('admin');
}
$page->replaceContent ('script',$script);
$page->replaceContent ('count',$goodscount);
$page->replaceContent ('summa',$goodssum);
} else {
$page->clearLoopTags ('clear');
}
$page->replaceContent ('username',$c->{uname});
$page->clearAllTags ();
$page->print ();
}
sub checkprint {
my $script = shift;
my $page = new template ('$paths:: root/checkprint. htm','ALL');
my $uid = $c->{uid};
my $goodscount = getCountGoodByUser ($uid);
my $sth;
my @out;
my $sum = 0;
my $class;
my $count;
my $curdate = strftime '%d. %m. %Y', localtime;
if ($goodscount) {
$sth = $c->prepare ('select t1. id,t1. number,t1. seller,t1. gid,t1. oldname,t2. name,t2. cost from $tables:: mygoods as t1
left join goods as t2 ON t1. gid = t2. id
and t1. pid = t2. pid
and t1. seller = t2. seller
where t1. uid =?');
$c->execute ($sth,$uid);
while (my ($id_,$number_,$seller_,$gid_,$oldname_,$name_,$cost_) = $sth->fetchrow_array) {
$sum = $sum + $cost_ * $number_;
$sum = sprintf ('%.2f', $sum);
$count += 1;
if (! $name_) {
$cost_ = 0;
$number_ = 0;
$name_ = '<span class='warning'>Товар с артикулом $seller_$gid_ не найден. ($oldname_) </span>';
}
if ($count & 1) {
$class ='even';
} else {
$class ='';
}
push @out, {
npp => $count,
class => $class,
sum => sprintf ('%.2f', ($cost_ * $number_)),
name => $name_,
cost => $cost_,
number => $number_,
id=>'$seller_$gid_',
};
}
$page->replaceLoopContent ('goodsloop', @out);
} else {
$page->clearLoopTags ();
}
my $print = getSettings ($settings:: printcount);
$print++;
setSettings ($settings:: printcount,$print);
$page->replaceContent ('summa',$sum);
$page->replaceContent ('curdate',$curdate);
$page->clearAllTags ();
$page->print ();
}
sub register {
my $info = shift;
my $page = new template ('$paths:: root/reg_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub register2 {
my $user = $c->{cgi}->param ('user');
my $phone = $c->{cgi}->param ('phone');
my $pass = $c->{cgi}->param ('pass');
my $pass1 = $c->{cgi}->param ('pass1');
my $email = $c->{cgi}->param ('email');
if (UserAlreadyExist ($user)) {
register ('Пользователь $user уже зарегистрирован. Выберите другое имя. ');
} elsif (! $user) {
register ('Введите имя пользователя!');
} elsif ($pass ne $pass1 or! $pass) {
register ('Введите одинаковые пароли не пустые пароли!');
} else {
AddUser ($user,$phone,$pass,$email);
login2 ($user,$pass);
}
}
sub AddUser {
my $user = shift;
my $phone = shift;
my $pass = shift;
my $email = shift;
my $cryptpass = crypt ($pass,substr ($pass,0,2));
my $sth;
$sth = $c->prepare ('insert into $tables:: users (id,name,phone,password,createdate,accessdate,email,admin)
values (null,?,?,?,now (),now (),?,0)');
$c->execute ($sth,$user,$phone,$cryptpass,$email);
}
sub UserAlreadyExist {
my $user = shift;
my $sth;
$sth = $c->prepare ('select count (*) from $tables:: users where name=?');
$c->execute ($sth,$user);
my $count = $sth->fetchrow_array;
return $count;
}
sub logout {
$c->clearCookie ();
DeleteSession ();
myaccountgoods ('window. parent. reloadInfo (); nwindow. parent. Welcome (); n');
}
sub changepass {
my $info = shift;
my $uid = $c->{uid};
if ($uid) {
my $page = new template ('$paths:: root/changepass_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
}
sub changepass2 {
my $info = shift;
my $user = $c->{uname};
my $oldpass = $c->{cgi}->param ('oldpass');
my $pass = $c->{cgi}->param ('pass');
my $pass1 = $c->{cgi}->param ('pass1');
if (! checkPass ($user,$oldpass)) {
changepass ('Старый пароль не верен!');
} elsif ($pass ne $pass1) {
changepass ('Разные новые пароли!');
} else {
ChangePASS ($user,$pass);
myaccountgoods ();
}
}
sub login {
my $info = shift;
my $page = new template ('$paths:: root/login_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub login2 {
my $user = shift || $c->{cgi}->param ('user');
my $pass = shift || $c->{cgi}->param ('pass');
my ($id,$admin) = checkPass ($user,$pass);
if (! $id) {
login ('Неверное имя пользователя или пароль!');
return;
} else {
CreateSession ($id);
$c->{admin} = $admin;
$c->{uid} = $id;
$c->{uname} = $user;
myaccountgoods ('window. parent. reloadInfo (); nwindow. parent. Welcome (); n'.' // == $c->{pid} == n');
}
}
sub DeleteSession {
my $sid = $c->{pid};
my $sth;
$sth = $c->prepare ('delete from $tables:: sessions where id=?');
$c->execute ($sth,$sid);
$c->{uid} = 0;
$c->{admin} = 0;
$c->{uname} = 'Гость';
}
sub CreateSession {
my $uid = shift;
$c->setCookie ();
my $sid = $c->{pid};
my $sth;
$sth = $c->prepare ('insert into $tables:: sessions (id,uid,createdate,accessdate) values (?,?,now (),now ())');
$c->execute ($sth,$sid,$uid);
}
sub ChangePASS () {
my $user = shift;
my $pass = shift;
my $cryptpass = crypt ($pass,substr ($pass,0,2));
my $sth;
$sth = $c->prepare ('update $tables:: users set password=? where name=?');
$c->execute ($sth,$cryptpass,$user);
}
sub checkPass {
my $user = shift;
my $pass = shift;
my $sth;
$sth = $c->prepare ('select id,password,admin from $tables:: users where name=?');
$c->execute ($sth,$user);
my ($id,$password,$admin) = $sth->fetchrow_array;
if (crypt ($pass,$password) ne $password) {
return (0,0);
} else {
return ($id,$admin);
}
}
sub myaccountgoods {
my $script = shift;
my $page = new template ('$paths:: root/myaccountgoods_frame. htm','ALL');
my $uid = $c->{uid};
my $goodscount = getCountGoodByUser ($uid);
my $sth;
my @out;
my $sum = 0;
my $class;
my $count;
my $error = '';
if ($goodscount) {
$sth = $c->prepare ('select t1. id,t1. number,t1. seller,t1. gid,t1. oldname,t2. name,t2. cost from $tables:: mygoods as t1
left join goods as t2 ON t1. gid = t2. id
and t1. pid = t2. pid
and t1. seller = t2. seller
where t1. uid =?');
$error. = $sth->errstr if $sth->err;
$c->execute ($sth,$uid);
$error. = $sth->errstr if $sth->err;
while (my ($id_,$number_,$seller_,$gid_,$oldname_,$name_,$cost_) = $sth->fetchrow_array) {
if (! $name_) {
$cost_ = 0;
$number_ = 0;
$name_ = '<span class='warning'>Товар с артикулом $seller_$gid_ не найден. ($oldname_) </span>';
}
$sum = $sum + $cost_ * $number_;
$cost_ = sprintf ('%.2f', $cost_);
$count += 1;
if ($count & 1) {
$class ='even';
} else {
$class ='';
}
push @out, {
class => $class,
name => $name_,
cost => $cost_,
number => $number_,
id=>'$seller_$gid_',
idgoods=>'$id_',
};
}
$page->replaceLoopContent ('goodsloop', @out);
} else {
$page->clearLoopTags ();
}
if ($script) {
$page->replaceContent ('script','$scriptn $error');
}
$page->clearAllTags ();
$page->print ();
}
sub getSumGoodByUser {
my $uid = shift;
my $sth;
my $sum = 0;
$sth = $c->prepare ('select t2. cost,t1. number from $tables:: mygoods as t1,$tables:: goods as t2 where
t1. uid=? and t2. id = t1. gid and t2. seller=t1. seller and t2. pid=t1. pid');
$c->execute ($sth,$uid);
while (my ($cost,$number) = $sth->fetchrow_array) {
$sum = $sum + $cost * $number;
}
if ($sum eq '0E0' ||! $sum) {
$sum = 0;
}
return $sum;
}
sub getCountGoodByUser {
my $uid = shift;
my $sth;
#$sth = $c->prepare ('select sum (t1. number) from $tables:: mygoods as t1,$tables:: goods as t2 where
# t1. uid=? and t2. id = t1. gid and t2. seller=t1. seller and t2. pid=t1. pid');
$sth = $c->prepare ('select sum (number) from $tables:: mygoods where uid=?');
$c->execute ($sth,$uid);
my $count = $sth->fetchrow_array;
if ($count eq '0E0' ||! $count) {
$count = 0;
}
return $count;
}
sub deletemygoods {
my $id = $c->{cgi}->param ('id');
my $uid = $c->{uid};
my $sth;
my $script;
if ($id eq 'all') {
$sth = $c->prepare ('delete from $tables:: mygoods where uid=?');
$c->execute ($sth,$uid);
myaccountinfo ('window. parent. reloadGoods (); ');
} else {
$sth = $c->prepare ('delete from $tables:: mygoods where id=? and uid=?');
$c->execute ($sth,$id,$uid);
$script = 'window. parent. reloadInfo (); n';
myaccountgoods ($script);
}
}
sub editmygoods {
my $id = $c->{cgi}->param ('id');
my $uid = $c->{uid};
my $number = $c->{cgi}->param ('number');
my $sth;
my $script;
$sth = $c->prepare ('update $tables:: mygoods set number=? where id=? and uid=?');
$c->execute ($sth,$number,$id,$uid);
$script = 'window. parent. reloadInfo (); n';
$script. = 'window. parent. document. getElementById ('infoelapsedtime'). innerHTML = ''; n';
myaccountgoods ($script);
}
sub getNameByID {
my $id = shift;
my $pid = shift;
my $seller = shift;
my $sth;
$sth = $c->prepare ('select name from $tables:: goods where id=? and pid=? and seller=?');
$c->execute ($sth,$id,$pid,$seller);
return $sth->fetchrow_array;
}
sub addmygoods {
my $gid = $c->{cgi}->param ('id');
my $pid = $c->{cgi}->param ('pid');
my $uid = $c->{uid};
my $seller = $c->{cgi}->param ('seller');
my $number = $c->{cgi}->param ('number');
my $sth;
my $script;
if ($uid) {
my $oldname = getNameByID ($gid,$pid,$seller);
if ($gid && $uid && $seller && $pid && $number) {
$sth = $c->prepare ('insert into $tables:: mygoods (oldname, id,uid,gid,pid,seller,number,createdate)
values (?,null,?,?,?,?,?,now ())');
#$error. = $sth->errstr if $sth->err;
$c->execute ($sth,$oldname,$uid,$gid,$pid,$seller,$number);
#$error. = $sth->errstr if $sth->err;
}
$script = 'window. parent. reloadInfo (); n';
}
myaccountgoods ($script);
}
sub search {
showgoods ('search');
}
sub showgoods {
my $cmd = shift;
my $str = $c->{cgi}->param ('str'); # search text
my $artikul = $c->{cgi}->param ('artikul');
my $str1 = $str;
if ($str) {
$str =~ s/'/\'/;
$str =~ s/</< /;
$str =~ s/>/> /;
}
my $from = $c->{cgi}->param ('from') || 0;
my $t0 = [gettimeofday];
my $pid = $c->{cgi}->param ('pid');
my $seller = $c->{cgi}->param ('seller');
my $page;
my $sth;
my @out;
my $count = 0;
my $class;
my $p;
my $img;
my $parent;
my $url;
$page = new template ('$paths:: root/goods_frame. htm','ALL');
my $sql;
my $invalue = '';
if ($cmd eq 'search') {
if ($artikul) {
my @list = split (/|/,$str);
my $index;
foreach $index (0. $#list) {
$invalue. = $list [$index];
if ($index < $#list) {
$invalue. = ',';
}
}
$sth = $c->prepare ('select count (*) from $tables:: goods
where id in ($invalue) and isgoods=? and cost>? order by cost');
$c->execute ($sth,1,0);
} else {
$sth = $c->prepare ('select count (*) from $tables:: goods
where name like? and isgoods=? and cost>? order by cost');
$c->execute ($sth,'%$str%',1,0);
}
my $count = $sth->fetchrow_array;
my $url;
if ($from > 0) {
my $from1 = $from - $max:: goodsperpage;
if ($from1 < 0) {
$from1 = 0;
}
$url ='<a href='? cmd=search&from='. ($from1). '&str=$str&artikul=$artikul'>
<img src='img/back. gif' width='16' height='16' border='0' align='middle'> Назад</a>';
}
if ($from + $max:: goodsperpage < $count) {
if ($url) {
$url. = ' | ';
}
$url. = ' <a href='? cmd=search&from='. ($from+$max:: goodsperpage). '&str=$str&artikul=$artikul'>
Вперед <img src='img/go. gif' width='16' height='16' border='0' align='middle'></a>';
}
$page->replaceContent ('nextprevurl',$url);
my $to = $from + $max:: goodsperpage;
if ($to > $count) {
$to = $count;
}
$parent = 'Поиск: $str1 Найдено товаров: $count Показаны:'. ($from+1).' - $to';
$page->replaceContent ('parent','$parent');
$sth = 0;
if ($artikul) {
$sth = $c->prepare ('select name,cost,oldcost, id,seller,pid from $tables:: goods
where id in ($invalue) and isgoods=? and cost>? order by cost limit?,?');
$c->execute ($sth,1,0,$from,$max:: goodsperpage);
} else {
$sth = $c->prepare ('select name,cost,oldcost, id,seller,pid from $tables:: goods
where name like? and isgoods=? and cost>? order by cost limit?,?');
$c->execute ($sth,'%$str%',1,0,$from,$max:: goodsperpage);
}
} else {
if ($pid) {
$parent = getParentName ($pid,$seller);
$page->replaceContent ('parent','$parent');
$sth = $c->prepare ('select name,cost,oldcost, id,seller,pid from $tables:: goods
where pid=? and seller=? and isgoods=? and cost>?
order by cost');
$c->execute ($sth,$pid,$seller,1,0);
}
}
$page->replaceContent ('pid', $pid);
$page->replaceContent ('seller', $seller);
if ($sth) {
while (my ($name,$cost,$oldcost,$id,$seller_,$pid_) = $sth->fetchrow_array) {
if ($oldcost > 0) {
if ($cost > $oldcost) {
$img = '<img src='img/up. gif' width='10' height='10' title='$oldcost'>';
} elsif ($cost < $oldcost) {
$img = '<img src='img/down. gif' width='10' height='10' title='$oldcost'>';
}
} else {
$img = '';
}
$p = $parent;
$count++;
if (! ($count & 1)) {
$class = 'even';
} else {
$class='';
}
if ($seller_ eq 'o') {
$url = $name;
$url =~ s/\'/'/;
$url =~ s/< /</;
$url =~ s/> />/;
$url =~ s/. +' //;
$url =~ s/,. + //;
#$url =~ s/'/" /;
$url = 'http://www.oldi.ru/catalog/search. php? str=$url';
} else {
$url = 'http://www.nix.ru/dealers/includes/find_by_label.html? id=$id'
}
push @out, {
urlinfo => $url,
name => $name,
cost => $cost,
class=> $class,
oldcost=>$img,
id=>'$seller_$id',
idshow=>'$id',
addgoods=>'javascript: window. parent. addGoods ($id,$pid_,'$seller_',1)',
addgoods2=>'javascript: window. parent. addGoods2 ($id,$pid_,'$seller_')',
};
}
if (! $c->{uid}) {
$page->clearLoopTags ('useronly');
}
$page->replaceLoopContent ('goodsloop', @out);
} else {
$page->clearLoopTags ();
}
my $elapsed = tv_interval ($t0, [gettimeofday]);
my $script. = 'window. parent. document. getElementById ('infoelapsedtime'). innerHTML = '$elapsed'; n';
$script. = 'window. parent. document. getElementById ('infoqueries'). innerHTML = '$c->{queries}'; n';
$page->replaceContent ('script',$script);
$page->clearAllTags ();
$page->print ();
}
sub getSubDivCount {
my $pid = shift;
my $seller = shift;
my $sth;
my $count = 0;
$sth = $c->prepare ('select count (*) from $tables:: goods where pid=? and seller=? and isgoods=?');
$c->execute ($sth,$pid,$seller,0);
$count = $sth->fetchrow_array;
return $count;
}
sub getParentName {
my $pid = shift;
my $seller = shift;
my $sth;
my $parentname;
$sth = $c->prepare ('select name,pid, id from $tables:: goods where id=? and seller=? and isgoods=?');
$c->execute ($sth,$pid,$seller,0);
my ($name,$pid1,$id) = $sth->fetchrow_array;
$name =~ s/\'/'/;
$name =~ s/\'/'/;
if (! $pid1) {
return $name;
} else {
$parentname = $name;
my ($parname,$parid) = getParentName ($pid1,$seller);
$parentname = '$parname » $parentname';
return $parentname;
}
}
sub getGoodsCount {
my $pid = shift;
my $seller = shift;
my $sth;
my $count = 0;
$sth = $c->prepare ('select count (*) from $tables:: goods where pid=? and seller=? and isgoods=? and cost>?');
$c->execute ($sth,$pid,$seller,1,0);
$count = $sth->fetchrow_array;
return $count;
}
sub showTreeByID {
my $t0 = [gettimeofday];
my $pid = shift;
my $seller = shift;
my $sth;
my $tree_items = 'parent. t. removeChilds ('$pid', false); n';
my $page = new template ('$paths:: root/showtree. htm','ALL');
my $goodsurl;
my $goodscount;
if ( (substr ($pid,0,1) eq 'o' || substr ($pid,0,1)) && length ($pid) > 1) {
$pid = substr ($pid,1,length ($pid) - 1);
}
my $pid1 = $pid;
if ( ($pid + 1) == 1) {
$pid = 0;
}
if (length ($pid1) > 1) {
$pid1= '$seller$pid1';
}
$sth = $c->prepare ('Select id,name from $tables:: goods where pid=? and seller=? and isgoods=?');
$c->execute ($sth,$pid,$seller,0);
while (my ($id,$name) = $sth->fetchrow_array) {
if ($goodscount = getGoodsCount ($id,$seller)) {
#$goodsurl = '? cmd=showgoods&pid=$id';
$goodsurl = ''javascript: showGoods ($id,'$seller') '';
$goodscount = ' ($goodscount)';
} else {
$goodsurl = '''';
$goodscount = '';
}
if (getSubDivCount ($id,$seller)) {
$tree_items. = 'parent. t. add ('$seller$id','$pid1','$name $goodscount', $goodsurl, '',false,false,'$seller'); n';
$tree_items. = 'parent. t. add ('C$seller$id','$seller$id','Загрузка. ','','',false); n';
} else {
if ($goodscount) {
$tree_items. = 'parent. t. add ('$seller$id','$pid1','$name $goodscount', $goodsurl, ''); n';
}
}
}
my $elapsed = tv_interval ($t0, [gettimeofday]);
$tree_items. = 'window. parent. document. getElementById ('infoelapsedtime'). innerHTML = '$elapsed'; n';
$tree_items. = 'window. parent. document. getElementById ('infoqueries'). innerHTML = '$c->{queries}'; n';
$tree_items. = 'parent. t. reloadNode ('$pid1'); n';
$tree_items. = 'var nd = parent. t. getNodeById ('$pid1'); n';
$tree_items. = 'nd. xtra =''; n';
$page->replaceContent ('script',$tree_items);
$page->clearAllTags ();
$page->print ();
}
sub showtree {
my $seller = $c->{cgi}->param ('seller');
my $pid = $c->{cgi}->param ('pid');
if ($seller) {
showTreeByID ($pid,$seller);
} else {
my $page = new template ('$paths:: root/showtree. htm','ALL');
$page->replaceContent ('script',' // NULL');
$page->clearAllTags ();
$page->print ();
}
}
sub home {
my $page = new template ('$paths:: root/stoik_goods. htm');
my $prdate = getSettings ($settings:: pricedate);
$page->replaceContent ('pricedate', '$prdate');
$mainpage->replaceContent ('data', $page->getContent ());
CreateSellerTree ();
}
sub upload {
my $param = shift || return;
my $outputfile = shift || return;
my $inputfile = $c->{cgi}->param ($param);
my $bytesread;
my $buffer;
my $sizefile = 0;
open (OUTFILE,'>$outputfile');
binmode (OUTFILE);
binmode ($inputfile);
while ($bytesread = read ($inputfile,$buffer,1024)) {
$sizefile += $bytesread;
print OUTFILE $buffer;
}
close (OUTFILE);
close ($inputfile);
goadmin ('Файл $outputfile загружен (размер = $sizefile)');
}
sub upload_price {
my $oldi = $c->{cgi}->param ('upload_oldi');
my $nix = $c->{cgi}->param ('upload_nix');
my $stoik = $c->{cgi}->param ('upload_stoik');
my $file;
if ($oldi) {
$file = $files:: oldi_file;
} elsif ($nix) {
$file = $files:: nix_file;
} elsif ($stoik) {
$file = $files:: stoik_file;
}
upload ('file',$file);
}
sub admin_set_info {
my $info = shift;
$mainpage->replaceContent ('info', $info);
}
sub admin_set_status {
my $info = shift;
$mainpage->replaceContent ('status', $info);
}
sub goadmin {
my $info = shift;
my $page = new template ('$paths:: root/admin_go. htm');
my $print = getSettings ($settings:: printcount);
$page->replaceContent ('printcount', $print);
$mainpage->replaceContent ('data', $page->getContent ());
admin_set_status ($info);
}
sub ClearSessions {
my $sth;
$sth = $c->prepare ('delete from $tables:: sessions where UNIX_TIMESTAMP () - UNIX_TIMESTAMP (accessdate) >?');
$c->execute ($sth,$max:: sessionlength*60);
}
sub admin {
if ($c->{admin}) {
ClearSessions ();
my $page = new template ('$paths:: root/admin. htm');
$mainpage->replaceContent ('data', $page->getContent ());
my $cmd2 = $c->{cgi}->param ('cmd2') || 'goadmin';
my %func;
$func{'upload_price'} = &upload_price;
$func{'load_price'} = &load_price;
$func{'goadmin'} = &goadmin;
$func{$cmd2}-> ();
}
}
sub addGoods {
my $pid = shift;
my $list_ref = shift;
my $count;
my $sth;
$list_ref-> [3] =~ s/,/. /;
$sth = $c->prepare ('update $tables:: oldi set pid=?,name=?,cost=?, isGoods=1 where id=?');
$count = $c->execute ($sth,$pid,$list_ref-> [2],$list_ref-> [3],$list_ref-> [1]);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: oldi (id,pid,name,cost, isGoods) values (?,?,?,?,1)');
$c->execute ($sth,$list_ref-> [1],$pid,$list_ref-> [2],$list_ref-> [3]);
}
}
sub addSubDiv {
my $pid = shift;
my $list_ref = shift;
my $count;
my $sth;
$sth = $c->prepare ('update $tables:: oldi set pid=?,name=? where id=?');
$count = $c->execute ($sth,$pid,$list_ref-> [2],$list_ref-> [1]);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: oldi (id,pid,name) values (?,?,?)');
$c->execute ($sth,$list_ref-> [1],$pid,$list_ref-> [2]);
}
}
sub addDiv {
my $list_ref = shift;
my $count;
my $sth;
$sth = $c->prepare ('update $tables:: oldi set name=? where id=?');
$count = $c->execute ($sth,$list_ref-> [2],$list_ref-> [1]);
if (! $count || $count eq '0E0') {
$c->prepare ('insert into $tables:: oldi (id,name) values (?,?)');
$c->execute ($list_ref-> [1],$list_ref-> [2]);
}
}
sub addItem {
my $seller = shift;
my $list_ref = shift;
my $sth;
my $count;
# isGood|ID|PID|NAME|PRICE
# 0 |1 |2 |3 |4
my ($isgoods,$id,$pid,$name,$cost);
($isgoods,$id,$pid,$name,$cost) = @$list_ref;
if ($isgoods) {
$sth = $c->prepare ('update $tables:: goods set name=?,cost=? where id=? and pid=? and seller=?');
$count = $c->execute ($sth,$name,$cost,$id,$pid,$seller);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: goods (id,pid,name,cost, isGoods,seller) values (?,?,?,?,?,?)');
$c->execute ($sth,$id,$pid,$name,$cost,$isgoods,$seller);
}
} else {
$sth = $c->prepare ('update $tables:: goods set name=?,cost=?,pid=? where id=? and seller=? and pid=?');
$count = $c->execute ($sth,$name,$cost,$pid,$id,$seller,$pid);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: goods (id,pid,name,cost, isGoods,seller) values (?,?,?,?,?,?)');
$c->execute ($sth,$id,$pid,$name,$cost,$isgoods,$seller);
}
}
}
sub load_price {
my $mseller = shift;
my $line;
my @lines;
my @list;
my $from = $c->{cgi}->param ('start') || 0;
my $begintime = time;
my $endtime;
my $seller;
my $file;
my $sth;
if ($c->{cgi}->param ('load_oldi') || $c->{cgi}->param ('seller') eq 'o' || $mseller eq 'o') {
$seller = 'o';
$file = $files:: oldi_file;
} elsif ($c->{cgi}->param ('load_nix') || $c->{cgi}->param ('seller') eq 'n' || $mseller eq 'n') {
$seller = 'n';
$file = $files:: nix_file;
} elsif ($c->{cgi}->param ('load_stoik') || $c->{cgi}->param ('seller') eq 's' || $mseller eq 's') {
$seller = 's';
$file = $files:: stoik_file;
}
open (FILE, $file) || die 'Не могу открыть $file';
@lines = <FILE>;
my $size = @lines;
my $i;
if (! $from) {
if ($seller eq 'o') {
$sth = $c->prepare ('delete from $tables:: goods where seller=?');
$c->execute ($sth,$seller);
} else {
$sth = $c->prepare ('update $tables:: goods set oldcost=cost,cost=0 where isgoods=? and cost>? and seller=?');
$c->execute ($sth,1,0,$seller);
}
}
for ($i = $from; $i < $size; $i++) {
$line = $lines [$i];
$endtime = time;
chomp ($line);
@list = split (/|/,$line);
# isGood|ID|PID|NAME|PRICE
# 0 |1 |2 |3 |4
$list [4] =~ s/,/. /;
if (! $list [4]) {
$list [4] = 0;
}
$list [3] =~ s/'/\'/;
$list [3] =~ s/</< /;
$list [3] =~ s/>/> /;
addItem ($seller,@list);
$endtime = time;
if ( ($endtime - $begintime) >= $max:: scripttime) {
$i++;
admin_set_status ('Добавлено'. ($i+1).' из $size строк<br>');
admin_set_info ('Выгрузка прайса в базу ($seller)');
$mainpage->replaceContent ('meta','<meta http-equiv='refresh' content='3;
URL=$paths:: url? cmd=admin&cmd2=load_price&start=$i&seller=$seller'');
return;
}
}
goadmin ('Добавлено $i из $size строк<br>Обработка завершена!');
}
sub CreateSellerTree {
my $tree_items = 't. add ('root',0,'Поставщики товара','','',true); n';
my $sth;
$tree_items. = 't. add ('o','root','OLDI','','',false, false, 'o'); n';
$tree_items. = 't. add ('LoadO','o','Загрузка. ','','',false); n';
$tree_items. = 't. add ('n','root','NIX','','',false, false, 'n'); n';
$tree_items. = 't. add ('LoadN','n','Загрузка. ','','',false); n';
$tree_items. = 't. add ('s','root','Стоик','','',false, false, 's'); n';
$tree_items. = 't. add ('LoadS','s','Загрузка. ','','',false); n';
$mainpage->replaceContent ('tree', $tree_items);
#$mainpage->replaceContent ('body', 'onload='CreateTree () '');
}
sub getSettings {
my $name = shift || return 0;
my $sth;
$sth = $c->prepare ('select value from $tables:: settings where name=?');
$c->execute ($sth,$name);
my $value = $sth->fetchrow_array;
return $value;
}
sub setSettings {
my $name = shift || return 0;
my $value = shift || '';
my $sth;
$sth = $c->prepare ('update $tables:: settings set value=? where name=?');
my $count = $c->execute ($sth,$value,$name);
if (! $count || $count eq '0E0') {
$sth = $c->prepare ('insert into $tables:: settings (id,name,value) values (null,?,?)');
$c->execute ($sth,$name,$value);
}
sub welcome {
my $info = shift;
my $page = new template ('$paths:: root/welcome. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub aboutus {
my $info = shift;
my $page = new template ('$paths:: root/aboutus. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub order {
my $info = shift;
my $page = new template ('$paths:: root/order. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub buy {
my $info = shift;
my $page = new template ('$paths:: root/buy. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub deliver {
my $info = shift;
my $page = new template ('$paths:: root/deliver. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub uslugi {
my $info = shift;
my $page = new template ('$paths:: root/uslugi. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub menuhow {
my $info = shift;
my $page = new template ('$paths:: root/menu_how. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub basket {
my $info = shift;
my $page = new template ('$paths:: root/myaccountgoods_frame. htm','ALL');
$page->replaceContent ('info',$info);
$page->clearAllTags ();
$page->print ();
}
sub sendmail {
my $script = shift;
my $page = new template ('$paths:: root/sendmail. htm','ALL');
my $uid = $c->{uid};
my $goodscount = getCountGoodByUser ($uid);
my $sth;
my @out;
my $sum = 0;
my $class;
my $count;
my $curdate = strftime '%d. %m. %Y', localtime;
if ($goodscount) {
$sth = $c->prepare ('select t1. id,t1. number,t1. seller,t1. gid,t1. oldname,t2. name,t2. cost from $tables:: mygoods as t1
left join goods as t2 ON t1. gid = t2. id
and t1. pid = t2. pid
and t1. seller = t2. seller
where t1. uid =?');
$c->execute ($sth,$uid);
while (my ($id_,$number_,$seller_,$gid_,$oldname_,$name_,$cost_) = $sth->fetchrow_array) {
$sum = $sum + $cost_ * $number_;
$sum = sprintf ('%.2f', $sum);
$count += 1;
if (! $name_) {
$cost_ = 0;
$number_ = 0;
$name_ = '<span class='warning'>Товар с артикулом $seller_$gid_ не найден. ($oldname_) </span>';
}
if ($count & 1) {
$class ='even';
} else {
$class ='';
}
push @out, {
npp => $count,
class => $class,
sum => sprintf ('%.2f', ($cost_ * $number_)),
name => $name_,
cost => $cost_,
number => $number_,
id=>'$seller_$gid_',
};
}
$page->replaceLoopContent ('goodsloop', @out);
} else {
$page->clearLoopTags ();
}
my $print = getSettings ($settings:: printcount);
$print++;
setSettings ($settings:: printcount,$print);
$page->replaceContent ('summa',$sum);
$page->replaceContent ('curdate',$curdate);
$page->replaceContent ('username',$c->{uname});
$page->clearAllTags ();
$page->print ();
}
}
exit (0);
daemon. pl
use LWP:: Simple;
use Archive:: Zip qw (: ERROR_CODES: CONSTANTS);
use Spreadsheet:: ParseExcel;
use Spreadsheet:: ParseExcel:: FmtUnicode;
use Net:: FTP;
use CGI:: Carp qw (carpout);
BEGIN {
use CGI:: Carp qw (carpout);
open (LOG, '>>error. log');
carpout (LOG);
}
close STDOUT;
open (STDOUT, '>>logfile. log');
STDOUT->autoflush (1);
$nixfile = 'c: nix. zip';
$nixprice = 'ftp: // ftp2. nix.ru/download/price/Nix3. ZIP';
$oldifile = 'c: oldi. zip';
$oldiprice = 'http://www.oldi.ru/price/oldipr. zip';
$extractpath = 'c: ';
$oldixls = $extractpath. 'OLDIPR. XLS';
$nixxls = $extractpath. 'NIX3. XLS';
$olditxt = $extractpath. 'oldi. txt';
$nixtxt = $extractpath. 'nix. txt';
$archive = $extractpath. 'archive. zip';
$ftphost = 'stoik.5gigs.com';
$ftpuser = 'stoi9984';
$ftppass = '111111';
$loadurl = 'http://stoik.5gigs.com/? cmd=loadprices&user=dmit&pass=777';
print '-== - Загрузка прайсов - ==-n';
print 'NIX... ';
$res = getstore ($nixprice, $nixfile);
if ($res == RC_OK) {
print 'OK n';
} else {
die 'ОШИБКАn';
}
print 'OLDI.. ';
$res = getstore ($oldiprice, $oldifile);
if ($res == RC_OK) {
print 'OKn';
} else {
die 'ОШИБКАn';
}
print '-== - Распаковка прайсов - ==-n';
$zipFile = Archive:: Zip->new ();
$status = $zipFile->read ($nixfile);
print 'NIX... ';
if ($status! = AZ_OK) {
die 'ОШИБКАn';
} else {
print 'OKn';
}
print 'OLDI.. ';
$zipFile->extractTree ('','',$extractpath);
$zipFile = Archive:: Zip->new ();
$status = $zipFile->read ($oldifile);
if ($status! = AZ_OK) {
die die 'ОШИБКАn';
} else {
print 'OKn';
}
$zipFile->extractTree ('','',$extractpath);
print '-== - Разборка прайсов - ==-n';
ParseOldi ();
ParseNix ();
#archivePrice ();
print '-== - Выгрузка прайсов - ==-n';
uploadArchive ();
print '-== - Загрузка прайсов в базу - ==-n';
LoadPrice ();
sub LoadPrice {
my $content = get ($loadurl);
}
sub uploadArchive {
my $ftp = Net:: FTP->new ($ftphost, Debug => 0) or die 'Cannot connect to some. host. name: $@';
$ftp->login ($ftpuser,$ftppass) or die 'Cannot login', $ftp->message;
$ftp->cwd ('/www') or die 'Cannot change working directory', $ftp->message;
$ftp->put ($nixtxt);
$ftp->put ($olditxt);
$ftp->quit;
}
sub archivePrice {
my $zip = Archive:: Zip->new ();
$zip->addFile ($nixtxt);
$zip->addFile ($olditxt);
$zip->writeToFileNamed ($archive);
}
sub ParseNix {
my $oExcel = new Spreadsheet:: ParseExcel;
my $oFmtR = Spreadsheet:: ParseExcel:: FmtUnicode->new (Unicode_Map => 'CP1251');
my $oBook = $oExcel->Parse ($nixxls, $oFmtR);
my ($iR, $iC, $oWkS, $oWkC);
$oWkS = $oBook->Worksheet (0);
my $kurs = $oWkS->{Cells} [3] [4] - >{Val};
my $price;
my $price1;
my $id;
my $pid;
my $name;
my $isGood;
my $parent;
my $comp;
open (FILE,'>',$nixtxt);
NEXTL: for (my $iR = 7; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow}; $iR++) {
$pid = $oWkS->{Cells} [$iR] [7] - >{Val};
$price = $oWkS->{Cells} [$iR] [3] - >{Val};
$price1 = $oWkS->{Cells} [$iR] [3] - >Value;
$comp = $oWkS->{Cells} [$iR] [5] - >Value;
$id = $oWkS->{Cells} [$iR] [0] - >{Val};
if ($comp eq 'Компьютер') {
next NEXTL;
} elsif ($price1 eq 'Дилер') {
$price = $oWkS->{Cells} [$iR] [5] - >{Val};
$price = ($price*0.15 + $price) *$kurs;
} else {
$price = $price*$kurs;
}
if ($pid) {
$parent = $pid;
$id = $parent;
$pid = 0;
$isGood = 0;
$name = $oWkS->{Cells} [$iR] [0] - >Value;
} else {
$id = $oWkS->{Cells} [$iR] [0] - >{Val};
$isGood = 1;
$pid = $parent;
$name = $oWkS->{Cells} [$iR] [1] - >Value;
}
print FILE '$isGood|$id|$pid|$name|$pricen';
}
close (FILE);
}
sub ParseOldi {
my $oExcel = new Spreadsheet:: ParseExcel;
my $oFmtR = Spreadsheet:: ParseExcel:: FmtUnicode->new (Unicode_Map => 'CP1251');
my $oBook = $oExcel->Parse ($oldixls, $oFmtR);
my ($iR, $iC, $oWkS, $oWkC);
$oWkS = $oBook->Worksheet (0);
open (FILE,'>',$olditxt);
my @parent;
$parent [0] = 0;
my $iParent;
my $isGood;
my $price;
#my $iR = $oWkS->{MinRow}
NEXTL: for (my $iR = 2; defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow}; $iR++) {
my $colId = $oWkS->{Cells} [$iR] [1];
my $colName = $oWkS->{Cells} [$iR] [2];
my $colPrice = $oWkS->{Cells} [$iR] [10];
my $colStore = $oWkS->{Cells} [$iR] [6];
my $id = $colId->Value;
my $name = $colName->Value;
my $bgcolor = $oExcel->ColorIdxToRGB ($colName->{Format}->{Fill} [1]);
my $font = $colName->{Format}->{Font};
my $store;
if ($bgcolor eq '000000') {
$iParent = 0;
$isGood = 0;
$parent [1] = $id;
} elsif ($font->{Bold} &&! $font->{Italic}) {
$iParent = 1;
$isGood = 0;
$parent [2] = $id;
} elsif ($font->{Bold} && $font->{Italic}) {
$iParent = 2;
$isGood = 0;
$parent [3] = $id;
} elsif (! $isGood) {
$isGood = 1;
$iParent = $iParent + 1;
}
if ($colStore) {
$store = $colStore->Value;
} else {
$store = 0;
}
if ($isGood &&! $store) {
next NEXTL;
}
if ($colPrice) {
$price = $colPrice->{Val};
} else {
$price = 0;
}
print FILE '$isGood|$id|$parent [$iParent] |$name|$pricen';
}
close (FILE);
}
exit (0);
common. pm
#! /usr/bin/perl
package common;
require Exporter;
our @ISA = qw (Exporter);
our @EXPORT_OK = qw ();
use strict;
use localset;
use settings;
use CGI;
use CGI:: Cookie;
use DBI;
sub new {
my $class = shift;
my ($user,$pass,$database,$host) = ($mysql:: user,$mysql:: pass,$mysql:: base,$mysql:: host);
my %attr;
my $self = {};
my %mycookie = fetch CGI:: Cookie;
$self->{dbh} = DBI->connect ('DBI: mysql: $database: $host', $user, $pass, %attr);
$self->{cgi} = new CGI;
if ($mycookie{$cookies:: name}) {
$self->{pid} = $mycookie{$cookies:: name}->value;
}
$self->{queries} = 0;
bless $self, $class;
$self->getUIDbySID ();
return $self;
}
sub getUIDbySID {
my $self = shift;
my $sid = $self->{pid};
my $sth;
if ($sid) {
$sth = $self->prepare ('select t1. uid,t2. admin,t2. name from $tables:: sessions as t1,$tables:: users as t2
where t1. id=? and t2. id=t1. uid');
$self->execute ($sth,$sid);
($self->{uid},$self->{admin},$self->{uname}) = $sth->fetchrow_array;
if (! $self->{uid}) {
$self->{uid} = 0;
$self->{uname} = 'Гость';
}
} else {
$self->{uid} = 0;
$self->{uname} = 'Гость';
}
}
sub generatePID {
my $self = shift;
my $SIDLen = 8;
my @lst = ('A'. 'Z','0'. '9');
my $sid;
$sid = time;
srand;
$sid. = $lst [rand ($#lst)] for (1. $SIDLen);
return $sid;
}
sub clearCookie {
my $self = shift;
$self->setCookie (0);
}
sub setCookie {
my $self = shift;
$self->{pid} = $self->generatePID ();
my $cookie = new CGI:: Cookie (-name=>$cookies:: name,
value=>$self->{pid},
expires => '+1h'
);
print 'Set-Cookie: $cookien';
$self->{cookie} = $cookie;
}
sub deleteAdminCookie {
my $self = shift;
my $cookie = new CGI:: Cookie (-name=>$cookies:: admin,
value=>'',
expires=>'-1d',
);
print 'Set-Cookie: $cookien';
}
sub setAdminCookie {
my $self = shift;
my $cookie = new CGI:: Cookie (-name=>$cookies:: admin,
value=>$self->generatePID (),
);
print 'Set-Cookie: $cookien';
}
sub GetMySQLErrorStr {
return $DBI:: errstr;
}
sub prepare {
my $self = shift;
my $sql = shift || return;
return $self->{dbh}->prepare ($sql);
}
sub execute {
my $self = shift;
my $sth = shift;
my @params = @_;
$self->{queries}++;
$sth->execute (@params);
}
sub do {
my $self = shift;
my $sql = shift || return;
$self->{dbh}->do ($sql);
$self->{queries}++;
}
1;
template. pm
package template;
use strict;
sub new {
my $class = shift;
my $template = shift;
my $cmd = shift || 'ONLYBODY';
my $this ={'pagecontent' => ''};
bless $this, $class;
if (defined ($template)) {
$this->parse ($template,$cmd);
}
return $this;
}
sub parse {
my $this = shift;
my $filename = shift;
my $cmd = shift || 'ONLYBODY';
if (-e $filename) {
open (FILE, $filename);
local $/;
undef $/;
my $contents = <FILE>;
if ($cmd eq 'ONLYBODY') {
$contents =~ /<body. +? > (. +) </body>/is;
$contents = $1;
}
$this->{'pagecontent'} = $contents;
close (FILE);
}
else {
print 'content-type: text/htmlnn';
print '<h3><font color=red>Error! </font>n</h3>';
print '<p>Can not find <b>$filename</b> template! ><br>n';
}
}
sub print
{
my $this = shift;
my $printContentType = shift;
my $pagelen = length ($this->{'pagecontent'});
if ($printContentType ne 'NO') {
print 'Content-type: text/htmln';
print 'Content-length: '. $pagelen. 'n' if ($printContentType ne 'NOLEN');
print 'n';
}
binmode (STDOUT);
print ($this->{'pagecontent'});
$this->{'pagecontent'}='';
}
sub replaceContent
{
my $this = shift;
my $key = shift || '';
my $value = shift;
my $startdelimiter = shift || '<!! ';
my $enddelimiter = shift || '!! >';
if (ref ($value)) {
$this->{'pagecontent'} =~ s/$startdelimiter$key$enddelimiter/$$value/gis;
} else {
$this->{'pagecontent'} =~ s/$startdelimiter$key$enddelimiter/$value/gis;
}
}
sub replaceContentHash
{
my $this = shift;
my $hash = shift;
my $startdelimiter = shift || '<!! ';
my $enddelimiter = shift || '!! >';
foreach my $key (keys (%$hash)) {
if ($key =~ s/^_ // o) {
$this->{'pagecontent'} =~ s/$startdelimiter$key$enddelimiter/HTMLescape ($hash->{'_$key'}) /ges;
} else {
$this->{'pagecontent'} =~ s/$startdelimiter$key$enddelimiter/$hash->{$key}/gs;
}
}
}
sub clearAllTags
{
my $this = shift;
my $hash = shift;
my $startdelimiter = shift || '<!! ';
my $enddelimiter = shift || '!! >';
$this->{'pagecontent'} =~ s/$startdelimiter (. +?) $enddelimiter // gs;
$this->{'pagecontent'} =~ s/$startdelimiter/ (. +?) $enddelimiter // gs;
#$startdelimiter = '<<';
#$enddelimiter = '>>';
#$this->{'pagecontent'} =~ s/$startdelimiter (. +?) $enddelimiter // gs;
}
sub clearLoopTags
{
my $this = shift;
my $name = shift ||'. +';
$name = ' ($name)';
my $startdelimiter = shift || '<!! ';
my $enddelimiter = shift || '!! >';
$this->{'pagecontent'} =~ s/$startdelimiter$name$enddelimiter (. *?) $startdelimiter/1$enddelimiter // gs;
}
sub createLoopContent
{
my $this = shift;
my $dbh = shift || return;
my $sql = shift || return;
my @list;
my $sth = $dbh->prepare ($sql);
$sth->execute;
while (my $hash_ref = $sth->fetchrow_hashref)
{
push @list, $hash_ref;
}
return @list;
}
sub replaceLoopContent
{
my $this = shift;
my @modeltext;
my $listtype = shift || '';
my $listdata = shift || goto EMPTY;
my $colums = shift || '';
my $rows_split = shift || '</tr><tr valign=top>';
my $i = $colums;
if (@$listdata) {
$this->{'pagecontent'} =~ m/<!! $listtype!! > (. *?) <!! /$listtype!! >/gis;
my $model = $1;
foreach my $item (@$listdata) {
my $line = $model;
foreach my $key (keys %$item) {
if ($key =~ s/^_ // o) {
$line =~ s/<!! $key!! >/HTMLescape ($item->{'_'. $key}) /ges;
} else {
$line =~ s/<!! $key!! >/$item->{$key}/gs;
}
}
push @modeltext,$line;
if ($colums &&! (--$i)) {
push @modeltext,$rows_split;
$i = $colums;
}
}
}
EMPTY:
$this->{'pagecontent'} =~ s/<!! $listtype!! > (. *?) <!! /$listtype!! >/join ('',@modeltext) /gies;
}
sub getContent
{
my $this = shift;
return $this->{'pagecontent'};
}
sub getContentRef
{
my $this = shift;
return $this->{'pagecontent'};
}
sub setContents
{
my $this = shift;
my $contents = shift || '';
$this->{'pagecontent'} = $contents;
}
sub getFile {
my $file_name = shift;
if (-e $file_name)
{
open (TM, $file_name);
local $/;
undef $/;
my $file_cont = <TM>;
close (TM);
return $file_cont;
}
else
{
return '<p> [<font color=red>file include error - $file_name</font>] n';
}
}
sub HTMLescape {
my $str = shift;
$str =~ s/'/" /go;
$str =~ s/</< /go;
$str =~ s/>/> /go;
return $str;
}
sub DESTROY {
my $this = shift;
}
1;
localset. pm
package paths;
$root = '/корневая_директория/html';
$url = 'http://адрес_сайта.ru'; (корневая ссылка)
package mysql;
$host = 'адрес_хоста_mysql.ru';
$pass = 'пароль_mysql';
$user = 'пользователь_mysql';
$base = 'база_mysql';
settings. pm
use localset;
package max;
$scripttime = 80000000; # время выполнения скрипта
$goodsperpage = 20;
$sessionlength = 60; #minutes
package tables;
$goods = 'goods';
$mygoods = 'ordergoods';
$users = 'users';
$sessions = 'sessions';
$settings = 'settings';
package files;
$oldi_file = $paths:: root. '/oldi. txt';
$nix_file = $paths:: root. '/nix. txt';
$stoik_file = $paths:: root. '/stoik. txt';
$archive_file = $paths:: root. '/archive. zip';
package cookies;
$name = 'STOIK_COOK';
$admin = 'STOIK_ADMIN_COOK';
package settings;
$pricedate = 'PRICEDATE';
$printcount = 'PRINTCOUNT';
1;
stoic_goods. htm
<html>
<head>
<title>Стоик - Компьютеры, комплектующие, расходные материалы. </title>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251'>
<link href='stoikcss. css' rel='stylesheet' type='text/css'>
<link href='nlstree3. css' rel='stylesheet' type='text/css'>
<!! meta!! >
</head>
<body bgcolor='#FFFFFF' text='#000000' link='#0066CC' vlink='#006699'>
<script language='JavaScript' src='nlstree. js'></script>
<script language='JavaScript' type='text/JavaScript'>
var t = new NlsTree ('Pub');
function IconSet1 (path) {
this. pnb = path+'plus. gif';
this. pb = path+'plus. gif';
this. mnb = path+'minus. gif';
this. mb = path+'minus. gif';
this. opf = path+'folderopen. gif';
this. clf = path+'folder. gif';
this. chd = path+'leaf. gif';
this. rot = path+'root. gif';
this. lnb = path+'blank. gif';
this. lb = path+'blank. gif';
this. lin = path+'blank. gif';
this. bln = path+'blank. gif';
this. toString = function () { return 'Simple Icons'; }
return this;
}
function treeExpand (id) {
var expNode = t. getNodeById (id);
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['comFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('comFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. pid. value=id;
frm. seller. value=expNode. xtra;
frm. submit ();
}
function showGoods (id,seller) {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['goodsFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('goodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. pid. value=id;
frm. seller. value=seller;
frm. submit ();
}
function addGoods (id,pid,seller,number) {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['myaccountgoodsFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('myaccountgoodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. id. value=id;
frm. pid. value=pid;
frm. seller. value=seller;
frm. number. value=number;
frm. submit ();
}
function addGoods2 (id,pid,seller) {
s = prompt ('Введите количество товара','2');
if (! isNaN (s)) {
addGoods (id,pid,seller,s);
} else {
alert (s+' - Это не число!');
}
}
function reloadInfo () {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['myaccountinfoFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('myaccountinfoFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. submit ();
}
function reloadGoods () {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['myaccountgoodsFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('myaccountgoodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. submit ();
}
function reloadGoods2 () {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['goodsFrame']. document. all.comForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('goodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms.comForm: ifrm. contentWindow. document. forms.comForm);
}
frm. submit ();
}
function CreateTree (tree) {
t. ico = new IconSet1 ('tree_img/');
t. opt. stlprf = 'tree3';
t. opt. selRow = true;
<!! tree!! >
t. opt. editable=false;
t. treeOnExpand = treeExpand;
t. render ('mytree1');
}
function GoSearch (a) {
var artikul = a;
var frm;
var str;
str = document. getElementById ('searchtext'). value;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['goodsFrame']. document. all. searchForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('goodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms. searchForm: ifrm. contentWindow. document. forms. searchForm);
}
frm. artikul. value=artikul;
frm. str. value=str;
frm. submit ();
}
function GoSearch2 (field,e) {
var keycode;
if (window. event) keycode = window. event. keyCode;
else if (e) keycode = e. which;
else return true;
if (keycode == 13)
{
GoSearch (0);
}
}
function GoSearchReload () {
var frm;
var str;
str = document. getElementById ('searchtext'). value;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames ['goodsFrame']. document. all. searchForm;
} else { // NETSCAPE/MOZILLA/FF
var ifrm = NlsGetElementById ('goodsFrame');
var frm = (ifrm. contentDocument? ifrm. contentDocument. forms. searchForm: ifrm. contentWindow. document. forms. searchForm);
}
frm. str. value=str;
frm. submit ();
}
function resizeFrame (frameid,maxHeight) {
var getFFVersion=navigator. userAgent. substring (navigator. userAgent. indexOf ('Firefox')). split ('/') [1]
var FFextraHeight=parseFloat (getFFVersion) >=0.1? 16: 0 // extra height in px to add to iframe in FireFox 1.0+ browsers
var h;
var currentfr;
currentfr = document. getElementById (frameid);
if (document. frames) {
h = document. frames (frameid). document. body. scrollHeight;
if (maxHeight > 0 && h > maxHeight) {
h = maxHeight;
}
currentfr. style. height = h;
} else {
h = currentfr. contentDocument. body. offsetHeight + FFextraHeight;
if (maxHeight > 0 && h > maxHeight) {
h = maxHeight;
}
currentfr. height = h;
}
}
function showLayer (n) {
var x=document. getElementById (n);
x. style. visibility = 'visible';
}
function closeLayer (n) {
var x=document. getElementById (n);
x. style. visibility = 'hidden';
}
function getFormByFrameName (frame,form) {
var frm;
if (document. frames) { // check if supportted. IE/OPERA
frm = document. frames (frame). document. all (form);
} else { // NETSCAPE/MOZILLA/FF
var ifrm = document. getElementById (frame);
frm = (ifrm. contentDocument? ifrm. contentDocument. getElementById (form): ifrm. contentWindow. document. getElementById (form));
}
return frm;
}
function Login () {
var frm = getFormByFrameName ('myaccountgoodsFrame','comForm');
frm. cmd. value='login';
frm. submit ();
}
function Logout () {
var frm = getFormByFrameName ('myaccountgoodsFrame','comForm');
frm. cmd. value='logout';
frm. submit ();
}
function Register () {
var frm = getFormByFrameName ('myaccountgoodsFrame','comForm');
frm. cmd. value='register';
frm. submit ();
}
function ChangePass () {
var frm = getFormByFrameName ('myaccountgoodsFrame','comForm');
frm. cmd. value='changepass';
frm. submit ();
}
function Welcome () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='welcome';
frm. submit ();
}
function Aboutus () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='aboutus';
frm. submit ();
}
function Order () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='order';
frm. submit ();
}
function Buy () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='buy';
frm. submit ();
}
function Deliver () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='deliver';
frm. submit ();
}
function Uslugi () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='uslugi';
frm. submit ();
}
function Basket () {
var frm = getFormByFrameName ('myaccountgoodsFrame','comForm');
frm. cmd. value='myaccountgoods';
frm. submit ();
}
function Sendmail () {
var frm = getFormByFrameName ('goodsFrame','comForm');
frm. cmd. value='sendmail';
frm. submit ();
}
function Admin () {
window. location. href='? cmd=admin';
}
</script>
<table>
<table width='100%' border='0' cellpadding='0' cellspacing='0'>
<tr>
<td width='201' valign='top' class='rightline'><table width='100%' border='0' cellpadding='0' cellspacing='0'>
<tr>
<td class='tblheader'><b>П</b>РАЙС<b>-</b>ЛИСТ</td>
</tr>
<tr>
<td><span class='verysmall-black'>Ассортимент и цены обновлены: <br><strong><!! pricedate!! ></strong></span></td>
</tr>
<tr>
<td height='1'><img src='img/pixel. gif'></td>
</tr>
<tr>
<td><form action='' method='get' onSubmit='javascript: return false; '>
<input name='searchtext' id='searchtext' type='text' size='25' onKeyPress='javascript: GoSearch2 (this,event); '>
<a href='#'><img src='img/find. gif' width='16' height='16' border='0' align='middle' title='Поиск по наименованию' onClick='javascript: GoSearch (0); '></a><a href='#'><img src='img/find_a. gif' width='16' height='16' border='0' align='middle' title='Поиск по артикулу' onClick='javascript: GoSearch (1); '></a>
</form>
<a href='#'></a></td>
</tr>
<tr valign='top'>
<td id='mytree1'> </td>
</tr>
<script language='JavaScript' type='text/javascript'>
CreateTree ();
</script>
<tr valign='top'>
<td class='tblheader'>Информация</td>
</tr>
<tr valign='top'>
<td><img src='img/pixel. gif'></td>
</tr>
<tr valign='top'>
<td valign='middle'><div align='center'>
<script>
document. write ('<a href='http://www.informer.ru/cgi-bin/redirect. cgi? id=172_1_1_33_39_1-0&url=http://www.rbc.ru&src_url=usd/usd_dm_cb_000066_88x61. gif' target='_blank'><img src='http://pics. rbc.ru/img/grinf/usd/usd_dm_cb_000066_88x61. gif? '+ Math. floor (100000*Math. random ()) + '' WIDTH=88 HEIGHT='61' border=0></a>');
</script>
<a href='http://www.gismeteo.ru/towns/27703. htm'><img alt='GISMETEO.ru: погода в г. Калуга' src='http://informer. gismeteo.ru/g30/27703-30. GIF' border=0 width=110 height=60></a></div><br></td>
</tr>
<tr>
<td class='tblheader'>Новости Hardware</td>
</tr>
<tr>
<td>
<script language='javascript' type='text/javascript'>
var encoding='0';
var news_link = 'http://rsslenta.ru/? event=viewrss&type=js&source_id=10196&align_text=0&font_size=6&font_text=2&feed_width=201&frame_color=000000&table_spacing=0&item_spacing=10&title_color=000000&title_bg=FFFFFF&headline_color=006699&item_color=006699&box_bg=&open_blank=1&hidefeed_title=1&feed_compact=1&max_item=10&limit_chars=150';
</script>
<script language='javascript' src='http://rsslenta.ru/js/view_rss. js'>
</script>
<noscript>
<a href='http://rsslenta.ru/visitor/syndication/id/7552'>Subscribe to RSS headline updates. </a>
</noscript>
</td>
</tr>
<tr>
<td><hr>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td><table width='100%' border='0'>
<tr>
<td height='0'></td>
<td height='0'></td>
</tr>
<tr>
<td><p align='left'><! - begin of Top100 logo - ->
<a href='http://top100. rambler.ru/home? id=1614566'><img src='http://top100-images. rambler.ru/top100/banner-88x31-rambler-blue. gif' alt='Rambler's Top100' width='88' height='31' border='0' /></a>
<! - end of Top100 logo - ->
</p></td>
<td><p align='right'><! - -Rating@Mail.ru COUNTER--><script language='JavaScript' type='text/javascript'><! - -
d=document; var a=''; a+='; r='+escape (top. document. referrer)
js=10 // --></script><script language='JavaScript1.1' type='text/javascript'><! - -
a+='; j='+navigator. javaEnabled ()
js=11 // --></script><script language='JavaScript1.2' type='text/javascript'><! - -
s=screen; a+='; s='+s. width+'*'+s. height
a+='; d='+ (s. colorDepth? s. colorDepth: s. pixelDepth)
js=12 // --></script><script language='JavaScript1.3' type='text/javascript'><! - -
js=13 // --></script><script language='JavaScript' type='text/javascript'><! - -
d. write ('<a href='http://top. mail.ru/jump? from=1590409''+
' target='_top'><img src='http://d4. c4. b8. a1. top. mail.ru/counter'+
'? id=1590409; t=211; js='+js+a+'; rand='+Math. random () +
'' alt='Рейтинг@Mail.ru''+' border='0' height='31' width='88'/></a>')
if (11<js) d. write ('<'+'! - ') // --></script><noscript><a
target='_top' href='http://top. mail.ru/jump? from=1590409'><img
src='http://d4. c4. b8. a1. top. mail.ru/counter? js=na; id=1590409; t=211'
border='0' height='31' width='88'
alt='Рейтинг@Mail.ru'/></a></noscript><script language='JavaScript' type='text/javascript'><! - -
if (11<js) d. write ('--'+'>') // --></script><! - -/COUNTER-->
</p></td>
</tr>
<tr>
<td height='0'></td>
<td height='0'></td>
</tr>
<tr>
<td><p align='left'><img src='img/counterkaluga. gif'></p></td>
<td><p align='right'><img src='img/count5kalugacity. gif'></p></td>
</tr>
</table></td>
</tr>
</table> </td>
<td valign='top'>
<iframe scrolling='no' marginwidth='0' marginheight='0' frameborder='0' id='myaccountinfoFrame' width='100%' src='<!! rooturl!! >? cmd=myaccountinfo'></iframe>
<iframe scrolling='auto' marginwidth='0' marginheight='0' frameborder='0' id='menuhowFrame' height='25' width='100%' src='<!! rooturl!! >? cmd=menuhow'></iframe>
<iframe scrolling='auto' marginwidth='0' marginheight='0' frameborder='0' id='myaccountgoodsFrame' width='100%' src='<!! rooturl!! >? cmd=myaccountgoods'></iframe>
<iframe scrolling='auto' marginwidth='0' marginheight='0' frameborder='0' id='goodsFrame' width='100%' src='<!! rooturl!! >? cmd=welcome'></iframe>
</td>
</tr>
</table>
<iframe src='<!! rooturl!! >? cmd=showtree' height='1' width='1' frameborder='0' id='comFrame'></iframe>
<form action='' method='post' name='comForm' id='comForm'>
<input name='cmd' type='hidden' id='cmd' value='reloadgoodsframe'>
</form>
<! - begin of Top100 code - ->
<script id='top100Counter' type='text/javascript' src='http://counter. rambler.ru/top100. jcn? 1614566'></script><noscript><img src='http://counter. rambler.ru/top100. cnt? 1614566' alt='' width='1' height='1' border='0'></noscript>
<! - end of Top100 code - ->
</body>
</html>