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

Информация о распродажах на уровне базы данных
В таблицу Products включаются новые поля, в которых хранится цена товара при распродаже и срок ее действия. В листинге 15.1 приведены примеры команд SQL для распродажи трех видов товаров.
Листинг 15.1. Команды SQL для распродажи товаров
update products set intSalePrice = 400, dtSaleStart = getdate (), dtStartEnd = "1/1/2001" where idProduct = 1
update products set intSalePrice = 500, dtSaleStart = getdate (), dtStartEnd = "1/1/2001" where idProduct = 2
update products set intSalePrice = 600, dtSaleStart = getdate (), dtStartEnd = "1/1/2001" where idProduct = 3
В распоряжение покупателя будут предоставлены различные средства, при помощи которых он сможет получить информацию о текущих распродажах в нашем магазине. Кроме того, в управляющей программе необходимо предусмотреть возможность установки цены для распродаваемых товаров.
Чтобы наш магазин поддерживал бесплатную доставку, в таблицу Basket необходимо включить дополнительное поле intFreeShipping. По его значению можно будет определить, распространяется ли на заказ бесплатная доставка или нет.
Кроме того, в базу данных будет включена новая таблица, содержащая информацию о том, действует ли в настоящее время рекламная кампания по бесплатной доставке. Структура таблицы приведена в табл. 15.1.
Таблица 15.1. Таблица FreeShip


Поле

Описание

idFreeShip

Первичный ключ таблицы

dtStartDate

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

dtEndDate

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

Таблицы базы данных обновляются кодом SQL, приведенным в листинге 15.2.
Листинг 15.2. Обновление таблиц базы данных
ALTER TABLE dbo.Basket ADD
intFreeShipping int NULL DEFAULT(0)
CREATE TABLE dbo.FreeShip (
intFreeShip int IDENTITY (1, 1) NOT NULL,
dtStartDate datetime NULL
CONSTRAINT DF_FreeShip_dtStartDate DEFAULT (getdate()),
dtEndDate datetime NULL
CONSTRAINT DF_FreeShip_dtEndtDate DEFAULT (getdate()),
CONSTRAINT PK_FreeShip PRIMARY KEY CLUSTERED
(
intFreeShip
))
Для вывода информации о бесплатной доставке на стороне покупателя нам понадобятся примеры данных. В листинге 15.3 приведена команда SQL, создающая новую запись в таблице FreeShip.
Листинг 15.3. Запись, описывающая рекламную кампанию по бесплатной доставке
insert into FreeShip(dtStartDate, dtEndDate) values (getdate() , '2/1/2000')
Переходим к построению пользовательского интерфейса.

Построение средств для организации распродажи
Изменения в программном коде электронного магазина состоят из двух шагов: вывод информации о распродаваемых товарах в процессе покупки и изменения в процессе оформления заказа для поддержки бесплатной доставки.
Вывод информации о распродаже
Информация о распродаже должна выводиться вместе с перечнем ключевых товаров на домашней странице магазина. Впрочем, необходимо действовать осторожно - распродаваемых товаров может быть много, и полный список может не поместиться на домашней странице.
Мы будем выбирать распродаваемый товар случайным образом и выводить информацию о нем перед списком ключевых товаров. В листинге 15.4 приведен фрагмент, который вставляется в файл Default.asp непосредственно перед выводом ключевых товаров.
Страница открывает подключение к базе данных и вызывает хранимую процедуру sp_RetrieveSaleProducts для получения текущего списка распродаваемых товаров.
Листинг 15.4. Default.asp
<!-- Show the featured products for today. -->
<b>On sale Today!</b><BR><BR>
<%

' Create an ADO database connection
set dbSaleProd = server.createobject("adodb.connection")
' Create a record set
set rsSaleProd = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbSaleProd.open("filedsn=WildWillieCDs")
' Retrieve all of the current sale products
sql = "execute sp_RetrieveSaleProducts"
' Execute the SQL statement
set rsSaleProd = dbSaleProd.Execute(sql)
Если хранимая процедура вернула какие-либо записи, мы произвольно выбираем одну из них для вывода на странице (см. листинг 15.5). Хранимая процедура sp_RetrieveSaleProducts возвращает столбец, содержащий общее количество возвращаемых записей. При помощи функции VBScript RND случайным образом выбирается одна из записей, информация о которой будет выводиться на странице.
После выбора индекса мы в цикле перебираем записи полученного набора. Обнаружив нужный товар, мы получаем и выводим его параметры.
Листинг 15.5. Default.asp (продолжение)
' Ensure something is returned so it can be displayed
if not rsSaleProd.EOF then

