Глава 11. Управление информацией о налогах и стоимости доставки
Налоги и стоимость доставки - две ключевые области бизнес-логики, для управления которыми необходим удобный интерфейс. В главе 10 мы написали на Visual Basic объект СОМ, использующий информацию в базе данных для расчета налога и стоимости доставки. В этой главе мы создадим ASP-интерфейс для работы с информацией в базе данных.
Следует учитывать, что описанные в этой главе страницы ASP предназначены для управления данными на основании текущего набора бизнес-правил. Если ваш магазин поддерживает одно- и двухдневную доставку с разной стоимостью и/или несколько вариантов расчета налогов, вам придется изменить эти страницы наряду с СОМ-объектом Visual Basic.

Операции с налогами
Начнем с управления данными о налогах. В нашем магазине налог вычисляется на уровне штата. При этом необходимо иметь возможность обновления налоговой ставки для каждого штата. В рассмотренном примере налог взимается только в штатах Виржиния и Техас.
Страница ManageTax.asp строит форму, которая позволяет ввести данные о налоговых ставках всех штатов на одном экране и передать внесенные изменения в базу данных. Страница начинается со стандартных тегов и включения заголовочных файлов (см. листинг 11.1).
Листинг 11.1. ManageTax.asp
<%@ Language=VBScript %>
<!-- #Include file="include/validatecheck.asp" -->
<HTML>
<!--
ManageTax.asp - Supports managing the tax table
settings for the store.
-->
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<!-- #include file="include/navinclude.asp" -->
<!-- Таблица налоговых ставок -->
<BR><B>Update the tax tables below:</b><BR>
Текущие значения налоговых ставок загружаются хранимой процедурой sp_RetrieveTaxRates (см. листинг 11.2). Процедура загружает налоговые ставки сразу для всех штатов.
Листинг 11.2. ManageTax.asp (продолжение)
<%
' Create an ADO database connection
set dbTax = server.createobject("adodb.connection")
' Create the record set
set rsTax = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbTax.open("filedsn=WildWillieCDs")
' Execute the Retrieve Tax Rates stored
' procedure to retrieve all of the current
' tax rates.
sql = "execute sp_RetrieveTaxRates"

