File: D:/web/hyperflight/apps/royalmaildelivery/index.asp
<%
Option Explicit
Response.Buffer = True
Response.Expires = -1
Const adCmdText = 1
Const adParamInput = 1
Const adVarChar = 200
Const adInteger = 3
Dim conn
Dim cmd
Dim rs
Dim serviceCodeFilter
Dim packageSizeFilter
Dim sortKey
Dim sortSql
serviceCodeFilter = Trim(Request.QueryString("ServiceCode") & "")
packageSizeFilter = Trim(Request.QueryString("PackageSize") & "")
sortKey = LCase(Trim(Request.QueryString("Sort") & ""))
'------------------------------------------------------------
' Validation helpers
'------------------------------------------------------------
Function IsValidServiceCode(ByVal value)
Select Case UCase(value)
Case "", "BPR1", "CRL24", "SD1", "OLA", "OTA", "OSA", "OTC"
IsValidServiceCode = True
Case Else
IsValidServiceCode = False
End Select
End Function
Function IsValidPackageSize(ByVal value)
Select Case value
Case "", "Letter", "Large Letter", "Parcel"
IsValidPackageSize = True
Case Else
IsValidPackageSize = False
End Select
End Function
Function NzDisplay(ByVal value)
If IsNull(value) Then
NzDisplay = ""
Else
NzDisplay = value
End If
End Function
Function FormatMoneyOrBlank(ByVal value)
If IsNull(value) Then
FormatMoneyOrBlank = ""
Else
FormatMoneyOrBlank = FormatNumber(CDbl(value), 2, -1, 0, -1)
End If
End Function
Function FormatDiff(ByVal oldValue, ByVal newValue)
If IsNull(oldValue) Or IsNull(newValue) Then
FormatDiff = ""
Else
FormatDiff = FormatNumber(CDbl(newValue) - CDbl(oldValue), 2, -1, 0, -1)
End If
End Function
Function HasChanged(ByVal oldValue, ByVal newValue)
If IsNull(oldValue) And IsNull(newValue) Then
HasChanged = False
ElseIf IsNull(oldValue) Xor IsNull(newValue) Then
HasChanged = True
Else
HasChanged = (CDbl(oldValue) <> CDbl(newValue))
End If
End Function
Function CellClass(ByVal oldValue, ByVal newValue)
If HasChanged(oldValue, newValue) Then
CellClass = "table-warning"
Else
CellClass = ""
End If
End Function
'------------------------------------------------------------
' Validate inputs
'------------------------------------------------------------
If Not IsValidServiceCode(serviceCodeFilter) Then serviceCodeFilter = ""
If Not IsValidPackageSize(packageSizeFilter) Then packageSizeFilter = ""
'------------------------------------------------------------
' Whitelist sort order
'------------------------------------------------------------
Select Case sortKey
Case "service"
sortSql = "x.ServiceCode, x.PackageSize, x.WeightUpToGrams"
Case "package"
sortSql = "x.PackageSize, x.WeightUpToGrams, x.ServiceCode"
Case "weight"
sortSql = "x.WeightUpToGrams, x.ServiceCode, x.PackageSize"
Case "changetype"
sortSql = "x.ChangeType, x.ServiceCode, x.PackageSize, x.WeightUpToGrams"
Case Else
sortSql = "x.ServiceCode, x.PackageSize, x.WeightUpToGrams"
sortKey = "service"
End Select
'------------------------------------------------------------
' Open connection
'------------------------------------------------------------
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DSN=MySQL_hyperflight;"
'------------------------------------------------------------
' Build parameterised query
'------------------------------------------------------------
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandType = adCmdText
cmd.CommandText = _
"SELECT " & vbCrLf & _
" x.ServiceCode, " & vbCrLf & _
" x.PackageSize, " & vbCrLf & _
" x.WeightUpToGrams, " & vbCrLf & _
" x.OldUK, x.NewUK, " & vbCrLf & _
" x.OldEZ1, x.NewEZ1, " & vbCrLf & _
" x.OldEZ2, x.NewEZ2, " & vbCrLf & _
" x.OldEZ3, x.NewEZ3, " & vbCrLf & _
" x.OldWZ1, x.NewWZ1, " & vbCrLf & _
" x.OldWZ2, x.NewWZ2, " & vbCrLf & _
" x.OldWZ3, x.NewWZ3, " & vbCrLf & _
" x.ChangeType " & vbCrLf & _
"FROM (" & vbCrLf & _
" SELECT " & vbCrLf & _
" o.ServiceCode AS ServiceCode, " & vbCrLf & _
" o.PackageSize AS PackageSize, " & vbCrLf & _
" o.WeightUpToGrams AS WeightUpToGrams, " & vbCrLf & _
" o.UK AS OldUK, n.UK AS NewUK, " & vbCrLf & _
" o.EZ1 AS OldEZ1, n.EZ1 AS NewEZ1, " & vbCrLf & _
" o.EZ2 AS OldEZ2, n.EZ2 AS NewEZ2, " & vbCrLf & _
" o.EZ3 AS OldEZ3, n.EZ3 AS NewEZ3, " & vbCrLf & _
" o.WZ1 AS OldWZ1, n.WZ1 AS NewWZ1, " & vbCrLf & _
" o.WZ2 AS OldWZ2, n.WZ2 AS NewWZ2, " & vbCrLf & _
" o.WZ3 AS OldWZ3, n.WZ3 AS NewWZ3, " & vbCrLf & _
" CASE " & vbCrLf & _
" WHEN n.ServiceCode IS NULL THEN 'Old row only' " & vbCrLf & _
" ELSE 'Price changed' " & vbCrLf & _
" END AS ChangeType " & vbCrLf & _
" FROM deliverycosts_rm_25_04 o " & vbCrLf & _
" LEFT JOIN deliverycosts_rm_26_04 n " & vbCrLf & _
" ON n.ServiceCode = o.ServiceCode " & vbCrLf & _
" AND n.PackageSize = o.PackageSize " & vbCrLf & _
" AND n.WeightUpToGrams = o.WeightUpToGrams " & vbCrLf & _
" WHERE " & vbCrLf & _
" n.ServiceCode IS NULL " & vbCrLf & _
" OR NOT (o.UK <=> n.UK) " & vbCrLf & _
" OR NOT (o.EZ1 <=> n.EZ1) " & vbCrLf & _
" OR NOT (o.EZ2 <=> n.EZ2) " & vbCrLf & _
" OR NOT (o.EZ3 <=> n.EZ3) " & vbCrLf & _
" OR NOT (o.WZ1 <=> n.WZ1) " & vbCrLf & _
" OR NOT (o.WZ2 <=> n.WZ2) " & vbCrLf & _
" OR NOT (o.WZ3 <=> n.WZ3) " & vbCrLf & _
"" & vbCrLf & _
" UNION ALL " & vbCrLf & _
"" & vbCrLf & _
" SELECT " & vbCrLf & _
" n.ServiceCode AS ServiceCode, " & vbCrLf & _
" n.PackageSize AS PackageSize, " & vbCrLf & _
" n.WeightUpToGrams AS WeightUpToGrams, " & vbCrLf & _
" o.UK AS OldUK, n.UK AS NewUK, " & vbCrLf & _
" o.EZ1 AS OldEZ1, n.EZ1 AS NewEZ1, " & vbCrLf & _
" o.EZ2 AS OldEZ2, n.EZ2 AS NewEZ2, " & vbCrLf & _
" o.EZ3 AS OldEZ3, n.EZ3 AS NewEZ3, " & vbCrLf & _
" o.WZ1 AS OldWZ1, n.WZ1 AS NewWZ1, " & vbCrLf & _
" o.WZ2 AS OldWZ2, n.WZ2 AS NewWZ2, " & vbCrLf & _
" o.WZ3 AS OldWZ3, n.WZ3 AS NewWZ3, " & vbCrLf & _
" 'New row only' AS ChangeType " & vbCrLf & _
" FROM deliverycosts_rm_26_04 n " & vbCrLf & _
" LEFT JOIN deliverycosts_rm_25_04 o " & vbCrLf & _
" ON o.ServiceCode = n.ServiceCode " & vbCrLf & _
" AND o.PackageSize = n.PackageSize " & vbCrLf & _
" AND o.WeightUpToGrams = n.WeightUpToGrams " & vbCrLf & _
" WHERE o.ServiceCode IS NULL " & vbCrLf & _
") x " & vbCrLf & _
"WHERE ( ? = '' OR x.ServiceCode = ? ) " & vbCrLf & _
" AND ( ? = '' OR x.PackageSize = ? ) " & vbCrLf & _
"ORDER BY " & sortSql
cmd.Parameters.Append cmd.CreateParameter("@pServiceCodeBlank1", adVarChar, adParamInput, 20, serviceCodeFilter)
cmd.Parameters.Append cmd.CreateParameter("@pServiceCode2", adVarChar, adParamInput, 20, serviceCodeFilter)
cmd.Parameters.Append cmd.CreateParameter("@pPackageBlank1", adVarChar, adParamInput, 20, packageSizeFilter)
cmd.Parameters.Append cmd.CreateParameter("@pPackage2", adVarChar, adParamInput, 20, packageSizeFilter)
Set rs = cmd.Execute
%>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Royal Mail Price Comparison</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
}
.table-responsive {
max-height: 75vh;
}
.sticky-header thead th {
position: sticky;
top: 0;
z-index: 2;
background: #212529;
color: #fff;
white-space: nowrap;
}
.number-cell {
text-align: right;
white-space: nowrap;
}
.small-note {
font-size: 0.875rem;
color: #6c757d;
}
.diff-positive {
color: #198754;
font-weight: 600;
}
.diff-negative {
color: #dc3545;
font-weight: 600;
}
.diff-neutral {
color: #6c757d;
}
</style>
</head>
<body>
<div class="container-fluid py-4">
<div class="row mb-3">
<div class="col-12">
<h1 class="h3 mb-1">Royal Mail Price Comparison</h1>
<div class="small-note">
Comparing <code>deliverycosts_rm_25_04</code> against <code>deliverycosts_rm_26_04</code>
</div>
</div>
</div>
<form method="get" class="card shadow-sm mb-4">
<div class="card-body">
<div class="row g-3 align-items-end">
<div class="col-sm-6 col-md-3">
<label for="ServiceCode" class="form-label">Service Code</label>
<select name="ServiceCode" id="ServiceCode" class="form-select">
<option value="">All</option>
<option value="BPR1"<% If serviceCodeFilter = "BPR1" Then Response.Write(" selected") End If %>>BPR1</option>
<option value="CRL24"<% If serviceCodeFilter = "CRL24" Then Response.Write(" selected") End If %>>CRL24</option>
<option value="SD1"<% If serviceCodeFilter = "SD1" Then Response.Write(" selected") End If %>>SD1</option>
<option value="OLA"<% If serviceCodeFilter = "OLA" Then Response.Write(" selected") End If %>>OLA</option>
<option value="OTA"<% If serviceCodeFilter = "OTA" Then Response.Write(" selected") End If %>>OTA</option>
<option value="OSA"<% If serviceCodeFilter = "OSA" Then Response.Write(" selected") End If %>>OSA</option>
<option value="OTC"<% If serviceCodeFilter = "OTC" Then Response.Write(" selected") End If %>>OTC</option>
</select>
</div>
<div class="col-sm-6 col-md-3">
<label for="PackageSize" class="form-label">Package Size</label>
<select name="PackageSize" id="PackageSize" class="form-select">
<option value="">All</option>
<option value="Letter"<% If packageSizeFilter = "Letter" Then Response.Write(" selected") End If %>>Letter</option>
<option value="Large Letter"<% If packageSizeFilter = "Large Letter" Then Response.Write(" selected") End If %>>Large Letter</option>
<option value="Parcel"<% If packageSizeFilter = "Parcel" Then Response.Write(" selected") End If %>>Parcel</option>
</select>
</div>
<div class="col-sm-6 col-md-3">
<label for="Sort" class="form-label">Sort By</label>
<select name="Sort" id="Sort" class="form-select">
<option value="service"<% If sortKey = "service" Then Response.Write(" selected") End If %>>Service / Package / Weight</option>
<option value="package"<% If sortKey = "package" Then Response.Write(" selected") End If %>>Package / Weight / Service</option>
<option value="weight"<% If sortKey = "weight" Then Response.Write(" selected") End If %>>Weight</option>
<option value="changetype"<% If sortKey = "changetype" Then Response.Write(" selected") End If %>>Change Type</option>
</select>
</div>
<div class="col-sm-6 col-md-3">
<button type="submit" class="btn btn-primary">Apply Filters</button>
<a href="delivery_costs_compare.asp" class="btn btn-outline-secondary">Reset</a>
</div>
</div>
</div>
</form>
<div class="card shadow-sm">
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm align-middle sticky-header">
<thead class="table-dark">
<tr>
<th>Service</th>
<th>Package</th>
<th class="number-cell">Weight g</th>
<th>Change Type</th>
<th class="number-cell">Old UK</th>
<th class="number-cell">New UK</th>
<th class="number-cell">Δ UK</th>
<th class="number-cell">Old EZ1</th>
<th class="number-cell">New EZ1</th>
<th class="number-cell">Δ EZ1</th>
<th class="number-cell">Old EZ2</th>
<th class="number-cell">New EZ2</th>
<th class="number-cell">Δ EZ2</th>
<th class="number-cell">Old EZ3</th>
<th class="number-cell">New EZ3</th>
<th class="number-cell">Δ EZ3</th>
<th class="number-cell">Old WZ1</th>
<th class="number-cell">New WZ1</th>
<th class="number-cell">Δ WZ1</th>
<th class="number-cell">Old WZ2</th>
<th class="number-cell">New WZ2</th>
<th class="number-cell">Δ WZ2</th>
<th class="number-cell">Old WZ3</th>
<th class="number-cell">New WZ3</th>
<th class="number-cell">Δ WZ3</th>
</tr>
</thead>
<tbody>
<%
If rs.EOF Then
%>
<tr>
<td colspan="25" class="text-center py-4 text-muted">No differences found for the selected filters.</td>
</tr>
<%
Else
Dim diffText
Do Until rs.EOF
%>
<tr>
<td><%=Server.HTMLEncode(rs("ServiceCode") & "")%></td>
<td><%=Server.HTMLEncode(rs("PackageSize") & "")%></td>
<td class="number-cell"><%=rs("WeightUpToGrams")%></td>
<td>
<%
Select Case rs("ChangeType") & ""
Case "Price changed"
Response.Write "<span class=""badge text-bg-warning"">Price changed</span>"
Case "Old row only"
Response.Write "<span class=""badge text-bg-danger"">Old row only</span>"
Case "New row only"
Response.Write "<span class=""badge text-bg-success"">New row only</span>"
Case Else
Response.Write Server.HTMLEncode(rs("ChangeType") & "")
End Select
%>
</td>
<td class="number-cell <%=CellClass(rs("OldUK"), rs("NewUK"))%>"><%=FormatMoneyOrBlank(rs("OldUK"))%></td>
<td class="number-cell <%=CellClass(rs("OldUK"), rs("NewUK"))%>"><%=FormatMoneyOrBlank(rs("NewUK"))%></td>
<td class="number-cell <%=CellClass(rs("OldUK"), rs("NewUK"))%>">
<%
diffText = FormatDiff(rs("OldUK"), rs("NewUK"))
If diffText <> "" Then
If CDbl(rs("NewUK")) - CDbl(rs("OldUK")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewUK")) - CDbl(rs("OldUK")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldEZ1"), rs("NewEZ1"))%>"><%=FormatMoneyOrBlank(rs("OldEZ1"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ1"), rs("NewEZ1"))%>"><%=FormatMoneyOrBlank(rs("NewEZ1"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ1"), rs("NewEZ1"))%>">
<%
diffText = FormatDiff(rs("OldEZ1"), rs("NewEZ1"))
If diffText <> "" Then
If CDbl(rs("NewEZ1")) - CDbl(rs("OldEZ1")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewEZ1")) - CDbl(rs("OldEZ1")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldEZ2"), rs("NewEZ2"))%>"><%=FormatMoneyOrBlank(rs("OldEZ2"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ2"), rs("NewEZ2"))%>"><%=FormatMoneyOrBlank(rs("NewEZ2"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ2"), rs("NewEZ2"))%>">
<%
diffText = FormatDiff(rs("OldEZ2"), rs("NewEZ2"))
If diffText <> "" Then
If CDbl(rs("NewEZ2")) - CDbl(rs("OldEZ2")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewEZ2")) - CDbl(rs("OldEZ2")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldEZ3"), rs("NewEZ3"))%>"><%=FormatMoneyOrBlank(rs("OldEZ3"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ3"), rs("NewEZ3"))%>"><%=FormatMoneyOrBlank(rs("NewEZ3"))%></td>
<td class="number-cell <%=CellClass(rs("OldEZ3"), rs("NewEZ3"))%>">
<%
diffText = FormatDiff(rs("OldEZ3"), rs("NewEZ3"))
If diffText <> "" Then
If CDbl(rs("NewEZ3")) - CDbl(rs("OldEZ3")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewEZ3")) - CDbl(rs("OldEZ3")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldWZ1"), rs("NewWZ1"))%>"><%=FormatMoneyOrBlank(rs("OldWZ1"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ1"), rs("NewWZ1"))%>"><%=FormatMoneyOrBlank(rs("NewWZ1"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ1"), rs("NewWZ1"))%>">
<%
diffText = FormatDiff(rs("OldWZ1"), rs("NewWZ1"))
If diffText <> "" Then
If CDbl(rs("NewWZ1")) - CDbl(rs("OldWZ1")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewWZ1")) - CDbl(rs("OldWZ1")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldWZ2"), rs("NewWZ2"))%>"><%=FormatMoneyOrBlank(rs("OldWZ2"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ2"), rs("NewWZ2"))%>"><%=FormatMoneyOrBlank(rs("NewWZ2"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ2"), rs("NewWZ2"))%>">
<%
diffText = FormatDiff(rs("OldWZ2"), rs("NewWZ2"))
If diffText <> "" Then
If CDbl(rs("NewWZ2")) - CDbl(rs("OldWZ2")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewWZ2")) - CDbl(rs("OldWZ2")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
<td class="number-cell <%=CellClass(rs("OldWZ3"), rs("NewWZ3"))%>"><%=FormatMoneyOrBlank(rs("OldWZ3"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ3"), rs("NewWZ3"))%>"><%=FormatMoneyOrBlank(rs("NewWZ3"))%></td>
<td class="number-cell <%=CellClass(rs("OldWZ3"), rs("NewWZ3"))%>">
<%
diffText = FormatDiff(rs("OldWZ3"), rs("NewWZ3"))
If diffText <> "" Then
If CDbl(rs("NewWZ3")) - CDbl(rs("OldWZ3")) > 0 Then
Response.Write "<span class=""diff-positive"">+" & diffText & "</span>"
ElseIf CDbl(rs("NewWZ3")) - CDbl(rs("OldWZ3")) < 0 Then
Response.Write "<span class=""diff-negative"">" & diffText & "</span>"
Else
Response.Write "<span class=""diff-neutral"">" & diffText & "</span>"
End If
End If
%>
</td>
</tr>
<%
rs.MoveNext
Loop
End If
%>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
<%
If Not rs Is Nothing Then
If rs.State <> 0 Then rs.Close
Set rs = Nothing
End If
Set cmd = Nothing
If Not conn Is Nothing Then
If conn.State <> 0 Then conn.Close
Set conn = Nothing
End If
%>