' Seed the random number generator
randomize

' Pick a random sale product to display. Note that the first
' column returned is the count of rows.
Row = Int((rsSaleProd(0) - 1 + 1) * Rnd + 1)
' Loop to the row selected.
for N = 1 to row - 1

' Move to the next row.
rsSaleProd.MoveNext

next
' Retrieve the product information to be displayed.
chrProductName = rsSaleProd("chrProductName")
chrProductImage = rsSaleProd("chrProductImage")
dblSalePrice = rsSaleProd("intSalePrice")
idProduct = rsSaleProd("idProduct")
%>
<!-- Build the link to the product information. -->
<a href="product.asp?idProduct=<%=idProduct%>">
<img src="images/products/sm_<%=chrProductImage%>"
align="middle" border="0">
<%=chrProductName%></a>
<font color="red"><b>
- Only <%=formatcurrency(dblSalePrice/100, 2)%>
</b></font><BR><BR>
В этом фрагменте используется хранимая процедура для получения списка распродаваемых товаров (см. листинг 15.6). Прежде всего эта процедура определяет общее количество товаров, участвующих в распродаже. Это значение необходимо для случайного выбора товара на домашней странице сайта. Количество записей сохраняется в переменной, возвращаемой следующей командой SELECT.
Затем в хранимой процедуре выполняется запрос, возвращающий данные по распродаваемым товарам. В первом столбце каждой записи возвращается общее количество записей.
Листинг 15.6. Хранимая процедура sp_RetrieveSaleProducts
CREATE PROCEDURE sp_RetrieveSaleProducts AS
declare @Cnt int
select @cnt = count(*) from products where getdate() >= dtSaleStart and getdate() <= dtSaleEnd
select @Cnt, * from products where getdate() >= dtSaleStart and getdate() <= dtSaleEnd
Сведения о распродаваемом товаре выводятся под панелью ссылок, рядом с информацией о ключевых товарах. Необходимо модифицировать заголовочный файл Header.asp и включить в него программный код для отображения распродаваемого товара.
Товар, отображаемый под панелью ссылок, как и прежде, будет выбираться случайным образом. В листинге 15.7 приведен новый фрагмент, вставляемый в Header.asp перед выводом сведений о ключевых товарах.
Как и на домашней странице, мы открываем подключение к базе данных и загружаем список распродаваемых товаров. После этого страница случайным образом выбирает один товар в списке и выводит информацию о нем под панелью ссылок. Обратите внимание - информация о распродаже, как и информация о ключевых товарах, выводится на всех страницах, кроме домашней и страницы корзины.
Листинг 15.8. Header.asp
<hr>
<font size="2" color="red">Featured Products:</font>
<br><br>

<%

' Create an ADO database connection
set dbFeaturedProd = server.createobject("adodb.connection")
' Create a record set
set rsFeaturedProd = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbFeaturedProd.open("filedsn=WildWillieCDs")
' Retrieve the current featured products
sql = "execute sp_RetrieveFeaturedProducts"

' Execute the SQL statement
set rsFeaturedProd = dbFeaturedProd.Execute(sql)
' Loop through the featured products
do until rsFeaturedProd.EOF

' Retrieve the product information to be displayed.
chrProductName = rsFeaturedProd("chrProductName")
idProduct = rsFeaturedProd("idProduct")
%>
<font size="2">
<!-- Build the link to the product information. -->
<a href="product.asp?idProduct=<%=idProduct%>">
<%=chrProductName%></a>
</font><br><br>
<%
' Move to the next record set
rsFeaturedProd.MoveNext

' Loop back
Loop

end if