' Execute the statement
set rsTax = dbTax.Execute(sql)
Далее мы в цикле перебираем все полученные записи и читаем значения налоговых ставок командой Select Case (см. листинг 11.3). Каждое значение сохраняется в переменной для последующего отображения на странице.
Листинг 11.3. ManageTax.asp (продолжение)
' Loop through the tax rates.
do until rsTax.EOF
' We will retrieve the tax rate for each state
' and store it in a variable.
select case ucase(rsTax("chrState"))
case "AL"
fltAL = rsTax("fltTaxRate")
case "AK"
fltAK = rsTax("fltTaxRate")
case "AZ"
fltAZ = rsTax("fltTaxRate")
case "AR"
fltAR = rsTax("fltTaxRate")
case "CA"
fltCA = rsTax("fltTaxRate")
case "CT"
fltCT = rsTax("fltTaxRate")
case "CO"
fltCO = rsTax("fltTaxRate")
case "DC"
fltDC = rsTax("fltTaxRate")
case "DE"
fltDE = rsTax("fltTaxRate")
case "FL"
fltFL = rsTax("fltTaxRate")
case "GA"
fltGA = rsTax("fltTaxRate")
case "HI"
fltHI = rsTax("fltTaxRate")
case "ID"
fltID = rsTax("fltTaxRate")
case "IL"
fltIL = rsTax("fltTaxRate")
case "IN"
fltIN = rsTax("fltTaxRate")
case "IA"
fltIA = rsTax("fltTaxRate")
case "KS"
fltKS = rsTax("fltTaxRate")
case "KY"
fltKY = rsTax("fltTaxRate")
case "LA"
fltLA = rsTax("fltTaxRate")
case "ME"
fltME = rsTax("fltTaxRate")
case "MA"
fltMA = rsTax("fltTaxRate")
case "MD"
fltMD = rsTax("fltTaxRate")
case "MI"
fltMI = rsTax("fltTaxRate")
case "MN"
fltMN = rsTax("fltTaxRate")
case "MS"
fltMS = rsTax("fltTaxRate")
case "MO"
fltMO = rsTax("fltTaxRate")
case "MT"
fltMT = rsTax("fltTaxRate")
case "NE"
fltNE = rsTax("fltTaxRate")
case "NV"
fltNV = rsTax("fltTaxRate")
case "NH"
fltNH = rsTax("fltTaxRate")
case "NJ"
fltNJ = rsTax("fltTaxRate")
case "NM"
fltNM = rsTax("fltTaxRate")
case "NY"
fltNY = rsTax("fltTaxRate")
case "NC"
fltNC = rsTax("fltTaxRate")
case "ND"
fltND = rsTax("fltTaxRate")
case "OH"
fltOH = rsTax("fltTaxRate")
case "OK"
fltOK = rsTax("fltTaxRate")
case "OR"
fltOR = rsTax("fltTaxRate")
case "PA"
fltPA = rsTax("fltTaxRate")
case "RI"
fltRI = rsTax("fltTaxRate")
case "SC"
fltSC = rsTax("fltTaxRate")
case "SD"
fltSD = rsTax("fltTaxRate")
case "TN"
fltTN = rsTax("fltTaxRate")
case "TX"
fltTX = rsTax("fltTaxRate")
case "UT"
fltUT = rsTax("fltTaxRate")
case "VT"
fltVT = rsTax("fltTaxRate")
case "VA"
fltVA = rsTax("fltTaxRate")
case "WA"
fltWA = rsTax("fltTaxRate")
case "WY"
fltWY = rsTax("fltTaxRate")
case "WI"
fltWI = rsTax("fltTaxRate")
case "WV"
fltWV = rsTax("fltTaxRate")
end select
rsTax.movenext
Loop
В листинге 11.4 создается форма для вывода налоговых ставок всех штатов. Данные формы передаются странице UpdateTaxes.asp. Для каждого штата в таблице создается текстовое поле, позволяющее отредактировать налоговую ставку. Таблица начинается со строки заголовка.
Листинг 11.4. ManageTax.asp (продолжение)
%>
<!-- The form is created to post the changes -->
<form method="post" action="UpdateTaxes.asp">
<!-- Start the table to dispay the tax rates -->
<table cellpadding="3" cellspacing="3" border="1">
<!-- Show the header row -->
<tr>
<th>State</th><th>Rate</th>
<th>State</th><th>Rate</th>
<th>State</th><th>Rate</th>
<th>State</th><th>Rate</th>
</tr>
В таблице создаются строки для ввода налоговых ставок по каждому штату. Название штата выводится рядом с текстовым полем, содержащим налоговую ставку в этом штате. По умолчанию текстовое поле заполняется текущим значением ставки (см. листинг 11.5).
Листинг 11.5. ManageTax.asp (продолжение)
<!-- Build the first row of four tax rates. -->
<tr>
<!-- Display the Alabama symbol and the Alabama tax rate -->
<td>Alabama</td><td><input type="text" name="AL" value="<%=fltAL%>" size="5"></td>
<td>Alaska</td><td><input type="text" name="AK" value="<%=fltAK%>" size="5"></td>
<td>Arizona</td><td><input type="text" name="AZ" value="<%=fltAZ%>" size="5"></td>
<td>Arkansas</td><td><input type="text" name="AR" value="<%=fltAR%>" size="5"></td>
</tr>
<tr>
<td>California</td><td><input type="text" name="CA" value="<%=fltCA%>" size="5"></td>
<td>Connecticut</td><td><input type="text" name="CT" value="<%=fltCT%>" size="5"></td>
<td>Colorado</td><td><input type="text" name="CO" value="<%=fltCO%>" size="5"></td>
<td>District of Columbia</td><td><input type="text" name="DC" value="<%=fltDC%>" size="5"></td>
</tr>
<tr>
<td>Delaware</td><td><input type="text" name="DE" value="<%=fltDE%>" size="5"></td>
<td>Florida</td><td><input type="text" name="FL" value="<%=fltFL%>" size="5"></td>
<td>Georgia</td><td><input type="text" name="GA" value="<%=fltGA%>" size="5"></td>
<td>Hawaii</td><td><input type="text" name="HI" value="<%=fltHI%>" size="5"></td>
</tr>
<tr>
<td>Idaho</td><td><input type="text" name="ID" value="<%=fltID%>" size="5"></td>
<td>Illinois</td><td><input type="text" name="IL" value="<%=fltIL%>" size="5"></td>
<td>Indiana</td><td><input type="text" name="IN" value="<%=fltIN%>" size="5"></td>
<td>Iowa</td><td><input type="text" name="IA" value="<%=fltIA%>" size="5"></td>
</tr>
<tr>
<td>Kansas</td><td><input type="text" name="KS" value="<%=fltKS%>" size="5"></td>
<td>Kentucky</td><td><input type="text" name="KY" value="<%=fltKY%>" size="5"></td>
<td>Lousiana</td><td><input type="text" name="LA" value="<%=fltLA%>" size="5"></td>
<td>Maine</td><td><input type="text" name="ME" value="<%=fltME%>" size="5"></td>
</tr>
<tr>
<td>Massachusetts</td><td><input type="text" name="MA" value="<%=fltMA%>" size="5"></td>
<td>Maryland</td><td><input type="text" name="MD" value="<%=fltMD%>" size="5"></td>
<td>Michigan</td><td><input type="text" name="MI" value="<%=fltMI%>" size="5"></td>
<td>Minnesota</td><td><input type="text" name="MN" value="<%=fltMN%>" size="5"></td>
</tr>
<tr>
<td>Mississippi</td><td><input type="text" name="MS" value="<%=fltMS%>" size="5"></td>
<td>Missouri</td><td><input type="text" name="MO" value="<%=fltMO%>" size="5"></td>
<td>Montana</td><td><input type="text" name="MT" value="<%=fltMT%>" size="5"></td>
<td>Nebraska</td><td><input type="text" name="NE" value="<%=fltNE%>" size="5"></td>
</tr>
<tr>
<td>Nevada</td><td><input type="text" name="NV" value="<%=fltNV%>" size="5"></td>
<td>New Hampshire</td><td><input type="text" name="NH" value="<%=fltNH%>" size="5"></td>
<td>New Jersey</td><td><input type="text" name="NJ" value="<%=fltNJ%>" size="5"></td>
<td>New Mexico</td><td><input type="text" name="NM" value="<%=fltNM%>" size="5"></td>
</tr>
<tr>
<td>New York</td><td><input type="text" name="NY" value="<%=fltNY%>" size="5"></td>
<td>North Carolina</td><td><input type="text" name="NC" value="<%=fltNC%>" size="5"></td>
<td>North Dakota</td><td><input type="text" name="ND" value="<%=fltND%>" size="5"></td>
<td>Ohio</td><td><input type="text" name="OH" value="<%=fltOH%>" size="5"></td>
</tr>
<tr>
<td>Oklahoma</td><td><input type="text" name="OK" value="<%=fltOK%>" size="5"></td>
<td>Oregon</td><td><input type="text" name="OR" value="<%=fltOR%>" size="5"></td>
<td>Pennsylvania</td><td><input type="text" name="PA" value="<%=fltPA%>" size="5"></td>
<td>Rhode Island</td><td><input type="text" name="RI" value="<%=fltRI%>" size="5"></td>
</tr>
<tr>
<td>South Carolina</td><td><input type="text" name="SC" value="<%=fltSC%>" size="5"></td>
<td>South Dakota</td><td><input type="text" name="SD" value="<%=fltSD%>" size="5"></td>
<td>Tennessee</td><td><input type="text" name="TN" value="<%=fltTN%>" size="5"></td>
<td>Texas</td><td><input type="text" name="TX" value="<%=fltTX%>" size="5"></td>
</tr>
<tr>
<td>Utah</td><td><input type="text" name="UT" value="<%=fltUT%>" size="5"></td>
<td>Vermont</td><td><input type="text" name="VT" value="<%=fltVT%>" size="5"></td>
<td>Virginia</td><td><input type="text" name="VA" value="<%=fltVA%>" size="5"></td>
<td>Washington</td><td><input type="text" name="WA" value="<%=fltWA%>" size="5"></td>
</tr>
<tr>
<td>Wyoming</td><td><input type="text" name="WY" value="<%=fltWY%>" size="5"></td>
<td>Wisconsin</td><td><input type="text" name="WI" value="<%=fltWI%>" size="5"></td>
<td>West Virgnia</td><td><input type="text" name="WV" value="<%=fltWV%>" size="5"></td>
<td></td><td></td>
</tr>
Страница завершается кнопкой отправки данных формы и закрывающими тегами (см. листинг 11.6).
Листинг 11.6. ManageTax.asp (продолжение)
<tr>
<td colspan="8" align="center">
<input type="submit" value="Update Tax Table" name="Submit">
</td>
</tr>
</table>
</form>
</BODY>
</HTML>
РЕДАКТИРОВАНИЕ НАЛОГОВ
В нашем примере использован довольно громоздкий процесс построения таблицы с отдельным полем для каждого штата. Обновление данных можно было организовать и иначе. Например, на форме можно создать простой список с названиями штатов и текстовое поле для ввода налоговой ставки. Пользователь выбирает штат из списка н задает нужную ставку. Во втором варианте текстовые поля генерируются в цикле вместо того, чтобы создавать их по отдельности. Тем не менее, способ, продемонстрированный в этой главе, обладает своими преимуществами. Все поля выводятся одновременно, что упрощает операции с ними. Кроме того, вместо сокращенных обозначений выводятся полные названия штатов.

