25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

517 satır
24KB

  1. <%
  2. ' Auto-generated Controller: OrderApi
  3. ' Generated on 7/28/2026 2:56:29 PM
  4. ' Generator: generateController.vbs v1.0
  5. '
  6. ' Remember to:
  7. ' 1. Add to app/controllers/autoload_controllers.asp
  8. ' 2. Register in core/lib.ControllerRegistry.asp
  9. ' 3. Add routes in public/Default.asp
  10. Class OrderApiController_Class
  11. Private m_useLayout
  12. Private m_title
  13. Private Sub Class_Initialize()
  14. m_useLayout = False ' this controller returns JSON only, never the shared HTML layout
  15. m_title = "OrderApi"
  16. End Sub
  17. Public Property Get useLayout
  18. useLayout = m_useLayout
  19. End Property
  20. Public Property Let useLayout(v)
  21. m_useLayout = v
  22. End Property
  23. Public Property Get Title
  24. Title = m_title
  25. End Property
  26. Public Property Let Title(v)
  27. m_title = v
  28. End Property
  29. '-------------------------------------------------------------------------------------------------------------------
  30. ' POST: accept the completed SurveyJS order-details form (as JSON) for the order matching ?token=
  31. '-------------------------------------------------------------------------------------------------------------------
  32. Public Sub SubmitOrderDetails()
  33. Response.ContentType = "application/json"
  34. If Request.ServerVariables("REQUEST_METHOD") <> "POST" Then
  35. WriteJsonError "405 Method Not Allowed", "This endpoint only accepts POST."
  36. Exit Sub
  37. End If
  38. Dim token, order
  39. token = Trim(Request.QueryString("token"))
  40. Set order = Nothing
  41. If Len(token) > 0 Then Set order = OrdersRepository().FindByToken(token)
  42. If order Is Nothing Then
  43. WriteJsonError "404 Not Found", "Order not found."
  44. Exit Sub
  45. End If
  46. If order("TokenExpiresAt") < Now() Then
  47. WriteJsonError "410 Gone", "This order link has expired. Please request a new one."
  48. Exit Sub
  49. End If
  50. Dim csrfToken : csrfToken = Request.ServerVariables("HTTP_X_CSRF_TOKEN")
  51. If Not HTMLSecurity().IsValidAntiCSRFToken("Order.Continue", csrfToken) Then
  52. WriteJsonError "403 Forbidden", "Your form session expired. Please refresh the page and try again."
  53. Exit Sub
  54. End If
  55. Dim answers
  56. On Error Resume Next
  57. json().loadJSON GetRawJsonFromRequest()
  58. If Err.Number <> 0 Then
  59. Err.Clear
  60. On Error GoTo 0
  61. WriteJsonError "400 Bad Request", "Could not read the submitted form data."
  62. Exit Sub
  63. End If
  64. On Error GoTo 0
  65. Set answers = json().data
  66. Dim validationError : validationError = ValidateAnswers(answers)
  67. If Len(validationError) > 0 Then
  68. WriteJsonError "400 Bad Request", validationError
  69. Exit Sub
  70. End If
  71. Dim model : Set model = New POBO_OrderDetails
  72. On Error Resume Next
  73. MapOrderDetailsAnswers model, answers
  74. model.SubmittedAt = Now()
  75. If Err.Number <> 0 Then
  76. Err.Clear
  77. On Error GoTo 0
  78. WriteJsonError "400 Bad Request", "The submitted data could not be processed. Please check your entries and try again."
  79. Exit Sub
  80. End If
  81. On Error GoTo 0
  82. On Error Resume Next
  83. OrderDetailsRepository().SaveForOrder order("OrderID"), model
  84. If Err.Number <> 0 Then
  85. Err.Clear
  86. On Error GoTo 0
  87. WriteJsonError "500 Internal Server Error", "Could not save your order details. Please try again."
  88. Exit Sub
  89. End If
  90. On Error GoTo 0
  91. ' Best-effort: the order is already safely persisted at this point, so an SMTP hiccup
  92. ' should not turn a successful submission into a failed one.
  93. SendOrderDetailsEmail order, model
  94. Response.Write "{""success"":true}"
  95. End Sub
  96. '-------------------------------------------------------------------------------------------------------------------
  97. ' Order-confirmation email
  98. '-------------------------------------------------------------------------------------------------------------------
  99. Private Sub SendOrderDetailsEmail(order, model)
  100. On Error Resume Next
  101. Dim smtpPort : smtpPort = GetAppSetting("SmtpPort")
  102. If Not IsNumeric(smtpPort) Then smtpPort = 25
  103. Dim mail : Set mail = CDOEmail()
  104. mail.SMTPServer = GetAppSetting("SmtpServer")
  105. mail.SMTPPort = CInt(smtpPort)
  106. mail.SMTPUsername = GetAppSetting("SmtpUsername")
  107. mail.SMTPPassword = GetAppSetting("SmtpPassword")
  108. mail.SMTPUseSSL = (LCase(GetAppSetting("SmtpUseSSL")) = "true")
  109. mail.From = GetAppSetting("SmtpFromAddress")
  110. mail.Subject = "Your Purple Envelope order details - Jurisdiction " & order("JurisdictionNumber")
  111. mail.IsBodyHTML = True
  112. mail.Body = BuildOrderDetailsEmailBody(order, model)
  113. mail.AddRecipient "To", order("Email")
  114. mail.Send
  115. Err.Clear
  116. On Error GoTo 0
  117. End Sub
  118. Private Function BuildOrderDetailsEmailBody(order, model)
  119. Dim html
  120. html = "<!doctype html><html><body style=""margin:0; padding:0; background:#faf7fd; font-family:Arial, Helvetica, sans-serif;"">" & _
  121. "<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"" style=""background:#faf7fd; padding:24px 0;""><tr><td align=""center"">" & _
  122. "<table role=""presentation"" width=""600"" cellpadding=""0"" cellspacing=""0"" style=""background:#ffffff; border-radius:12px; overflow:hidden; box-shadow:0 4px 16px rgba(36,16,58,0.08);"">" & _
  123. "<tr><td style=""background:#24103a; padding:24px 32px;"">" & _
  124. "<span style=""display:inline-block; width:34px; height:34px; border-radius:50%; background:#7c3bc0; color:#fff; font-weight:800; font-size:12px; text-align:center; line-height:34px; vertical-align:middle;"">PE</span>" & _
  125. "<span style=""color:#ffffff; font-weight:700; font-size:16px; margin-left:10px; vertical-align:middle;"">Purple Envelope</span>" & _
  126. "<div style=""color:#dcc9ef; font-size:11px; margin-top:2px;"">Addressing &amp; Barcoding</div>" & _
  127. "</td></tr>" & _
  128. "<tr><td style=""padding:32px;"">" & _
  129. "<div style=""color:#7c3bc0; font-weight:800; font-size:11px; letter-spacing:0.06em; text-transform:uppercase;"">Order Received</div>" & _
  130. "<h1 style=""color:#201a27; font-size:22px; margin:6px 0 4px; font-family:Arial, Helvetica, sans-serif;"">Thanks! We've received your order details.</h1>" & _
  131. "<p style=""color:#6d6574; font-size:13px; margin:0 0 8px;"">Jurisdiction number <strong style=""color:#201a27;"">" & H(order("JurisdictionNumber")) & "</strong>" & _
  132. " &middot; submitted " & H(EmailDate(model.SubmittedAt)) & "</p>"
  133. html = html & EmailSection("Contact Information", _
  134. EmailRow("Contact Name", model.ContactName) & _
  135. EmailRow("Municipality", model.Municipality) & _
  136. EmailRow("Phone", model.Phone))
  137. If IsTrue(model.PurpleWantsQuote) Then
  138. html = html & EmailSection("Purple Ballot Envelopes", _
  139. EmailRow("Print option", LabelPrintOption(model.PurplePrintOption)) & _
  140. EmailRow("Envelope stock", LabelEnvelopeStock(model.PurpleEnvelopeStock)) & _
  141. EmailRow("Envelope provider", model.PurpleEnvelopeProvider) & _
  142. EmailRow("Also wants KCI blue envelopes", EmailYesNo(model.PurpleWantsBlueEnvelopes)) & _
  143. EmailRow("Print style", LabelPrintStyle(model.PurplePrintStyle)) & _
  144. EmailRow("Color coding by", LabelColorCodingBy(model.PurpleColorCodingBy)) & _
  145. EmailRow("Number of precincts", model.PurplePrecinctCount) & _
  146. EmailRow("Track with TrackMI Ballot", EmailYesNo(model.PurpleTrackMIBallot)) & _
  147. EmailRow("Extra envelopes requested", model.PurpleExtraEnvelopeQty) & _
  148. EmailRow("Requested delivery date", EmailDate(model.PurpleDeliveryDate)))
  149. End If
  150. If IsTrue(model.BlueWantsQuote) Then
  151. html = html & EmailSection("Blue AV Envelopes", _
  152. EmailRow("Provider", LabelBlueProvider(model.BlueEnvelopeProvider)) & _
  153. EmailRow("Print permit", EmailYesNo(model.BluePrintPermit)) & _
  154. EmailRow("Permit number", model.BluePermitNumber) & _
  155. EmailRow("City of permit holder", model.BluePermitCity) & _
  156. EmailRow("Permit class", model.BluePermitClass) & _
  157. EmailRow("Print return address", EmailYesNo(model.BluePrintReturnAddress)) & _
  158. EmailRow("Requested delivery date", EmailDate(model.BlueDeliveryDate)))
  159. End If
  160. If IsTrue(model.MailingWantsService) Then
  161. html = html & EmailSection("Ballot Mailing Service", _
  162. EmailRow("Postage", LabelPostageOption(model.MailingPostageOption)) & _
  163. EmailRow("Nonprofit status with USPS", LabelNonprofitStatus(model.MailingHasNonprofitStatus)) & _
  164. EmailRow("Sort ballots", EmailYesNo(model.MailingWantsSorting)) & _
  165. EmailRow("Preferred pickup date", EmailDate(model.MailingPickupDate)))
  166. End If
  167. If NumOrZero(model.SecrecySleevesQty) > 0 Or NumOrZero(model.IVotedStickerRolls) > 0 Or NumOrZero(model.FutureVoterStickerRolls) > 0 Then
  168. html = html & EmailSection("Additional Election Items", _
  169. EmailRow("Secrecy sleeves (quantity)", model.SecrecySleevesQty) & _
  170. EmailRow("""I Voted"" stickers (rolls of 250)", model.IVotedStickerRolls) & _
  171. EmailRow("""Future Voter"" stickers (rolls of 500)", model.FutureVoterStickerRolls))
  172. End If
  173. html = html & "<p style=""color:#6d6574; font-size:12px; margin-top:24px;"">Questions about this order? Just reply to this email.</p>" & _
  174. "</td></tr>" & _
  175. "<tr><td style=""background:#f0e7f8; padding:16px 32px; text-align:center;"">" & _
  176. "<span style=""color:#6529a0; font-size:11px;"">Purple Envelope &middot; Addressing &amp; Barcoding</span>" & _
  177. "</td></tr>" & _
  178. "</table></td></tr></table></body></html>"
  179. BuildOrderDetailsEmailBody = html
  180. End Function
  181. Private Function EmailSection(sectionTitle, rowsHtml)
  182. If Len(rowsHtml) = 0 Then
  183. EmailSection = ""
  184. Else
  185. EmailSection = "<h2 style=""color:#4d1d78; font-size:14px; margin:24px 0 8px; padding-top:16px; border-top:1px solid #f0e7f8; font-family:Arial, Helvetica, sans-serif;"">" & _
  186. H(sectionTitle) & "</h2>" & _
  187. "<table role=""presentation"" width=""100%"" cellpadding=""0"" cellspacing=""0"">" & rowsHtml & "</table>"
  188. End If
  189. End Function
  190. Private Function EmailRow(label, value)
  191. If Len(Trim(value & "")) = 0 Then
  192. EmailRow = ""
  193. Else
  194. EmailRow = "<tr>" & _
  195. "<td style=""padding:6px 0; color:#6d6574; font-size:13px; width:45%; vertical-align:top;"">" & H(label) & "</td>" & _
  196. "<td style=""padding:6px 0; color:#201a27; font-size:13px; font-weight:600;"">" & H(value) & "</td>" & _
  197. "</tr>"
  198. End If
  199. End Function
  200. ' Null-safe boolean check for gating whole sections - a section's top-level "do you want
  201. ' this?" question isn't marked required client-side, so it may be missing (Null) rather
  202. ' than explicitly false.
  203. Private Function IsTrue(v)
  204. If IsNull(v) Then
  205. IsTrue = False
  206. Else
  207. IsTrue = CBool(v)
  208. End If
  209. End Function
  210. Private Function EmailYesNo(v)
  211. If IsNull(v) Then
  212. EmailYesNo = ""
  213. ElseIf CBool(v) Then
  214. EmailYesNo = "Yes"
  215. Else
  216. EmailYesNo = "No"
  217. End If
  218. End Function
  219. Private Function EmailDate(v)
  220. If IsNull(v) Then
  221. EmailDate = ""
  222. Else
  223. On Error Resume Next
  224. EmailDate = MonthName(Month(v)) & " " & Day(v) & ", " & Year(v)
  225. If Err.Number <> 0 Then EmailDate = ""
  226. Err.Clear
  227. On Error GoTo 0
  228. End If
  229. End Function
  230. Private Function NumOrZero(v)
  231. If IsNull(v) Or Not IsNumeric(v) Then
  232. NumOrZero = 0
  233. Else
  234. NumOrZero = CDbl(v)
  235. End If
  236. End Function
  237. ' Human-readable labels for the coded choice values written by continue.asp's SurveyJS
  238. ' model - falls back to the raw code for anything unrecognized rather than hiding it.
  239. Private Function LabelPrintOption(code)
  240. Select Case CStr(code & "")
  241. Case "AddressesAndPostage" : LabelPrintOption = "Addresses and return postage"
  242. Case "PostageOnly" : LabelPrintOption = "Return postage only"
  243. Case Else : LabelPrintOption = CStr(code & "")
  244. End Select
  245. End Function
  246. Private Function LabelEnvelopeStock(code)
  247. Select Case CStr(code & "")
  248. Case "KCIStock" : LabelEnvelopeStock = "KCI's stock"
  249. Case "OwnStock" : LabelEnvelopeStock = "My own stock"
  250. Case Else : LabelEnvelopeStock = CStr(code & "")
  251. End Select
  252. End Function
  253. Private Function LabelPrintStyle(code)
  254. Select Case CStr(code & "")
  255. Case "ColorCoding" : LabelPrintStyle = "Color Coding"
  256. Case "BlackOnly" : LabelPrintStyle = "Black Only"
  257. Case Else : LabelPrintStyle = CStr(code & "")
  258. End Select
  259. End Function
  260. Private Function LabelColorCodingBy(code)
  261. Select Case CStr(code & "")
  262. Case "Precinct" : LabelColorCodingBy = "Precinct"
  263. Case "Election" : LabelColorCodingBy = "Election"
  264. Case Else : LabelColorCodingBy = CStr(code & "")
  265. End Select
  266. End Function
  267. Private Function LabelBlueProvider(code)
  268. Select Case CStr(code & "")
  269. Case "KCI" : LabelBlueProvider = "KCI"
  270. Case "OtherProvider" : LabelBlueProvider = "Other provider"
  271. Case Else : LabelBlueProvider = CStr(code & "")
  272. End Select
  273. End Function
  274. Private Function LabelPostageOption(code)
  275. Select Case CStr(code & "")
  276. Case "FirstClass" : LabelPostageOption = "Yes, at First Class Rate"
  277. Case "NonprofitRate" : LabelPostageOption = "Yes, at Nonprofit Rate"
  278. Case "No" : LabelPostageOption = "No"
  279. Case Else : LabelPostageOption = CStr(code & "")
  280. End Select
  281. End Function
  282. Private Function LabelNonprofitStatus(code)
  283. Select Case CStr(code & "")
  284. Case "Yes" : LabelNonprofitStatus = "Yes"
  285. Case "No" : LabelNonprofitStatus = "No"
  286. Case "NotSure" : LabelNonprofitStatus = "I'm not sure"
  287. Case Else : LabelNonprofitStatus = CStr(code & "")
  288. End Select
  289. End Function
  290. '-------------------------------------------------------------------------------------------------------------------
  291. ' Re-validates the submission server-side, mirroring the SurveyJS required/enum rules in
  292. ' continue.asp - the client-side checks are a UX convenience, not something the server can
  293. ' trust. Returns "" if valid, or a "; "-joined list of validation error messages.
  294. '-------------------------------------------------------------------------------------------------------------------
  295. Private Function ValidateAnswers(answers)
  296. Dim errors() : ReDim errors(-1)
  297. RequireNonEmptyString errors, answers, "ContactName", "Contact name is required."
  298. RequireNonEmptyString errors, answers, "Municipality", "Municipality is required."
  299. RequireNonEmptyString errors, answers, "Phone", "Phone number is required."
  300. RequireEnum errors, answers, "PurplePrintOption", Array("AddressesAndPostage", "PostageOnly")
  301. RequireEnum errors, answers, "PurpleEnvelopeStock", Array("KCIStock", "OwnStock")
  302. RequireEnum errors, answers, "PurplePrintStyle", Array("ColorCoding", "BlackOnly")
  303. RequireEnum errors, answers, "PurpleColorCodingBy", Array("Precinct", "Election")
  304. RequireEnum errors, answers, "BlueEnvelopeProvider", Array("KCI", "OtherProvider")
  305. RequireEnum errors, answers, "BluePermitClass", Array("NP", "STD")
  306. RequireEnum errors, answers, "MailingPostageOption", Array("FirstClass", "NonprofitRate", "No")
  307. RequireEnum errors, answers, "MailingHasNonprofitStatus", Array("Yes", "No", "NotSure")
  308. RequireBoolean errors, answers, "PurpleWantsQuote"
  309. RequireBoolean errors, answers, "PurpleWantsBlueEnvelopes"
  310. RequireBoolean errors, answers, "PurpleTrackMIBallot"
  311. RequireBoolean errors, answers, "BlueWantsQuote"
  312. RequireBoolean errors, answers, "BluePrintPermit"
  313. RequireBoolean errors, answers, "BluePrintReturnAddress"
  314. RequireBoolean errors, answers, "MailingWantsService"
  315. RequireBoolean errors, answers, "MailingWantsSorting"
  316. RequireNonNegativeInteger errors, answers, "PurplePrecinctCount"
  317. RequireNonNegativeInteger errors, answers, "PurpleExtraEnvelopeQty"
  318. RequireNonNegativeInteger errors, answers, "SecrecySleevesQty"
  319. RequireNonNegativeInteger errors, answers, "IVotedStickerRolls"
  320. RequireNonNegativeInteger errors, answers, "FutureVoterStickerRolls"
  321. RequireValidDate errors, answers, "PurpleDeliveryDate"
  322. RequireValidDate errors, answers, "BlueDeliveryDate"
  323. RequireValidDate errors, answers, "MailingPickupDate"
  324. If UBound(errors) >= 0 Then
  325. ValidateAnswers = Join(errors, "; ")
  326. Else
  327. ValidateAnswers = ""
  328. End If
  329. End Function
  330. Private Sub AddValidationError(ByRef errors, msg)
  331. ReDim Preserve errors(UBound(errors) + 1)
  332. errors(UBound(errors)) = msg
  333. End Sub
  334. ' Required on the client (page 1) - re-checked here since the client can't be trusted.
  335. Private Sub RequireNonEmptyString(ByRef errors, answers, key, msg)
  336. Dim v : v = AnswerValue(answers, key)
  337. If IsNull(v) Or Len(Trim(v & "")) = 0 Then AddValidationError errors, msg
  338. End Sub
  339. ' Only checked when present - these questions are conditionally hidden by visibleIf, so a
  340. ' missing value just means the question wasn't shown, not an invalid submission.
  341. Private Sub RequireEnum(ByRef errors, answers, key, allowedValues)
  342. Dim v : v = AnswerValue(answers, key)
  343. If Not IsNull(v) Then
  344. Dim found : found = False
  345. Dim i
  346. For i = 0 To UBound(allowedValues)
  347. If CStr(v) = allowedValues(i) Then found = True
  348. Next
  349. If Not found Then AddValidationError errors, key & " has an invalid value."
  350. End If
  351. End Sub
  352. Private Sub RequireBoolean(ByRef errors, answers, key)
  353. Dim v : v = AnswerValue(answers, key)
  354. If Not IsNull(v) Then
  355. If TypeName(v) <> "Boolean" Then AddValidationError errors, key & " must be true or false."
  356. End If
  357. End Sub
  358. Private Sub RequireNonNegativeInteger(ByRef errors, answers, key)
  359. Dim v : v = AnswerValue(answers, key)
  360. If Not IsNull(v) Then
  361. If Not IsNumeric(v) Then
  362. AddValidationError errors, key & " must be a number."
  363. ElseIf CDbl(v) < 0 Then
  364. AddValidationError errors, key & " cannot be negative."
  365. ElseIf CDbl(v) <> Int(CDbl(v)) Then
  366. AddValidationError errors, key & " must be a whole number."
  367. End If
  368. End If
  369. End Sub
  370. Private Sub RequireValidDate(ByRef errors, answers, key)
  371. Dim v : v = AnswerValue(answers, key)
  372. If Not IsNull(v) Then
  373. If Len(Trim(v & "")) > 0 And Not IsDate(v) Then
  374. AddValidationError errors, key & " is not a valid date."
  375. End If
  376. End If
  377. End Sub
  378. '-------------------------------------------------------------------------------------------------------------------
  379. ' Private helpers
  380. '-------------------------------------------------------------------------------------------------------------------
  381. Private Sub MapOrderDetailsAnswers(ByRef model, answers)
  382. ' Contact
  383. model.ContactName = AnswerValue(answers, "ContactName")
  384. model.Municipality = AnswerValue(answers, "Municipality")
  385. model.Phone = AnswerValue(answers, "Phone")
  386. ' Purple envelope
  387. model.PurpleWantsQuote = AnswerValue(answers, "PurpleWantsQuote")
  388. model.PurplePrintOption = AnswerValue(answers, "PurplePrintOption")
  389. model.PurpleEnvelopeStock = AnswerValue(answers, "PurpleEnvelopeStock")
  390. model.PurpleEnvelopeProvider = AnswerValue(answers, "PurpleEnvelopeProvider")
  391. model.PurpleWantsBlueEnvelopes = AnswerValue(answers, "PurpleWantsBlueEnvelopes")
  392. model.PurplePrintStyle = AnswerValue(answers, "PurplePrintStyle")
  393. model.PurpleColorCodingBy = AnswerValue(answers, "PurpleColorCodingBy")
  394. model.PurplePrecinctCount = AnswerValue(answers, "PurplePrecinctCount")
  395. model.PurpleTrackMIBallot = AnswerValue(answers, "PurpleTrackMIBallot")
  396. model.PurpleExtraEnvelopeQty = AnswerValue(answers, "PurpleExtraEnvelopeQty")
  397. model.PurpleDeliveryDate = AnswerValue(answers, "PurpleDeliveryDate")
  398. ' Blue envelope
  399. model.BlueWantsQuote = AnswerValue(answers, "BlueWantsQuote")
  400. model.BlueEnvelopeProvider = AnswerValue(answers, "BlueEnvelopeProvider")
  401. model.BluePrintPermit = AnswerValue(answers, "BluePrintPermit")
  402. model.BluePermitNumber = AnswerValue(answers, "BluePermitNumber")
  403. model.BluePermitCity = AnswerValue(answers, "BluePermitCity")
  404. model.BluePermitClass = AnswerValue(answers, "BluePermitClass")
  405. model.BluePrintReturnAddress = AnswerValue(answers, "BluePrintReturnAddress")
  406. model.BlueDeliveryDate = AnswerValue(answers, "BlueDeliveryDate")
  407. ' Mailing service
  408. model.MailingWantsService = AnswerValue(answers, "MailingWantsService")
  409. model.MailingPostageOption = AnswerValue(answers, "MailingPostageOption")
  410. model.MailingHasNonprofitStatus = AnswerValue(answers, "MailingHasNonprofitStatus")
  411. model.MailingWantsSorting = AnswerValue(answers, "MailingWantsSorting")
  412. model.MailingPickupDate = AnswerValue(answers, "MailingPickupDate")
  413. ' Additional items
  414. model.SecrecySleevesQty = AnswerValue(answers, "SecrecySleevesQty")
  415. model.IVotedStickerRolls = AnswerValue(answers, "IVotedStickerRolls")
  416. model.FutureVoterStickerRolls = AnswerValue(answers, "FutureVoterStickerRolls")
  417. End Sub
  418. ' Returns the value for key in a parsed aspJSON Dictionary, or Null if the question was
  419. ' skipped (hidden by visibleIf logic and so never included in SurveyJS's result data).
  420. Private Function AnswerValue(answers, key)
  421. If answers.Exists(key) Then
  422. AnswerValue = answers.Item(key)
  423. Else
  424. AnswerValue = Null
  425. End If
  426. End Function
  427. Private Sub WriteJsonError(statusLine, message)
  428. Response.Status = statusLine
  429. Response.Write "{""success"":false,""error"":" & JsonEncodeString(message) & "}"
  430. End Sub
  431. Private Function JsonEncodeString(s)
  432. Dim out : out = s
  433. out = Replace(out, "\", "\\")
  434. out = Replace(out, """", "\""")
  435. out = Replace(out, Chr(10), "\n")
  436. out = Replace(out, Chr(13), "\r")
  437. JsonEncodeString = """" & out & """"
  438. End Function
  439. End Class
  440. ' Singleton instance
  441. Dim OrderApiController_Class__Singleton
  442. Function OrderApiController()
  443. If IsEmpty(OrderApiController_Class__Singleton) Then
  444. Set OrderApiController_Class__Singleton = New OrderApiController_Class
  445. End If
  446. Set OrderApiController = OrderApiController_Class__Singleton
  447. End Function
  448. %>

Powered by TurnKey Linux.