%>
Итак, информация об одном из товаров, участвующих в распродаже, выводится на домашней странице и под панелью ссылок. Перейдем к странице Product.asp. На этой странице необходимо вывести сниженную цену товара и реализовать дополнительную логику, чтобы в корзине сохранялась не стандартная, а сниженная цена на товар.
В начало страницы Product.asp добавляется новый фрагмент, который проверяет, действует ли в настоящее время снижение цены на товар. Если проверка дает положительный результат, сниженная цена загружается из базы; в противном случае сниженная цена инициализируется 0. Новый фрагмент приведен в листинге 15.8.
Листинг 15.8. Product.asp
' Проверить, участвует ли товар в распродаже
if now >= cdate(rsProduct("dtSaleStart")) and _
date <= cdate(rsProduct("dtSaleEnd")) then
' Прочитать сниженную цену
intSalePrice = rsProduct("intSalePrice")
else
' По умолчанию сниженная цена инициализируется в 0.
intSalePrice = 0
end if
Далее мы займемся выводом цены. На странице товара следует вывести обе цены - как исходную, так и сниженную. В листинге 15.9 мы изменяем процесс вывода цены под графическим изображением товара и проверяем, распространяется ли на товар снижение цены. В этом случае цена распродажи выводится красным шрифтом.
Листинг 15.9. Product.asp (продолжение)
<!-- Show the product price. An input quantity box is
created. Also, several hidden variables will hold
key data for adding the product to the database. -->
<TR>
<TD align="center"><B>Price:
<%=formatcurrency(intPrice/100, 2)%></b>
<!-- Check to see if the product is on sale. -->
<% if intSalePrice <> 0 then %>

<!-- Show the sale price -->
<font color="red"><b>
<BR><BR> On Sale Now for
<%=formatcurrency(intSalePrice/100, 2)%>!
</font></b>

<% end if %>

</td>
В листинге 15.10 строится текстовое поле для количества единиц товара и скрытые поля. Затем мы проверяем, участвует ли товар в распродаже, и, если участвует, в скрытое поле вместо цены товара заносим сниженную цену распродажи. В результате товар заносится в корзину по сниженной цене.
Листинг 15.10. Product.asp (продолжение)
<TD align="center">
<B>Quantity:
<input type="text" value="1" name="quantity" size="2"></b>
<input type="hidden" value="<%=idProduct%>" name="idProduct">
<input type="hidden" value="<%=chrProductName%>" name="ProductName">
<%
' Check to see if the product is on sale.
if intSalePrice = 0 then
%>
<!-- Set the hidden price to the standard price. -->
<input type="hidden" value="<%=intPrice%>" name="ProductPrice">
<%
else
%>
<!-- Set the hidden price to the sale price. -->
<input type="hidden" value="<%=intSalePrice%>" name="ProductPrice">
<%
end if
%>
</td>
</TR>
СОВЕТ
Если запас распродаваемых товаров на складе недостаточен, можно установить ограничения на количество заказываемых товаров. Например, можно разрешить покупателю приобрести за определенный период времени не более четырех единиц товара по всем распродажам. Эту информацию можно хранить в профиле покупателя.

На этом построение интерфейса управления для организации распродаж завершается. Посмотрим, как он работает на практике. На рис. 15.1 изображена домашняя страница, в которой информация о распродаваемом товаре выводится перед списком ключевых товаров.
Панель ссылок, отображаемая на странице разделов. Информация о товаре, продаваемом по сниженной цене, также выводится перед списком ключевых товаров.
Страница товара, участвующего в распродаже. Обратите внимание - сниженная цена выводится красным шрифтом под стандартной ценой товара. Попробуем включить товар в корзину.
Корзина, в которую был включен распродаваемый товар. Обратите внимание - в поле цены указана цена распродажи. Даже если вы измените количество заказанных единиц товара, цена за единицу останется постоянной вплоть до оформления заказа.
Реализация бесплатной доставки
Перейдем к реализации бесплатной доставки. Общий принцип таков: в определенные дни, зависящие от содержимого таблицы FreeShip, доставка заказанных товаров осуществляется бесплатно.
Начнем со страницы Payment.asp (см. листинг 15.11). Изменения вносятся в ту часть страницы, где вызываются функции Tax и Shipping компонента ECStoreBizLogic. В листинге 15.11 приведен новый фрагмент, начинающийся с проверки того, что количество заказанных единиц больше 0.
Прежде всего мы открываем подключение к базе данных, чтобы получить данные из таблицы FreeShip. Чтобы узнать, действует ли в настоящий момент рекламная кампания по бесплатной доставке, мы вызываем хранимую процедуру sp_CheckFreeShip.
Если результат проверки окажется положительным, функцию Shipping компонента ECStoreBizLogic вызывать не нужно. В противном случае функция вызывается, как обычно. Присваивая сеансовой переменной FreeShipping значение 1, мы тем самым показываем, что в настоящий момент действует кампания по бесплатной доставке.
Листинг 15.11. Payment.asp
' Check the quantity returned from the database
if rsBasket("quantity") > 0 then
' Create an ADO database connection
set dbFreeShip = server.createobject("adodb.connection")
' Create the record set
set rsFreeShip = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbFreeShip.open("filedsn=WildWillieCDs")
' Check to see if free shipping is in effect.
sql = "execute sp_CheckFreeShip"
' Execute the statement
set rsFreeShip = dbBasket.Execute(sql)
' Check to see if a row was returned which indicates free
' shipping is currently in effect.
if rsFreeShip.EOF then