В листинге 11.7 приведен код хранимой процедуры sp_RetrieveTaxRates, которая возвращает все данные из таблицы Tax.
Листинг 11.7. Хранимая процедура sp_RetrieveTaxRates
CREATE PROCEDURE sp_RetrieveTaxRates AS
select * from tax
Переходим к непосредственному обновлению налоговых ставок в базе данных. Процесс обновления достаточно прост. Прежде всего мы загружаем из базы данных текущий список штатов при помощи той же самой хранимой процедуры (см. листинг 11.8).
Листинг 11.8. UpdateTaxes.asp
<%@ Language=VBScript %>
<%
' ****************************************************
' UpdateTaxes.asp - Handles the updates of the tax
' tables.
' ****************************************************
' Create an ADO database connection
set dbTaxUpd = server.createobject("adodb.connection")
' Create the record set
set rsTaxUpd = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbTaxUpd.open("filedsn=WildWillieCDs")
' Create an ADO database connection
set dbTax = server.createobject("adodb.connection")
' Create the record set
set rsTax = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbTax.open("filedsn=WildWillieCDs")
' Exeute the stored procedure to retrieve the
' current tax rate settings.
sql = "execute sp_RetrieveTaxRates"

' Execute the statement
set rsTax = dbTax.Execute(sql)
Затем мы перебираем записи всех штатов в базе данных и читаем соответствующие значения с формы (см. листинг 11.9). Для получения текущей налоговой ставки каждого штата используется команда Select Case, Обновление налоговых ставок производится хранимой процедурой sp_UpdateTaxRate.
Листинг 11.9. UpdateTaxes.asp
' Loop through the tax rate settings.
do until rsTax.EOF
' Do a select case to check which state we are
' going to update.
select case ucase(rsTax("chrState"))

