" & _
"" & _
"| " & _
- "PE" & _
- "Purple Envelope" & _
- " Addressing & Barcoding " & _
+ "KCI Purple Envelope Order Confirmation" & _
" | " & _
"| " & _
" Order Received " & _
@@ -182,14 +180,17 @@ Class OrderApiController_Class
End If
If IsTrue(model.BlueWantsQuote) Then
+ ' City/permit number are always collected for an own-organization permit - a
+ ' permit lookup can't be done from the nonprofit authorization code alone, so
+ ' that code is additional information when nonprofit status is Yes, not a
+ ' replacement for city/permit number.
Dim bluePermitLine
bluePermitLine = ""
If LabelPermitOwnership(model.BluePermitOwnership) = "My organization's permit" Then
+ bluePermitLine = EmailRow("City of permit holder", model.BluePermitCity) & _
+ EmailRow("Permit number", model.BluePermitNumber)
If IsTrue(model.BlueHasNonprofitStatus) Then
- bluePermitLine = EmailRow("Nonprofit authorization code", model.BlueNonprofitAuthCode)
- Else
- bluePermitLine = EmailRow("City of permit holder", model.BluePermitCity) & _
- EmailRow("Permit number", model.BluePermitNumber)
+ bluePermitLine = bluePermitLine & EmailRow("Nonprofit authorization code", model.BlueNonprofitAuthCode)
End If
End If
diff --git a/app/models/JurisdictionValidator.asp b/app/models/JurisdictionValidator.asp
index 0635cd4..83d98c0 100644
--- a/app/models/JurisdictionValidator.asp
+++ b/app/models/JurisdictionValidator.asp
@@ -2,9 +2,105 @@
'=======================================================================================================================
' Jurisdiction Number Validation
'=======================================================================================================================
-' STUB: always returns True. Replace with a real lookup once a jurisdictions
-' table/reference list exists to validate the submitted number against.
+' Validates a submitted jurisdiction number against the JCode field of the jurisdictions
+' list served by JurisdictionApiUrl (see public/web.config). That list is essentially static
+' reference data (townships/municipalities), so it's cached in Application scope for
+' JurisdictionCacheMinutes (default 60) instead of being fetched on every /request-order
+' submission. If a refresh attempt fails, stale cached data is used rather than blocking
+' order requests; only when there is no cached data at all (e.g. immediately after an app
+' pool restart, with the API also unreachable) does validation fail open (allow) rather than
+' block every order request site-wide.
+'
+' The cache is stored as a single delimited STRING ("|code1|code2|...|"), not a
+' Scripting.Dictionary or array of objects - Scripting.Dictionary is an apartment-threaded
+' COM object, and IIS raises "ASP 0197: Disallowed object use" if you try to store one in
+' the Application intrinsic (which is shared across all requests/threads). A plain string is
+' just script data, so it's safe to cache this way.
+'=======================================================================================================================
+
Function IsValidJurisdictionNumber(jurisdictionNumber)
- IsValidJurisdictionNumber = True
+ Dim codesText
+ codesText = GetJurisdictionCodesText()
+
+ jurisdictionNumber = Trim(jurisdictionNumber)
+
+ If Len(codesText) = 0 Then
+ ' No jurisdiction list available at all (first request after startup, API also
+ ' down) - fail open rather than block every order request site-wide.
+ IsValidJurisdictionNumber = True
+ Else
+ IsValidJurisdictionNumber = (InStr(codesText, "|" & jurisdictionNumber & "|") > 0)
+ End If
+End Function
+
+' Returns the cached "|code1|code2|...|" string, refreshing it from JurisdictionApiUrl when
+' missing or older than JurisdictionCacheMinutes. Falls back to the existing (stale) cached
+' string if a refresh attempt fails.
+Private Function GetJurisdictionCodesText()
+ Dim cacheMinutes, cachedAt, isStale
+
+ cacheMinutes = GetAppSetting("JurisdictionCacheMinutes")
+ If Not IsNumeric(cacheMinutes) Then cacheMinutes = 60
+
+ cachedAt = Application("JurisdictionCodesFetchedAt")
+ isStale = IsEmpty(cachedAt)
+ If Not isStale Then isStale = (DateDiff("n", cachedAt, Now()) >= CInt(cacheMinutes))
+
+ If isStale Then
+ Dim fresh
+ fresh = FetchJurisdictionCodesText()
+ If Len(fresh) > 0 Then
+ Application.Lock
+ Application("JurisdictionCodesText") = fresh
+ Application("JurisdictionCodesFetchedAt") = Now()
+ Application.Unlock
+ End If
+ End If
+
+ GetJurisdictionCodesText = Application("JurisdictionCodesText")
+End Function
+
+' Fetches the jurisdictions list and extracts every JCode value. Returns a
+' "|code1|code2|...|" string, or "" on any failure (network, HTTP status, or no matches).
+'
+' Uses a targeted regex over the raw response text rather than this codebase's generic
+' aspJSON parser (core/lib.json.asp) - that parser walks the input character-by-character in
+' plain VBScript, which measured at over 40 seconds for this API's ~450KB/1500-record
+' response. RegExp.Execute is implemented natively and handles the same payload
+' near-instantly; since JCode is the only field this validator needs, a full generic parse
+' isn't necessary anyway.
+Private Function FetchJurisdictionCodesText()
+ Dim apiUrl : apiUrl = GetAppSetting("JurisdictionApiUrl")
+ Dim result : result = ""
+
+ On Error Resume Next
+
+ Dim http : Set http = Server.CreateObject("Msxml2.ServerXMLHTTP")
+ http.setTimeouts 5000, 5000, 5000, 5000
+ http.Open "GET", apiUrl, False
+ http.Send ""
+
+ If Err.Number = 0 And http.Status = 200 Then
+ Dim re, matches, m, codes, code
+ Set re = New RegExp
+ re.Pattern = """JCode""\s*:\s*""([^""]*)"""
+ re.Global = True
+ re.IgnoreCase = True
+
+ Set matches = re.Execute(http.responseText)
+ If Err.Number = 0 And matches.Count > 0 Then
+ codes = "|"
+ For Each m In matches
+ code = Trim(m.SubMatches(0))
+ If Len(code) > 0 Then codes = codes & code & "|"
+ Next
+ If Len(codes) > 1 Then result = codes
+ End If
+ End If
+
+ Err.Clear
+ On Error GoTo 0
+
+ FetchJurisdictionCodesText = result
End Function
%>
diff --git a/app/views/Order/continue.asp b/app/views/Order/continue.asp
index d4c85a1..9b9622d 100644
--- a/app/views/Order/continue.asp
+++ b/app/views/Order/continue.asp
@@ -217,13 +217,13 @@
},
{
type: "text", name: "BluePermitCity", title: "City of permit holder",
- description: "Please provide the following information.",
- visibleIf: "{BlueHasNonprofitStatus} = false",
+ description: "A permit lookup can't be done from the authorization code alone, so please also provide the following information.",
+ visibleIf: "{BluePermitOwnership} = 'OwnPermit'",
isRequired: true
},
{
type: "text", name: "BluePermitNumber", title: "Permit Number",
- visibleIf: "{BlueHasNonprofitStatus} = false",
+ visibleIf: "{BluePermitOwnership} = 'OwnPermit'",
isRequired: true
}
]
diff --git a/public/web.config b/public/web.config
index 4e40608..bd6a612 100644
--- a/public/web.config
+++ b/public/web.config
@@ -53,6 +53,14 @@
+
+
+
+
| |