' Call the shipping function of our component. The quantity
' is passed in and must be in a long data type format. The
' Shipping fee is returned.
Shipping = BizLogic.Shipping(clng(rsBasket("quantity")))

' Indicate free shipping is not in effect
session("FreeShipping") = 0

else

' Default the shipping to 0.
Shipping = 0
' Indicate free shipping is in effect.
session("FreeShipping") = 1
end if

else

' Redirect to the basket page since the quantity is 0
Response.Redirect("Basket.asp")

end if
Следующий фрагмент начинается с вычисления налога и итоговой стоимости заказа (см. листинг 15.12), после чего выводится сводка данных о заказе. Если доставка выполняется бесплатно, на странице выводится сообщение, уведомляющее об этом покупателя. Для привлечения внимания сообщение выводится красным жирным шрифтом.
Листинг 15.12. Payment.asp (продолжение)
' Store the shipping value in a session variable
session("Shipping") = Shipping
' Store the quantity in a session variable
session("Quantity") = rsBasket("quantity")
' Calculate the tax by calling the Tax function of
' our component. We pass in the shipping state and the
' order subtotal. The value is also stored in a session
' variable.
Tax = BizLogic.tax(session("chrShipState"), clng(subtotal))
session("Tax") = Tax
' Calculate the total and store in a session variable.
Total = SubTotal + Shipping + Tax
session("Total") = Total
%>
<HTML>
<!-- #include file="include/header.asp" -->
<BR>
<center>
<font size="5"><b>Billing Information</b></font>
</center>
<BR>
<b>Order Recap:</b>
<BR><BR>
<!-- Build a table to display the order total -->
<table>
<!-- Display the Subtotal -->
<tr>
<td align="right">Subtotal:</td>
<td><%=formatcurrency(Subtotal/100, 2)%></td>
</tr>
<!-- Display the Shipping Value -->
<tr>
<td align="right">

<!-- Check to see if Free Shipping is in effect. -->
<% if session("FreeShipping") = 0 then %>
<!-- Indicate standard shipping -->
Shipping:
<% else %>
<!-- Indicate free shipping -->
<font color="red"><b>
Free Shipping Today!
</b></font>
<% end if %>

</td>
<td><%=formatcurrency(Shipping/100, 2)%></td>
</tr>
Хранимая процедура sp_CheckFreeShip (см. листинг 15.13) проверяет, действует ли в настоящее время рекламная кампания по бесплатной доставке. Для этого даты начала и завершения кампании сравниваются с текущей системной датой, полученной при помощи функции GetDateC).

Листинг 15.13. Хранимая процедура sp_CheckFreeShip
CREATE PROCEDURE sp_CheckFreeShip
AS
select * from FreeShip where getdate() >= dtStartDate and getdate() <= dtEndDate
На этом все вычисления и операции вывода, связанные с бесплатной доставкой, завершаются. Всем сеансовым переменным присваиваются значения, которые будут сохранены в базе данных. Информация о бесплатной доставке сохраняется наряду с остальными данными.
В листинге 15.14 приведен новый фрагмент кода страницы ValidatePayment.asp. Обновляется код, сохраняющий вычисленные значения в корзине. Хранимая процедура sp_UpdateBasket модифицируется таким образом, чтобы ей передавался дополнительный параметр FreeShipping. Обратите внимание: при бесплатной доставке сеансовой переменной Shipping присваивается 0.
Листинг 15.14. ValidatePayment.asp
'***********************************************
'**** 6. Update the basket with the final
'**** order data.
'***********************************************