' Check for Alabama
case "AL"
' Execute the sp_UpdateTaxRate stored procedure
' to change the tax rate setting for Alabama
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("AL") & ", " & rsTax("idState")

case "AK"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("AK") & ", " & rsTax("idState")

case "AZ"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("AZ") & ", " & rsTax("idState")

case "AR"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("AR") & ", " & rsTax("idState")

case "CA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("CA") & ", " & rsTax("idState")

case "CT"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("CT") & ", " & rsTax("idState")

case "CO"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("CO") & ", " & rsTax("idState")

case "DC"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("DC") & ", " & rsTax("idState")

case "DE"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("DE") & ", " & rsTax("idState")

case "FL"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("FL") & ", " & rsTax("idState")

case "GA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("GA") & ", " & rsTax("idState")

case "HI"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request ("HI") & ", " & rsTax("idState")

case "ID"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("ID") & ", " & rsTax("idState")

case "IL"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("IL") & ", " & rsTax("idState")

case "IN"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("IN") & ", " & rsTax("idState")

case "IA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("IA") & ", " & rsTax("idState")

case "KS"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("KS") & ", " & rsTax("idState")

case "KY"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("KY") & ", " & rsTax("idState")

case "LA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("LA") & ", " & rsTax("idState")

case "ME"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("ME") & ", " & rsTax("idState")

case "MA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MA") & ", " & rsTax("idState")

case "MD"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MD") & ", " & rsTax("idState")

case "MI"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MI") & ", " & rsTax("idState")

case "MN"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MN") & ", " & rsTax("idState")

case "MS"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MS") & ", " & rsTax("idState")

case "MO"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MO") & ", " & rsTax("idState")

case "MT"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("MT") & ", " & rsTax("idState")

case "NE"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NE") & ", " & rsTax("idState")

case "NV"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NV") & ", " & rsTax("idState")

case "NH"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NH") & ", " & rsTax("idState")

