File: D:/web/hyperflight/inxpress/inxpress.asp
<%@LANGUAGE="VBScript" CODEPAGE="65001"%>
<% Option Explicit %>
<!-- =========================================================================================
inxpress.asp
Displays shipment data from inxpress_shipments_parsed with modal details from
inxpress_shipments. Includes join to orders for delivery charges.
⚠️ IMPORTANT:
SafeHTML() fixes ODBC memo/text bug — do not alter its val & "" conversion.
FmtNum() blanks zeros, FmtNumAlways() always shows 2 DP (for totals only).
Author: ChatGPT + Surinder Singh
Date: 2025-10-27
========================================================================================= -->
<%
Const PAGE_SIZE = 10000
Dim conn, rs, sql, whereSQL, sortField, sortDir
Dim searchText, carrierSel, invoiceSel, countrySel
Dim missingOrders, duplicateRefs
Dim totalBase, totalFuel, totalOther, totalNet, totalVAT, totalGrand
Dim totalDelivery, totalDeliveryAgent, totalDeliveryCalc
totalBase=0 : totalFuel=0 : totalOther=0 : totalNet=0
totalVAT=0 : totalGrand=0 : totalDelivery=0 : totalDeliveryAgent=0 : totalDeliveryCalc=0
' ---------------------- Connection ----------------------
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DSN=MySQL_hyperflight"
' ---------------------- Helper functions ----------------------
Function SafeHTML(val)
Dim tmp
tmp = Trim(val & "")
SafeHTML = Server.HTMLEncode(tmp)
End Function
' Format blank if 0 or null, else fixed 2 DP
Function FmtNum(val)
If IsNull(val) Or val = "" Or val = 0 Then
FmtNum = ""
Else
FmtNum = FormatNumber(val, 2, -1, 0, -1)
End If
End Function
' --------------------------------------------------------------------
' FmtNumAlways(val)
' Always returns a 2-decimal formatted string, even for zero.
' Used only for totals/footer cells.
' --------------------------------------------------------------------
Function FmtNumAlways(val)
If IsNull(val) Or val = "" Then
FmtNumAlways = "0.00"
Else
FmtNumAlways = FormatNumber(val, 2, -1, 0, -1)
End If
End Function
' ---------------------- Request params ----------------------
searchText = Trim(Request("search"))
carrierSel = Trim(Request("carrier"))
invoiceSel = Trim(Request("invoice"))
countrySel = Trim(Request("country"))
sortField = Trim(Request("sort"))
sortDir = Trim(Request("dir"))
missingOrders = (Request("missingorders")="1")
duplicateRefs = (Request("duplicates")="1")
If sortField="" Then sortField="s.shipment_id"
If sortDir="" Then sortDir="ASC"
whereSQL = " WHERE 1=1"
If searchText<>"" Then
whereSQL = whereSQL & " AND (s.Reference LIKE '%" & Replace(searchText,"'","''") & _
"%' OR s.ReceiverName LIKE '%" & Replace(searchText,"'","''") & "%')"
End If
If carrierSel<>"" Then whereSQL = whereSQL & " AND s.Carrier='" & Replace(carrierSel,"'","''") & "'"
If invoiceSel<>"" Then whereSQL = whereSQL & " AND s.InvoiceNumber='" & Replace(invoiceSel,"'","''") & "'"
If countrySel<>"" Then whereSQL = whereSQL & " AND s.DestCountry='" & Replace(countrySel,"'","''") & "'"
If missingOrders Then whereSQL = whereSQL & " AND s.Reference NOT IN (SELECT OrderNo FROM orders)"
If duplicateRefs Then whereSQL = whereSQL & " AND s.Reference IN (SELECT Reference FROM inxpress_shipments_parsed GROUP BY Reference HAVING COUNT(*)>1)"
' ---------------------- Main SQL ----------------------
sql = "SELECT s.*, " & _
"d.ShipmentDetails AS ShipmentDetails, d.ReceiverAddress AS ReceiverAddress, " & _
"d.PiecesWeightDimensionsZone AS PiecesWeightDimensionsZone, d.Charges AS DetailCharges, " & _
"d.Total AS DetailTotal, d.InvoiceNumber AS DetailInvoice, " & _
"o.Delivery, o.DeliveryAgentCost, o.DeliveryCalculatedCost " & _
"FROM inxpress_shipments_parsed s " & _
"LEFT JOIN inxpress_shipments d ON s.shipment_id = d.shipment_id " & _
"LEFT JOIN orders o ON s.Reference = o.OrderNo " & _
whereSQL & " ORDER BY " & sortField & " " & sortDir & " LIMIT " & PAGE_SIZE
Set rs = conn.Execute(sql)
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>InXpress Shipments</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { padding:10px; }
th a.sort { text-decoration:none; color:inherit; }
th { position:sticky; top:0; background:#fff; z-index:2; }
td.num { text-align:right; white-space:nowrap; }
td.total { font-weight:bold; }
tr.dup { background-color:#fff8d6; }
.modal-body pre { white-space:pre-wrap; }
</style>
</head>
<body>
<div class="container-fluid">
<h4 class="mb-3">InXpress Shipments</h4>
<form class="row row-cols-lg-auto g-2 align-items-center mb-3" method="get">
<div class="col-12"><input type="text" name="search" value="<%=SafeHTML(searchText)%>" class="form-control" placeholder="Search Reference or Receiver"></div>
<div class="col-12"><input type="text" name="carrier" value="<%=SafeHTML(carrierSel)%>" class="form-control" placeholder="Carrier"></div>
<div class="col-12"><input type="text" name="invoice" value="<%=SafeHTML(invoiceSel)%>" class="form-control" placeholder="Invoice"></div>
<div class="col-12"><input type="text" name="country" value="<%=SafeHTML(countrySel)%>" class="form-control" placeholder="Country"></div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Filter</button>
<a href="inxpress.asp" class="btn btn-secondary">Reset</a>
</div>
</form>
<div class="table-responsive">
<table class="table table-bordered table-sm align-middle">
<thead class="table-light">
<tr>
<th>ID</th>
<th>Ship Date</th>
<th>Carrier</th>
<th>Reference</th>
<th>Receiver</th>
<th>Country</th>
<th>Service Type</th>
<th>Weight</th>
<th>Length</th>
<th>Base (£)</th>
<th>Fuel (£)</th>
<th>Other (£)</th>
<th>Net (£)</th>
<th>VAT (£)</th>
<th>Total (£)</th>
<th>Charged (£)</th>
<th>Cost (£)</th>
<th>Calculated (£)</th>
</tr>
</thead>
<tbody>
<%
Do Until rs.EOF
Dim dupClass
If Not IsNull(rs("Reference")) Then
Dim tmpRS : Set tmpRS = conn.Execute("SELECT COUNT(*) FROM inxpress_shipments_parsed WHERE Reference='" & Replace(rs("Reference"),"'", "''") & "'")
If tmpRS(0)>1 Then dupClass="dup" Else dupClass=""
tmpRS.Close : Set tmpRS=Nothing
End If
Response.Write "<tr class='" & dupClass & "'>"
Response.Write "<td class='num'>" & SafeHTML(rs("shipment_id")) & "</td>"
Response.Write "<td>" & SafeHTML(Replace(Replace(CStr(rs("ShipDate")),"/","-"),"-","/")) & "</td>"
Response.Write "<td>" & SafeHTML(rs("Carrier")) & "</td>"
Response.Write "<td>" & SafeHTML(rs("Reference")) & "</td>"
Response.Write "<td><a href='#' data-bs-toggle='modal' data-bs-target='#m"&rs("shipment_id")&"'>" & SafeHTML(rs("ReceiverName")) & "</a></td>"
Response.Write "<td>" & SafeHTML(rs("DestCountry")) & "</td>"
Response.Write "<td style='font-size:0.9em'>" & SafeHTML(Replace(rs("ServiceType")," - Package","")) & "</td>"
Response.Write "<td class='num'>" & SafeHTML(rs("WeightKg")) & "</td>"
Response.Write "<td class='num'>" & SafeHTML(rs("Length")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("BaseCharge")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("FuelSurcharge")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("OtherCharges")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("NetAmount")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("VATAmount")) & "</td>"
Response.Write "<td class='num total'>" & FmtNum(rs("Total")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("Delivery")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("DeliveryAgentCost")) & "</td>"
Response.Write "<td class='num'>" & FmtNum(rs("DeliveryCalculatedCost")) & "</td>"
Response.Write "</tr>"
' Totals
totalBase = totalBase + CDbl(0 & rs("BaseCharge"))
totalFuel = totalFuel + CDbl(0 & rs("FuelSurcharge"))
totalOther = totalOther + CDbl(0 & rs("OtherCharges"))
totalNet = totalNet + CDbl(0 & rs("NetAmount"))
totalVAT = totalVAT + CDbl(0 & rs("VATAmount"))
totalGrand = totalGrand + CDbl(0 & rs("Total"))
totalDelivery = totalDelivery + CDbl(0 & rs("Delivery"))
totalDeliveryAgent = totalDeliveryAgent + CDbl(0 & rs("DeliveryAgentCost"))
totalDeliveryCalc = totalDeliveryCalc + CDbl(0 & rs("DeliveryCalculatedCost"))
' Modal
Response.Write "<div class='modal fade' id='m"&rs("shipment_id")&"' tabindex='-1'>"
Response.Write "<div class='modal-dialog modal-lg modal-dialog-scrollable'><div class='modal-content'>"
Response.Write "<div class='modal-header'><h5 class='modal-title'>Shipment #" & rs("shipment_id") & "</h5>"
Response.Write "<button type='button' class='btn-close' data-bs-dismiss='modal'></button></div>"
Response.Write "<div class='modal-body'>"
Response.Write "<p><b>Shipment Details:</b><br>" & SafeHTML(rs("ShipmentDetails")) & "</p>"
Response.Write "<p><b>Receiver Address:</b><br>" & SafeHTML(rs("ReceiverAddress")) & "</p>"
Response.Write "<p><b>Pieces/Weight/Dimensions/Zone:</b><br>" & SafeHTML(rs("PiecesWeightDimensionsZone")) & "</p>"
Response.Write "<p><b>Charges:</b><br>" & SafeHTML(rs("DetailCharges")) & "</p>"
Response.Write "<p><b>Total:</b> " & FmtNum(rs("DetailTotal")) & "</p>"
Response.Write "<p><b>Invoice Number:</b> " & SafeHTML(rs("DetailInvoice")) & "</p>"
Response.Write "</div></div></div></div>"
rs.MoveNext
Loop
%>
</tbody>
<tfoot>
<tr style="background-color:#e6f7e6;">
<td colspan="9" class="text-end fw-bold">Totals:</td>
<td class="num fw-bold"><%=FmtNumAlways(totalBase)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalFuel)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalOther)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalNet)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalVAT)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalGrand)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalDelivery)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalDeliveryAgent)%></td>
<td class="num fw-bold"><%=FmtNumAlways(totalDeliveryCalc)%></td>
</tr>
<tr class="table-light">
<td colspan="9"></td>
<td class="text-center">Base (£)</td>
<td class="text-center">Fuel (£)</td>
<td class="text-center">Other (£)</td>
<td class="text-center">Net (£)</td>
<td class="text-center">VAT (£)</td>
<td class="text-center">Total (£)</td>
<td class="text-center">Charged (£)</td>
<td class="text-center">Cost (£)</td>
<td class="text-center">Calculated (£)</td>
</tr>
</tfoot>
</table>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- ===================================================================== -->
<!-- End of inxpress.asp | SafeHTML ODBC memo fix active -->
<!-- ===================================================================== -->
</body>
</html>