' Finally we need to update the basket with the final
' amounts for quantity, subtotal, shipping, tax and
' total
sql = "execute sp_UpdateBasket " & _
session("idBasket") & ", " & _
session("Quantity") & ", " & _
session("Subtotal") & ", " & _
session("Shipping") & ", " & _
session("FreeShipping") & ", " & _
session("Tax") & ", " & _
session("Total") & ", 1"
Как упоминалось выше, хранимую процедуру sp_UpdateBasket также необходимо модифицировать для того, чтобы ей передавался признак бесплатной доставки (см. листинг 15.15). Новый параметр присваивается полю intFreeShipping и сохраняется в базе командой UPDATE.
Листинг 15.15. Хранимая процедура sp_UpdateBasket
/* Обновление содержимого корзины */
CREATE PROCEDURE sp_UpdateBasket
/* При вызове процедуре передается идентификатор корзины, количество единиц товара, общая стоимость заказа, стоимость доставки, признак бесплатной доставки, налог, итоговая стоимость и признак размещения заказа. */
@idBasket int,
@intQuantity int,
@intSubTotal int,
@intShipping int,
@intFreeShipping int,
@intTax int,
@intTotal int,
@intOrderPlaced int
AS
/* Обновление корзины */
update basket set
intQuantity = @intQuantity,
intSubtotal = @intSubtotal,
intShipping = @intShipping,
intFreeShipping = @intFreeShipping, intTax = @intTax,
intTotal = @intTotal,
intOrderPlaced = @intOrderPlaced
where idBasket = @idBasket
СОВЕТ
Существуют и другие способы снижения стоимости доставки. Например, можно организовать бесплатную доставку заказов, у которых общая стоимость превышает некоторое пороговое значение, или обеспечить бесплатную доставку каждого третьего заказа. Все эти рекламные средства играют важную роль в привлечении покупателей.

Проверим, как работают средства бесплатной доставки. Не забудьте создать в таблице FreeShip запись, у которой текущая дата входит в интервал дат рекламной кампании.
Перейдите к оформлению заказа. Проверьте состояние заказа и убедитесь в том, что информация о бесплатной доставке сохранилась в базе данных.
Построение интерфейса для управления распродажами
Познакомившись с работой пользовательского интерфейса, мы переходим к рассмотрению административных средств, предназначенных для организации распродаж и управления бесплатной доставкой товара.
Сразу же после кода управления ключевыми товарами, включенного в страницу ManageProduct.asp, будет добавлен аналогичный код для организации распродаж. Нам понадобятся текстовые поля для редактирования цены, начальной и конечной даты. В таблице создается новая строка с текстовыми элементами для редактирования полей базы данных intSalePrice, dtSaleStart и dtSaleEnd.
Листинг 15.16. ManageProduct.asp
<!-- Параметры рекламных кампаний по распродаже. -->
<tr>
<td align="right"><b>Sale Price:</b></td>
<td>

<!-- Текстовое поле для цены распродажи. -->
<input type="text" value="<%=intSalePrice/100%>"
name="intSalePrice" size="10">
<!-- Текстовые поля для дат начала и конца рекламной кампании. -->
Start Date: <input type="text" value="<%=dtSaleStart%>"
size="10" name="dtSaleStart">
End Date: <input type="text" value="<%=dtSaleEnd%>"
size="10" name="dtSaleEnd">