case "NJ"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NJ") & ", " & rsTax("idState")

case "NM"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NM") & ", " & rsTax("idState")

case "NY"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NY") & ", " & rsTax("idState")

case "NC"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("NC") & ", " & rsTax("idState")

case "ND"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("ND") & ", " & rsTax("idState")

case "OH"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("OH") & ", " & rsTax("idState")

case "OK"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("OK") & ", " & rsTax("idState")

case "OR"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("OR") & ", " & rsTax("idState")

case "PA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("PA") & ", " & rsTax("idState")

case "RI"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("RI") & ", " & rsTax("idState")

case "SC"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("SC") & ", " & rsTax("idState")

case "SD"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("SD") & ", " & rsTax("idState")

case "TN"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("TN") & ", " & rsTax("idState")

case "TX"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("TX") & ", " & rsTax("idState")

case "UT"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("UT") & ", " & rsTax("idState")

case "VT"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("VT") & ", " & rsTax("idState")

case "VA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("VA") & ", " & rsTax("idState")

case "WA"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("WA") & ", " & rsTax("idState")

case "WY"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("WY") & ", " & rsTax("idState")

case "WI"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("WI") & ", " & rsTax("idState")

case "WV"
dbTaxUpd.execute "execute sp_UpdateTaxRate " & _
request("WV") & ", " & rsTax("idState")
end select
' Move to the next state.
rsTax.movenext
Loop
После обновления налоговых ставок штатов пользователь возвращается на страницу ManageTax.asp для просмотра внесенных изменений (см. листинг 11.10).

Листинг 11.10. UpdateTaxes.asp
' Send the user back to the tax manager
' for a final check on the tax rate
' settings.
Response.Redirect "managetax.asp"
%>
Хранимая процедура sp_UpdateTaxRate обновляет поле fltTaxRate таблицы Tax для заданного штата (см. листинг 11.11). При вызове процедуре передаются налоговая ставка и идентификатор штата.
Листинг 11.11. Хранимая процедура sp_UpdateTaxRate
CREATE PROCEDURE sp_UpdateTaxRate
@fltTaxRate float,
@idState int
AS
update tax set fltTaxRate = @fltTaxRate
where idState = @idState
Давайте посмотрим, как работает построенный интерфейс. Страница с таблицей штатов. Обратите внимание: налоговая ставка для штатов Виржиния и Техас уже установлена. Введите новые значения для Алабамы и Аляски и передайте форму для обработки.
У Виржинии и Техаса сохранились прежние значения, а налоговые ставки Алабамы и Аляски заменились введенными величинами. Верните этим штатам нулевую ставку.

В таблице налоговая ставка Алабамы и Аляски вернулась к нулевому значению. Таким образом, построенный нами интерфейс позволяет легко управлять налогами на уровне штата.
Операции со стоимостью доставки
На следующем этапе мы займемся вычислением стоимости доставки. Страница ManageShipping.asp, с которой начинается рассмотрение этой темы, приведена в листинге 11.12.
Страница начинается с включения стандартных заголовочных файлов для проверки пользователя и создания панели ссылок, после чего открывается подключение ADO к базе данных.
Листинг 11.12. ManageShipping.asp
<%@ Language=VBScript %>
<!-- #Include file="include/validatecheck.asp" -->
<HTML>
<!--
ManageShipping.asp - Handles the listing of the
shipping rates. And, it provides functions for
deleting shipping rates and adding new ones.
-->
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<!-- #include file="include/navinclude.asp" -->
<%
' Create an ADO database connection
set dbShipping = server.createobject("adodb.connection")
' Create the record set
set rsShipping = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbShipping.open("filedsn=WildWillieCDs")
Текущие интервалы расценок на доставку загружаются из базы данных хранимой процедурой sp_GetShippingRate (см. листинг 11.13).
Листинг 11.13. ManageShipping.asp (продолжение)
' Execute the Retrieve Shipping Rates stored
' procedure to retrieve all of the current
' shipping rates.
sql = "execute sp_GetShippingRate"

' Execute the statement
set rsShipping = dbShipping.Execute(sql)
%>
В листинге 11.14 начинается форма для вывода расценок на доставку товаров. Данные формы передаются странице UpdateShipping.asp.
На форме строится таблица, в которой выводится идентификатор интервала, его нижняя граница, верхняя граница и стоимость доставки в этом интервале. Кроме того, в отдельном столбце создается ссылка для удаления интервала.
Листинг 11.14. ManageShipping.asp (продолжение)
<!-- Start the form for updating the shipping -->
<form method="post" action="UpdateShipping.asp">
<!-- Start the table to display the shipping
rates. -->
<table border="1" cellpadding="3" cellspacing="3">
<tr>
<th>ID</th>
<th>Low<BR>Quantity</th>
<th>High<BR>Quantity</th>
<th>Fee</th>
<th>Delete</th>
</tr>
В листинге 11.15 происходит циклический перебор записей расценок. При каждой итерации соответствующие значения заносятся в текстовые поля таблицы для последующего редактирования.
Имена полей объединяются с идентификаторами интервалов, что упрощает доступ к содержимому полей при обновлении данных.
Листинг 11.15. ManageShipping.asp (продолжение)
<%
' Loop through the shipping rates.
do until rsShipping.EOF
%>
<!-- Loop through the shipping rate ranges -->
<tr>
<!-- Show the quantity range id -->
<td><%=rsShipping("idQuantityRange")%></td>
<td>
<!-- Built input for the low quantity. Note that
the field name is built to include the id
of the quantity range. -->
<input type="text" name="intLow<%=rsShipping("idQuantityRange")%>"
value="<%=rsShipping("intLowQuantity")%>" size="6">
</td>
<td>
<!-- Built input for the high quantity. Note that
the field name is built to include the id
of the quantity range. -->
<input type="text" name="intHigh<%=rsShipping("idQuantityRange")%>"
value="<%=rsShipping("intHighQuantity")%>" size="6">
</td>
<td>
<!-- Built input for the fee. Note that the field
name is built to include the id of the quantity
range. -->
<input type="text" name="intFee<%=rsShipping("idQuantityRange")%>"
value="<%=rsShipping("intFee")%>" size="6">
</td>
Для удаления интервальных расценок мы создаем ссылки на страницу DeleteShipping.asp и передаем в URL идентификатор интервала (см. листинг 11.16). Затем цикл переходит к следующей записи, и все действия повторяются для новой строки таблицы.
Листинг 11.16. ManageShipping.asp (продолжение)
<td>
<!-- Build a delete link with the id of the
quantity range. -->
<a href="deleteshipping.asp?idQuantityRange=
<%=rsShipping("idQuantityRange")%>">Delete</a>
</td>
</tr>
<%
' Move to the next row.
rsShipping.MoveNext
' Loop back
Loop
%>
На этом построение формы и таблицы завершается (см. листинг 11.17). На странице рисуется горизонтальная черта, отделяющая таблицу от оставшейся части страницы.
Листинг 11.17. ManageShipping.asp (продолжение)
<!-- Build the submit button -->
<tr>
<td colspan="5" align="center">
<input type="submit" value="Submit" name="Submit">
</td>
</tr>
</table>
</form>
<BR><hr><BR>
В листинге 11.18 создается новая форма, предназначенная для создания новых интервальных расценок. Данные этой формы передаются странице AddShipping.asp. На форме создается таблица, аналогичная описанной выше, но без ссылки Delete.
Листинг 11.18. ManageShipping.asp (продолжение)
<!-- Start the form for adding new quantity ranges -->
<form method="post" action="AddShipping.asp">
<!-- Start the table -->
<table border="1" cellpadding="3" cellspacing="3">
<!-- Build the header -->
<tr>
<th>Low<BR>Quantity</th>
<th>High<BR>Quantity</th>
<th>Fee</th>
</tr>
В листинге 11.19 в таблице создаются три строки для ввода новых интервалов. Каждая строка таблицы содержит поля, определяющие интервал. В нашем примере для идентификации полей используется простая последовательная нумерация.
Листинг 11.19. ManageShipping.asp (продолжение)
<!-- Build the first new quantity option -->
<tr>
<td>
<input type="text" name="intLow1" value="" size="6">
</td>
<td>
<input type="text" name="intHigh1" value="" size="6">
</td>
<td>
<input type="text" name="intFee1" value="" size="6">
</td>
</tr>
<!-- Build the second new quantity option -->
<tr>
<td>
<input type="text" name="intLow2" value="" size="6">
</td>
<td>
<input type="text" name="intHigh2" value="" size="6">
</td>
<td>
<input type="text" name="intFee2" value="" size="6">
</td>
</tr>
<!-- Build the third new quantity option -->
<tr>
<td>
<input type="text" name="intLow3" value="" size="6">
</td>
<td>
<input type="text" name="intHigh3" value="" size="6">
</td>
<td>
<input type="text" name="intFee3" value="" size="6">
</td>
</tr>
После кнопки Submit, передающей новые данные для дальнейшей обработки, следуют завершающие теги таблицы, формы и страницы (см. листинг 11.20).
Листинг 11.20. ManageShipping.asp (продолжение)
<!-- Build the submit button -->
<tr>
<td colspan="3" align="center"><input type="submit" value="Submit" name="Submit"></td>
</tr>
</table>
</form>
</BODY>
</HTML>
В работе страницы используется хранимая процедура sp_GetShippingRate (см. листинг 11.21), которая просто возвращает информацию обо всех интервальных расценках, определенных в базе данных.
Листинг 11.21. Хранимая процедура sp_GetShippingRate
/* Загрузка интервальных расценок доставки, используемых магазином */
CREATE PROCEDURE sp_GetShippingRate
AS
/* Выборка всех записей из таблицы Shipping */
select * from shipping
Перейдем к обновлению интервальных расценок. Эта задача решается страницей UpdateShipping.asp, приведенной в листинге 11.22.
В начале своей работы страница создает подключение ADO к базе данных. Затем хранимая процедура sp_GetShippingRate загружает текущие расценки, чтобы мы могли в цикле перебрать и обновить их.
Листинг 11.22. UpdateShipping.asp
<%@ Language=VBScript %>
<%
' ****************************************************
' UpdateShipping.asp - Handles updating the existing
' shipping rates.
' ****************************************************
' Create an ADO database connection
set dbShipUpdate = server.createobject("adodb.connection")
' Open the connection using our ODBC file DSN
dbShipUpdate.open("filedsn=WildWillieCDs")
' Create an ADO database connection
set dbShipping = server.createobject("adodb.connection")
' Create the record set
set rsShipping = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbShipping.open("filedsn=WildWillieCDs")
' Execute the sp_GetShippingRate to retrieve
' the shipping rates.
sql = "execute sp_GetShippingRate"
' Execute the statement
set rsShipping = dbShipping.Execute(sql)
Далее (см. листинг 11.23) начинается цикл перебора текущих расценок. При обращении к содержимому полей формы используется комбинация названия поля с идентификатором интервала.
Листинг 11.23. UpdateShipping.asp (продолжение)
' Loop through the shipping rates.
do until rsShipping.EOF
' Retrieve the low and high shipping quantities
' along with the shipping rate. On the
' ManageShipping.asp page, the field names are
' built with the id of the quantity range tacked
' onto the field name. We build the same naming
' here to retrieve the values.
intLow = request("intLow" & rsShipping("idQuantityRange"))
intHigh = request("intHigh" & rsShipping("idQuantityRange"))
intFee = request("intFee" & rsShipping("idQuantityRange"))
После получения параметров интервала вызывается хранимая процедура sp_UpdateShippingRate, обновляющая информацию в базе данных (см. листинг 11.24), после чего цикл переходит к следующей записи. После того как обновление информации будет завершено, пользователь возвращается на страницу ManageShipping.asp.
Листинг 11.24. UpdateShipping.asp (продолжение)
' Execute the update stored procedure to change the range.
dbShipUpdate.Execute "execute sp_UpdateShippingRate " & _
rsShipping("idQuantityRange") & ", " & _
intLow & ", " & _
intHigh & ", " & _
intFee
' Move to the next row
rsShipping.MoveNext
' Loop back
loop
' Send the user back to the shipping manager
' range.
Response.Redirect "ManageShipping.asp"
%>
Хранимой процедуре sp_UpdateShippingRate (см. листинг 11.25) передаются значения, описывающие интервал, и его идентификатор. Процедура конструирует команду SQL UPDATE, которая обновляет запись указанного интервала.
Листинг 11.25. Хранимая процедура sp_UpdateShippingRate
CREATE PROCEDURE sp_UpdateShippingRate
@idQuantityRange int,
@intLowQuantity int,
@intHighQuantity int,
@intFee int
AS
update shipping set
intLowQuantity = @intLowQuantity,
intHighQuantity = @intHighQuantity,
intFee = @intFee
where
idQuantityRange = @idQuantityRange
Перейдем к странице DeleteShipping.asp (см. листинг 11.26), удаляющей интервалы из базы. Страница создает подключение ADO и вызывает хранимую процедуру sp_DeleteShippingRate, которая удаляет соответствующую запись интервала, определяемую по значению идентификатора. Затем пользователь возвращается на страницу ManageShipping.asp.
Листинг 11.26. DeleteShipping.asp
<%@ Language=VBScript %>
<%
' ****************************************************
' DeleteShipping.asp - Handles deleting the specific
' shipping range.
' ****************************************************
' Create an ADO database connection
set dbShipping = server.createobject("adodb.connection")
' Create the record set
set rsShipping = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbShipping.open("filedsn=WildWillieCDs")
' Execute the stored procedure to delete the
' specified shipping rate.
sql = "execute sp_DeleteShippingRate " & request("idQuantityRange")