</td>
</tr>
В страницу UpdateProduct.asp вносятся изменения, связанные с получением новых данных и обновлением базы. Изменения в коде страницы приведены в листинге 15.17. Необходимые значения читаются из переменных формы.
Хранимая процедура sp_UpdateProduct также должна получать параметры, связанные с распродажей. Ей передаются значения, полученные из формы.
Листинг 15.17. UpdateProduct.asp
' Retrieve the sale price and start and end
' date for the sale price campaign.
intSalePrice = request("intSalePrice") * 100
dtSaleStart = request("dtSaleStart")
dtSaleEnd = request("dtSaleEnd")
' Create an ADO database connection
set dbProduct = server.createobject("adodb.connection")
' Create the record set
set rsProduct = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbProduct.open("filedsn=WildWillieCDs")
' Execute the SQL stored procedure to update the
' product data
sql = "execute sp_UpdateProduct " & _
request("idProduct") & ", '" & _
chrProductName & "', '" & _
txtDescription & "', '" & _
chrProductImage & "', " & _
intPrice & ", " & _
intActive & ", " & _
intFeatured & ", '" & _
dtFeatureStart & "', '" & _
dtFeatureEnd & "', " & _
intSalePrice & ", '" & _
dtSaleStart & "', '" & _
dtSaleEnd & "'"
' Execute the statement
set rsProduct = dbProduct.Execute(sql)
' Send the user back to the product manager page and
' pass back the product i.
Response.Redirect "ManageProduct.asp?idProduct=" & _
request("idProduct")
В листинге 15.18 приведен новый вариант хранимой процедуры sp_UpdateProduct. Для каждого из полей, связанных с распродажей, процедуре передается новый параметр. Команда UPDATE присваивает переданные значения новым полям базы данных.
Листинг 15.18. Хранимая процедура sp_UpdateProduct
CREATE PROCEDURE sp_UpdateProduct
@idProduct int,
@chrProductName varchar(255),
@txtDescription text,
@chrProductImage varchar(100),
@intPrice int,
@intActive int,
@intFeatured int,
@dtFeatureStart datetime,
@dtFeatureEnd datetime,
@intSalePrice int,
@dtSaleStart datetime,
@dtSaleEnd datetime
AS
update products set
chrProductName = @chrProductName, txtDescription = @txtDescription,
chrProductImage = @chrProductImage,
intPrice = @intPrice,
intActive = @intActive,
intFeatured = @intFeatured,
dtFeatureStart = @dtFeatureStart,
dtFeatureEnd = @dtFeatureEnd,
intSalePrice = @intSalePrice,
dtSaleStart = @dtSaleStart,
dtSaleEnd = @dtSaleEnd
where
idProduct = @idProduct
Как видите, программный код для управления распродажами получился довольно простым. Страница Product.asp c новыми полями. Вы можете отредактировать содержимое этих полей и обновить сведения о товаре.
Внесите необходимые изменения и нажмите кнопку Update Product.
Тема управления распродажами на этом завершается, и мы переходим к управлению рекламными кампаниями по бесплатной доставке.
Управление рекламными кампаниями по бесплатной доставке
В настоящее время в нашем магазине не предусмотрены никакие средства управления бесплатной доставкой. Следовательно, мы должны создать дополнительную ссылку на страницах ManagerMenu.asp и Navlnclude.asp. В листингах 15.19 и 15.20 приведены новые фрагменты, которые включаются в эти страницы для создания новой ссылки.
На странице ManagerMenu.asp в таблице создается дополнительная строка, содержащая ссылку на страницу ManageFreeShipping.asp.
Листинг 15.19. ManagerMenu.asp
<tr>
<!-- Управление бесплатной доставкой -->
<td><a href="ManageFreeShipping.asp">
Manage Free Shipping</a></td>
</tr>
В листинге 15.20 на панели ссылок создается новая ссылка Manage Free Shipping, также связанная со страницей ManageFreeShipping.asp.
Листинг 15.20. NavInclude.asp
<!-- Ссылка на страницу управления бесплатной доставкой. -->
<a href="ManageFreeShipping.asp">
Manage Free Shipping</a>
В интерфейс администратора добавляется новая страница, ManageFreeShipping.asp (см. листинг 15.21), предназначенная для управления рекламными кампаниями по бесплатной доставке. Страница начинается с включения стандартных заголовочных файлов, обеспечивающих проверку пользователя и построение панели ссылок.
Листинг 15.21. ManagerFreeShipping.asp
<%@ Language=VBScript %>
<!-- #Include file="include/validatecheck.asp" -->
<HTML>
<!--
ManageFreeShipping.asp - Provides options to set the
next free shipping campaign date range.
-->
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<!-- #include file="include/navinclude.asp" -->
<BR><BR>
<B>Set free shipping campaign:
</b><BR><BR>
Продолжение приведено в листинге 15.22. Прежде всего мы открываем подключение к базе данных, чтобы прочитать текущие сроки бесплатной доставки. Загрузка данных из базы выполняется хранимой процедурой sp_RetrieveFreeShipping.
Листинг 15.22. ManagerFreeShipping.asp (продолжение)
<%
' Создать объект подключения к базе данных
set dbFreeShipping = server.createobject("adodb.connection")
' Создать объект набора записей
set rsFreeShipping = server.CreateObject("adodb.recordset")
' Открыть подключение, используя файловый DSN ODBC
dbFreeShipping.open("filedsn=WildWillieCDs")
' Хранимая процедура sp_RetrieveFreeShip возвращает текущие
' сроки рекламной кампании по бесплатной доставке.
sql = "execute sp_RetrieveFreeShip"

' Выполнить команду
set rsFreeShipping = dbFreeShipping.Execute(sql)
%>
Затем создается форма для передачи начальной и конечной даты кампании по бесплатной доставке. Форма завершается кнопкой отправки данных, после чего следуют закрывающие теги страницы (см. листинг 15.23).
Листинг 15.23. ManagerFreeShipping.asp (продолжение)
<!-- The changes will be posted to the UpdateFreeShipping.asp
page. -->
<form method="post" action="UpdateFreeShipping.asp">
<!-- Start a table to show the start and end date. -->
<table cellpadding="3" cellspacing"3">
<!-- Show the start date. -->
<tr>
<td align="right">Start Date:</td>
<td>
<input type="text" name="dtStartDate"
value="<%=rsFreeShipping("dtStartDate")%>">
</td>
</tr>
<!-- Show the end date. -->
<tr>
<td align="right">End Date:</td>
<td>
<input type="text" name="dtEndDate"
value="<%=rsFreeShipping("dtEndDate")%>">
</td>
</tr>
<!-- Show a submit button for the form -->
<tr><td align="center" colspan="2">
<input type="submit" value="Submit" name="Submit">
</td></tr>
</table>
</form>
</BODY>
</HTML>
ВНИМАНИЕ
Функции обработки дат предполагают, что в системе используется локальный контекст США, в котором даты кодируются в формате мм/дд/гг. При заполнении формы данные следует вводить именно в этом формате, в противном случае могут возникнуть непредвиденные ошибки.

Хранимая процедура sp_RetrieveFreeShip (cм. листинг 15.24) возвращает все записи в таблице. В действительности обрабатывается только первая запись, поскольку в любой момент времени может действовать лишь одна кампания по бесплатной доставке. Впрочем, при желании можно реализовать средства для создания нескольких кампаний и их планирования.
Листинг 15.24. Хранимая процедура sp_RetrieveFreeShip
CREATE PROCEDURE sp_RetrieveFreeShip AS
select * from FreeShip
Страница UpdateFreeShipping.asp (см. листинг 15.25) обновляет данные в таблице FreeShip. Сначала она открывает подключение к базе данных, после чего вызывает хранимую процедуру sp_UpdateFreeSh1p, которая вносит изменения в базу данных.
Листинг 15.25. UpdateFreeShipping.asp
<%@ Language=VBScript %>
<%
' ****************************************************
' UpdateFreeShipping.asp - Handles updating the free
' shipping campaign dates.
' ****************************************************
' Retrieve the start date
dtStartDate = request("dtStartDate")
' Retrieve the end date
dtEndDate = request("dtEndDate")
' Create an ADO database connection
set dbFreeShip = server.createobject("adodb.connection")
' Create the record set
set rsFreeShip = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbFreeShip.open("filedsn=WildWillieCDs")
' Execute the sp_UpdateFreeShip stored procedure
' to change the dates.
sql = "execute sp_UpdateFreeShip '" & _
dtStartDate & "', '" & _
dtEndDate & "'"