' Execute the statement
set rsShipping = dbShipping.Execute(sql)
' Send the user back to the shipping manager
Response.Redirect "ManageShipping.asp"
%>
Хранимая процедура sp_DeleteShippingRate (см. листинг 11.27) удаляет интервал с переданным идентификатором из таблицы Shipping.
Листинг 11.27. Хранимая процедура sp_DeleteShippingRate
CREATE PROCEDURE sp_DeleteShippingRate
@idQuantityRange int
AS
delete from shipping where idQuantityRange = @idQuantityRange
Остается лишь рассмотреть создание новых интервальных расценок. Задача решается страницей AddShipping.asp (см. листинг 11.28). Страница считывает содержимое полей в трех строках таблицы и проверяет внесенные изменения. В начале своей работы она открывает подключение ADO к базе данных.
Листинг 11.28. AddShipping.asp
<%@ Language=VBScript %>
<%
' Create an ADO database connection
set dbShipping = server.createobject("adodb.connection")
' Create the record set
set rsShipping = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbShipping.open("filedsn=WildWillieCDs")
Содержимое полей каждой строки сохраняется в локальных переменных (см. листинг 11.29). Затем страница проверяет, указал ли пользователь стоимость доставки в данном интервале. Если стоимость указана, выполняется хранимая процедура sp_InsertShippingRate, которая создает новую запись в базе данных. После создания новой расценки пользователь возвращается на страницу ManageShipping.asp.
Листинг 11.29. AddShipping.asp (продолжение)
intLow1 = request("intLow1")
intHigh1 = request("intHigh1")
intFee1 = request("intFee1")
if intFee1 <> "" then
dbShipping.Execute "execute sp_InsertShippingRate " & _
intLow1 & ", " & _
intHigh1 & ", " & _
intFee1
end if
intLow2 = request("intLow2")
intHigh2 = request("intHigh2")
intFee2 = request("intFee2")
if intFee2 <> "" then
dbShipping.Execute "execute sp_InsertShippingRate " & _
intLow2 & ", " & _
intHigh2 & ", " & _
intFee2
end if
intLow3 = request("intLow3")
intHigh3 = request("intHigh3")
intFee3 = request("intFee3")
if intFee3 <> "" then
dbShipping.Execute "execute sp_InsertShippingRate " & _
intLow3 & ", " & _
intHigh3 & ", " & _
intFee3
end if
Response.Redirect "ManageShipping.asp"
%>
Хранимая процедура sp_InsertShippingRate (см. листинг 11.30) создает в таблице Shipping новую запись и присваивает ее полям переданные значения - нижнюю границу, верхнюю границу и стоимость доставки в интервале.

Листинг 11.30. Хранимая процедура sp_InsertShippingRate
CREATE PROCEDURE sp_InsertShippingRate
@intLowQuantity int,
@intHighQuantity int,
@intFee int
AS
insert into shipping(intLowQuantity, intHighQuantity, intFee)
values(@intLowQuantity, @intHighQuantity, @intFee)
Все готово к тестированию нового интерфейса. Страница ManageShipping.asp с текущими значениями расценок из базы данных. Обратите внимание на ссылки удаления и обновления существующих интервалов. Таблица в нижней части страницы предназначена для ввода границ и стоимости доставки в новых интервалах.
Удалите одну из существующих расценок при помощи ссылки Delete.
Теперь попробуйте создать новый интервал. Обратите внимание: мы не пытаемся проверить, что интервалы не перекрываются или не существуют в таблице. Предполагается, что пользователь самостоятельно убедится в правильности данных каждого интервала, а также в отсутствии пропусков и перекрытий между интервалами.

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

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