' Execute the statement
set rsFreeShip = dbFreeShip.Execute(sql)
' Send the user back to free shipping manager page.
Response.Redirect "ManageFreeShipping.asp"
%>
Хранимая процедура sp_UpdateFreeShip приведена в листинге 15.26. При вызове ей передаются начальная и конечная дата рекламной кампании. На этот раз обновляются все записи, существующие в таблице.
Листинг 15.26. Хранимая процедура sp_UpdateFreeShip
CREATE PROCEDURE sp_UpdateFreeShip
@dtStartDate datetime,
@dtEndDate datetime
AS
Update FreeShip set dtStartDate = @dtStartDate, dtEndDate = @dtEndDate
Также необходимо внести изменения в систему вывода отчетов о заказах. В базе данных должна храниться информация о том, что при размещении заказа действовала бесплатная доставка, и в случае обновления заказа по какой-либо причине эта информация не должна теряться.
Новый код страницы OrderDetail.asp приведен в листинге 15.27. Чтобы узнать, действует ли в настоящий момент кампания по бесплатной доставке, мы проверяем значение поля intFreeShippingB базе данных. Если оно равно 1, выводится сообщение о бесплатной доставке; в противном случае выводится стандартный текст. Кроме того, информацию о бесплатной доставке необходимо передать странице UpdateOrder.asp. Независимо от результата проверки значение сохраняется в скрытом поле на форме и передается странице UpdateOrder.asp для обработки.
Листинг 15.27. OrderDetail.asp
<!-- Show the shipping total of the basket -->
<tr>
<td colspan="5" align="right">
<!-- Check to see if we have free shipping. -->
<% if rsOrderReceiptHeader("intFreeShipping") = 1 then %>
<!-- Show that there is free shipping on this order. -->
<b><font color="red">
Free Shipping:</b></font>
<input type="hidden" value="1" name="intFreeShipping">
<% else %>
<!-- Show that there is standard shipping on this order. -->
<b>Shipping:</b>
<input type="hidden" value="0" name="intFreeShipping">
<% end if %>
</td>
<td align="right"><%Response.Write _
formatcurrency(rsOrderReceiptHeader("intShipping")/100, 2) %></td>
</tr>
Страница UpdateOrder.asp обновляет данные заказа в соответствии с изменениями, внесенными на странице OrderDetail.asp. Например, пользователь мог изменить количество единиц заказанного товара, что, в свою очередь, повлияет на общую стоимость заказа и значения вычисляемых полей.
Изменения начинаются с того места, где с формы читаются значения данных заголовка. В этом фрагменте дополнительно читается значение intFreeShipping (см. листинг 15.28).
Листинг 15.28. UpdateOrder.asp
' Next we retrieve the core order data which
' includes the billing address and shipping
' address. Note that the key fields are updated
' to ensure any single quotes are doubled.
chrBillFirstName = replace(request("chrBillFirstName"), "'", "''")
chrBillLastname = replace(request("chrBillLastName"), "'", "''")
chrShipFirstName = replace(Request("chrShipFirstName"), "'", "''")
chrShipLastname = replace(request("chrShipLastName"), "'", "''")
chrBillAddress = replace(request("chrBillAddress"), "'", "''")
chrShipAddress = replace(request("chrShipAddress"), "'", "''")
chrBillCity = replace(request("chrBillCity"), "'", "''")
chrBillState = request("chrBillState")
chrBillZipCode = request("chrBillZipCode")
chrShipCity = replace(request("chrShipCity"), "'", "''")
chrShipState = request("chrShipState")
chrShipZipCode = request("chrShipZipCode")
chrBillPhone = request("chrBillPhone")
chrShipPhone = request("chrShipPhone")
chrBillEmail = request("chrBillEmail")
chrShipEmail = request("chrShipEmail")
' Get the free shipping setting for the order.
intFreeShipping = request("intFreeShipping")
В листинге 15.29 модификация UpdateOrder.asp продолжается. Как и на странице Payment.asp, мы проверяем, действует ли в настоящее время кампания по бесплатной доставке. Если доставка осуществляется бесплатно, функция Shipping компонента ECStoreBizLogic не вызывается.
После определения стоимости доставки информация корзины обновляется вычисленными значениями. При бесплатной доставке переменная Shipping равна 0. Хранимая процедура sp_UpdateBasket сохраняет в базе все параметры корзины, включая поле intFreeShipping.
ПРИМЕЧАНИЕ
Наш тривиальный сценарий открывает немалый простор для творчества. Например, вы можете предоставить администратору возможность отменять бесплатную доставку для конкретных заказов, или хранить в базе данных информацию о нескольких рекламных кампаниях. Программа была написана так, чтобы подобные модификации можно было вносить как можно проще, и при желании вы можете реализовать эти возможности самостоятельно.

Листинг 15.29. UpdateOrder.asp (продолжение)
' Check to see if there is free shipping on the order.
if intFreeShipping = 0 then
' Create the Bussiness Logic component to
' calculate the tax and shipping.
set BizLogic = server.CreateObject("ECStoreBizLogic.TaxShip")
' Call the shipping function of our component. The quantity
' is passed in and must be in a long data type format. The
' Shipping fee is returned.
Shipping = BizLogic.Shipping(cLng(TotalQuantity))
else
' Otherwise we default the shipping total to 0.
Shipping = 0
end if
' Calculate the tax by calling the Tax function of
' our component. We pass in the shipping state and the
' order subtotal. The value is also stored in a session
' variable.
Tax = BizLogic.tax(cstr(chrShipState), clng(subtotal))
' Calculate the new total.
Total = subtotal + shipping + tax
' Build a SQL statement to update the basket data
sql = "execute sp_UpdateBasket " & _
idBasket & ", " & _
TotalQuantity & ", " & _
SubTotal & ", " & _
Shipping & ", " & _
intFreeShipping & ", " & _
Tax & ", " & _
Total & ", 1"

' Execute the SQL statement
set rsOrderUpdate = dbOrderUpdate.execute(sql)
' Send the user back to the order detail
' page
Response.Redirect "OrderDetail.asp?idOrder=" & idOrder & _
"&idShopper=" & idShopper
%>
Давайте рассмотрим работу страниц управляющего интерфейса на конкретном примере.Меню управляющей программы с новым пунктом Manage Free Shipping, предназначенным для управления бесплатной доставкой. Щелкните на этой ссылке.

Страница управления бесплатной доставкой. На ней находятся всего два поля, в которых вводится срок проведения следующей рекламной кампании.

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

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика