Просмотр исходного кода

Apply revised order-form PDFs, tester feedback, and color picker

Order form revision (docs/lucid "(1)" PDFs):
- Purple Envelope: reordered stock/permit questions, renamed postage-only to
  state-permit-only, added colors question and blue-envelope-provider
  cross-sell
- Blue Envelope: reworked permit flow with KCI-vs-own-organization
  ownership and nonprofit-status branching
- Mailing Service: real per-piece pricing, new Presort Standard tier,
  estimated-quantity question, fixed pickup-date list, removed the
  ballot-sorting question
- Additional Items: added a special-requests field
- Added db/migrations/20260804153857_revise_order_details_columns.asp
  (additive only - columns retired by the revision are left in place,
  not dropped, since the table has real test data)

Tester feedback:
- Fixed "Spectrom" typo to "Spectrum" (value code + label + validation)
- Corrected First Class postage rate to $0.721/pc.
- Marked nearly every survey question required so SurveyJS blocks
  page navigation on missing answers

Color picker for envelope colors:
- Replaced free-text color entry with a modal image picker sourced from
  public/images/Purple_ballot_envelopes colors/*.bmp, converted to PNG
  in public/images/purple-envelope-colors/ (23MB -> 245KB)

Cleanup pass:
- Removed the redundant "KCI's blue envelopes or another provider's"
  question (redundant with the preceding yes/no)
- Removed the purple-envelope delivery-date picker in favor of a static
  lead-time note
- Trimmed the Mailing Service page title
- Fixed the post-submission message to stop showing SurveyJS's default
  "survey" wording
master
Daniel Covington 2 недель назад
Родитель
Сommit
aad06cecfa
67 измененных файлов: 524 добавлений и 130 удалений
  1. +71
    -46
      app/controllers/OrderApiController.asp
  2. +9
    -9
      app/models/OrderDetailsRepository.asp
  3. +155
    -7
      app/models/POBO_OrderDetails.asp
  4. +230
    -68
      app/views/Order/continue.asp
  5. +59
    -0
      db/migrations/20260804153857_revise_order_details_columns.asp
  6. Двоичные данные
      docs/lucid/Election Materials Order Form #1 (1).pdf
  7. Двоичные данные
      docs/lucid/Election Materials Request #3 (1).pdf
  8. Двоичные данные
      docs/lucid/Election Materials Request Form #2 (1).pdf
  9. Двоичные данные
      public/images/purple-envelope-colors/Aqua.png
  10. Двоичные данные
      public/images/purple-envelope-colors/Black.png
  11. Двоичные данные
      public/images/purple-envelope-colors/Blue.png
  12. Двоичные данные
      public/images/purple-envelope-colors/Brown.png
  13. Двоичные данные
      public/images/purple-envelope-colors/BurlyWood.png
  14. Двоичные данные
      public/images/purple-envelope-colors/Chocolate.png
  15. Двоичные данные
      public/images/purple-envelope-colors/Clay.png
  16. Двоичные данные
      public/images/purple-envelope-colors/Coral.png
  17. Двоичные данные
      public/images/purple-envelope-colors/CornflowerBlue.png
  18. Двоичные данные
      public/images/purple-envelope-colors/Crimson.png
  19. Двоичные данные
      public/images/purple-envelope-colors/DarkOrange.png
  20. Двоичные данные
      public/images/purple-envelope-colors/DeepPink.png
  21. Двоичные данные
      public/images/purple-envelope-colors/DeepSkyBlue.png
  22. Двоичные данные
      public/images/purple-envelope-colors/DimGray.png
  23. Двоичные данные
      public/images/purple-envelope-colors/DodgerBlue.png
  24. Двоичные данные
      public/images/purple-envelope-colors/FireBrick.png
  25. Двоичные данные
      public/images/purple-envelope-colors/ForestGreen.png
  26. Двоичные данные
      public/images/purple-envelope-colors/Fuchsia.png
  27. Двоичные данные
      public/images/purple-envelope-colors/Gold.png
  28. Двоичные данные
      public/images/purple-envelope-colors/Goldenrod.png
  29. Двоичные данные
      public/images/purple-envelope-colors/Green.png
  30. Двоичные данные
      public/images/purple-envelope-colors/HotPink.png
  31. Двоичные данные
      public/images/purple-envelope-colors/Indigo.png
  32. Двоичные данные
      public/images/purple-envelope-colors/LightSeaGreen.png
  33. Двоичные данные
      public/images/purple-envelope-colors/Lime.png
  34. Двоичные данные
      public/images/purple-envelope-colors/LimeGreen.png
  35. Двоичные данные
      public/images/purple-envelope-colors/LtGreen.png
  36. Двоичные данные
      public/images/purple-envelope-colors/MediumOrchid.png
  37. Двоичные данные
      public/images/purple-envelope-colors/MediumPurple.png
  38. Двоичные данные
      public/images/purple-envelope-colors/MediumTurquoise.png
  39. Двоичные данные
      public/images/purple-envelope-colors/MintGreen.png
  40. Двоичные данные
      public/images/purple-envelope-colors/Navy.png
  41. Двоичные данные
      public/images/purple-envelope-colors/Olive.png
  42. Двоичные данные
      public/images/purple-envelope-colors/OliveDrab.png
  43. Двоичные данные
      public/images/purple-envelope-colors/Orange.png
  44. Двоичные данные
      public/images/purple-envelope-colors/OrangeRed.png
  45. Двоичные данные
      public/images/purple-envelope-colors/Orchid.png
  46. Двоичные данные
      public/images/purple-envelope-colors/PastelBlue.png
  47. Двоичные данные
      public/images/purple-envelope-colors/PastelPink.png
  48. Двоичные данные
      public/images/purple-envelope-colors/PastelPurple.png
  49. Двоичные данные
      public/images/purple-envelope-colors/PastelYellow.png
  50. Двоичные данные
      public/images/purple-envelope-colors/Peru.png
  51. Двоичные данные
      public/images/purple-envelope-colors/Pink.png
  52. Двоичные данные
      public/images/purple-envelope-colors/Purple.png
  53. Двоичные данные
      public/images/purple-envelope-colors/Red.png
  54. Двоичные данные
      public/images/purple-envelope-colors/RoyalBlue.png
  55. Двоичные данные
      public/images/purple-envelope-colors/SaddleBrown.png
  56. Двоичные данные
      public/images/purple-envelope-colors/SeaGreen.png
  57. Двоичные данные
      public/images/purple-envelope-colors/Sienna.png
  58. Двоичные данные
      public/images/purple-envelope-colors/Silver.png
  59. Двоичные данные
      public/images/purple-envelope-colors/SkyBlue.png
  60. Двоичные данные
      public/images/purple-envelope-colors/SteelBlue.png
  61. Двоичные данные
      public/images/purple-envelope-colors/Tan.png
  62. Двоичные данные
      public/images/purple-envelope-colors/Teal.png
  63. Двоичные данные
      public/images/purple-envelope-colors/Tomato.png
  64. Двоичные данные
      public/images/purple-envelope-colors/Turquoise.png
  65. Двоичные данные
      public/images/purple-envelope-colors/Violet.png
  66. Двоичные данные
      public/images/purple-envelope-colors/White.png
  67. Двоичные данные
      public/images/purple-envelope-colors/Yellow.png

+ 71
- 46
app/controllers/OrderApiController.asp Просмотреть файл

@@ -162,43 +162,58 @@ Class OrderApiController_Class
EmailRow("Phone", model.Phone)) EmailRow("Phone", model.Phone))


If IsTrue(model.PurpleWantsQuote) Then If IsTrue(model.PurpleWantsQuote) Then
Dim purpleBlueProviderLine
purpleBlueProviderLine = LabelPurpleBlueProvider(model.PurpleBlueProvider)
If purpleBlueProviderLine = "Other" And Len(Trim(model.PurpleBlueProviderOther & "")) > 0 Then
purpleBlueProviderLine = model.PurpleBlueProviderOther
End If

html = html & EmailSection("Purple Ballot Envelopes", _ html = html & EmailSection("Purple Ballot Envelopes", _
EmailRow("Print option", LabelPrintOption(model.PurplePrintOption)) & _
EmailRow("Envelope stock", LabelEnvelopeStock(model.PurpleEnvelopeStock)) & _ EmailRow("Envelope stock", LabelEnvelopeStock(model.PurpleEnvelopeStock)) & _
EmailRow("Envelope provider", model.PurpleEnvelopeProvider) & _
EmailRow("Print option", LabelPrintOption(model.PurplePrintOption)) & _
EmailRow("Also wants KCI blue envelopes", EmailYesNo(model.PurpleWantsBlueEnvelopes)) & _ EmailRow("Also wants KCI blue envelopes", EmailYesNo(model.PurpleWantsBlueEnvelopes)) & _
EmailRow("Blue envelope provider", purpleBlueProviderLine) & _
EmailRow("Print style", LabelPrintStyle(model.PurplePrintStyle)) & _ EmailRow("Print style", LabelPrintStyle(model.PurplePrintStyle)) & _
EmailRow("Color coding by", LabelColorCodingBy(model.PurpleColorCodingBy)) & _ EmailRow("Color coding by", LabelColorCodingBy(model.PurpleColorCodingBy)) & _
EmailRow("Number of precincts", model.PurplePrecinctCount) & _ EmailRow("Number of precincts", model.PurplePrecinctCount) & _
EmailRow("Colors requested", model.PurpleColorNames) & _
EmailRow("Track with TrackMI Ballot", EmailYesNo(model.PurpleTrackMIBallot)) & _ EmailRow("Track with TrackMI Ballot", EmailYesNo(model.PurpleTrackMIBallot)) & _
EmailRow("Extra envelopes requested", model.PurpleExtraEnvelopeQty) & _
EmailRow("Requested delivery date", EmailDate(model.PurpleDeliveryDate)))
EmailRow("Extra envelopes requested", model.PurpleExtraEnvelopeQty))
End If End If


If IsTrue(model.BlueWantsQuote) Then If IsTrue(model.BlueWantsQuote) Then
Dim bluePermitLine
bluePermitLine = ""
If LabelPermitOwnership(model.BluePermitOwnership) = "My organization's permit" Then
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)
End If
End If

html = html & EmailSection("Blue AV Envelopes", _ html = html & EmailSection("Blue AV Envelopes", _
EmailRow("Provider", LabelBlueProvider(model.BlueEnvelopeProvider)) & _
EmailRow("Print permit", EmailYesNo(model.BluePrintPermit)) & _ EmailRow("Print permit", EmailYesNo(model.BluePrintPermit)) & _
EmailRow("Permit number", model.BluePermitNumber) & _
EmailRow("City of permit holder", model.BluePermitCity) & _
EmailRow("Permit class", model.BluePermitClass) & _
EmailRow("Print return address", EmailYesNo(model.BluePrintReturnAddress)) & _
EmailRow("Requested delivery date", EmailDate(model.BlueDeliveryDate)))
EmailRow("Permit ownership", LabelPermitOwnership(model.BluePermitOwnership)) & _
EmailRow("Confirmed nonprofit status with USPS", EmailYesNo(model.BlueHasNonprofitStatus)) & _
bluePermitLine)
End If End If


If IsTrue(model.MailingWantsService) Then If IsTrue(model.MailingWantsService) Then
html = html & EmailSection("Ballot Mailing Service", _ html = html & EmailSection("Ballot Mailing Service", _
EmailRow("Postage", LabelPostageOption(model.MailingPostageOption)) & _ EmailRow("Postage", LabelPostageOption(model.MailingPostageOption)) & _
EmailRow("Nonprofit status with USPS", LabelNonprofitStatus(model.MailingHasNonprofitStatus)) & _ EmailRow("Nonprofit status with USPS", LabelNonprofitStatus(model.MailingHasNonprofitStatus)) & _
EmailRow("Sort ballots", EmailYesNo(model.MailingWantsSorting)) & _
EmailRow("Estimated quantity", model.MailingEstimatedQuantity) & _
EmailRow("Preferred pickup date", EmailDate(model.MailingPickupDate))) EmailRow("Preferred pickup date", EmailDate(model.MailingPickupDate)))
End If End If


If NumOrZero(model.SecrecySleevesQty) > 0 Or NumOrZero(model.IVotedStickerRolls) > 0 Or NumOrZero(model.FutureVoterStickerRolls) > 0 Then
If NumOrZero(model.SecrecySleevesQty) > 0 Or NumOrZero(model.IVotedStickerRolls) > 0 Or NumOrZero(model.FutureVoterStickerRolls) > 0 Or Len(Trim(model.SpecialRequests & "")) > 0 Then
html = html & EmailSection("Additional Election Items", _ html = html & EmailSection("Additional Election Items", _
EmailRow("Secrecy sleeves (quantity)", model.SecrecySleevesQty) & _ EmailRow("Secrecy sleeves (quantity)", model.SecrecySleevesQty) & _
EmailRow("""I Voted"" stickers (rolls of 250)", model.IVotedStickerRolls) & _ EmailRow("""I Voted"" stickers (rolls of 250)", model.IVotedStickerRolls) & _
EmailRow("""Future Voter"" stickers (rolls of 500)", model.FutureVoterStickerRolls))
EmailRow("""Future Voter"" stickers (rolls of 500)", model.FutureVoterStickerRolls) & _
EmailRow("Special requests", model.SpecialRequests))
End If End If


html = html & "<p style=""color:#6d6574; font-size:12px; margin-top:24px;"">Questions about this order? Just reply to this email.</p>" & _ html = html & "<p style=""color:#6d6574; font-size:12px; margin-top:24px;"">Questions about this order? Just reply to this email.</p>" & _
@@ -277,9 +292,27 @@ Class OrderApiController_Class
' model - falls back to the raw code for anything unrecognized rather than hiding it. ' model - falls back to the raw code for anything unrecognized rather than hiding it.
Private Function LabelPrintOption(code) Private Function LabelPrintOption(code)
Select Case CStr(code & "") Select Case CStr(code & "")
Case "AddressesAndPostage" : LabelPrintOption = "Addresses and return postage"
Case "PostageOnly" : LabelPrintOption = "Return postage only"
Case Else : LabelPrintOption = CStr(code & "")
Case "AddressesAndPermit" : LabelPrintOption = "Addresses and state of Michigan permit"
Case "PermitOnly" : LabelPrintOption = "State of Michigan permit only"
Case Else : LabelPrintOption = CStr(code & "")
End Select
End Function

Private Function LabelPurpleBlueProvider(code)
Select Case CStr(code & "")
Case "ElectionSource" : LabelPurpleBlueProvider = "ElectionSource"
Case "PSI" : LabelPurpleBlueProvider = "PSI"
Case "Spectrum" : LabelPurpleBlueProvider = "Spectrum"
Case "Other" : LabelPurpleBlueProvider = "Other"
Case Else : LabelPurpleBlueProvider = CStr(code & "")
End Select
End Function

Private Function LabelPermitOwnership(code)
Select Case CStr(code & "")
Case "KCIPermit" : LabelPermitOwnership = "KCI permit"
Case "OwnPermit" : LabelPermitOwnership = "My organization's permit"
Case Else : LabelPermitOwnership = CStr(code & "")
End Select End Select
End Function End Function


@@ -294,7 +327,7 @@ Class OrderApiController_Class
Private Function LabelPrintStyle(code) Private Function LabelPrintStyle(code)
Select Case CStr(code & "") Select Case CStr(code & "")
Case "ColorCoding" : LabelPrintStyle = "Color Coding" Case "ColorCoding" : LabelPrintStyle = "Color Coding"
Case "BlackOnly" : LabelPrintStyle = "Black Only"
Case "BlackOnly" : LabelPrintStyle = "Black Ink Only"
Case Else : LabelPrintStyle = CStr(code & "") Case Else : LabelPrintStyle = CStr(code & "")
End Select End Select
End Function End Function
@@ -307,20 +340,13 @@ Class OrderApiController_Class
End Select End Select
End Function End Function


Private Function LabelBlueProvider(code)
Select Case CStr(code & "")
Case "KCI" : LabelBlueProvider = "KCI"
Case "OtherProvider" : LabelBlueProvider = "Other provider"
Case Else : LabelBlueProvider = CStr(code & "")
End Select
End Function

Private Function LabelPostageOption(code) Private Function LabelPostageOption(code)
Select Case CStr(code & "") Select Case CStr(code & "")
Case "FirstClass" : LabelPostageOption = "Yes, at First Class Rate"
Case "NonprofitRate" : LabelPostageOption = "Yes, at Nonprofit Rate"
Case "No" : LabelPostageOption = "No"
Case Else : LabelPostageOption = CStr(code & "")
Case "FirstClass" : LabelPostageOption = "Yes, at First Class Rate ($0.721/pc.)"
Case "NonprofitRate" : LabelPostageOption = "Yes, at Nonprofit Rate ($0.263/pc.)"
Case "PresortStandard" : LabelPostageOption = "Yes, at Presort Standard Rate ($0.473/pc.)"
Case "No" : LabelPostageOption = "No"
Case Else : LabelPostageOption = CStr(code & "")
End Select End Select
End Function End Function


@@ -345,13 +371,13 @@ Class OrderApiController_Class
RequireNonEmptyString errors, answers, "Municipality", "Municipality is required." RequireNonEmptyString errors, answers, "Municipality", "Municipality is required."
RequireNonEmptyString errors, answers, "Phone", "Phone number is required." RequireNonEmptyString errors, answers, "Phone", "Phone number is required."


RequireEnum errors, answers, "PurplePrintOption", Array("AddressesAndPostage", "PostageOnly")
RequireEnum errors, answers, "PurpleEnvelopeStock", Array("KCIStock", "OwnStock") RequireEnum errors, answers, "PurpleEnvelopeStock", Array("KCIStock", "OwnStock")
RequireEnum errors, answers, "PurplePrintOption", Array("AddressesAndPermit", "PermitOnly")
RequireEnum errors, answers, "PurpleBlueProvider", Array("ElectionSource", "PSI", "Spectrum", "Other")
RequireEnum errors, answers, "PurplePrintStyle", Array("ColorCoding", "BlackOnly") RequireEnum errors, answers, "PurplePrintStyle", Array("ColorCoding", "BlackOnly")
RequireEnum errors, answers, "PurpleColorCodingBy", Array("Precinct", "Election") RequireEnum errors, answers, "PurpleColorCodingBy", Array("Precinct", "Election")
RequireEnum errors, answers, "BlueEnvelopeProvider", Array("KCI", "OtherProvider")
RequireEnum errors, answers, "BluePermitClass", Array("NP", "STD")
RequireEnum errors, answers, "MailingPostageOption", Array("FirstClass", "NonprofitRate", "No")
RequireEnum errors, answers, "BluePermitOwnership", Array("KCIPermit", "OwnPermit")
RequireEnum errors, answers, "MailingPostageOption", Array("FirstClass", "NonprofitRate", "PresortStandard", "No")
RequireEnum errors, answers, "MailingHasNonprofitStatus", Array("Yes", "No", "NotSure") RequireEnum errors, answers, "MailingHasNonprofitStatus", Array("Yes", "No", "NotSure")


RequireBoolean errors, answers, "PurpleWantsQuote" RequireBoolean errors, answers, "PurpleWantsQuote"
@@ -359,18 +385,16 @@ Class OrderApiController_Class
RequireBoolean errors, answers, "PurpleTrackMIBallot" RequireBoolean errors, answers, "PurpleTrackMIBallot"
RequireBoolean errors, answers, "BlueWantsQuote" RequireBoolean errors, answers, "BlueWantsQuote"
RequireBoolean errors, answers, "BluePrintPermit" RequireBoolean errors, answers, "BluePrintPermit"
RequireBoolean errors, answers, "BluePrintReturnAddress"
RequireBoolean errors, answers, "BlueHasNonprofitStatus"
RequireBoolean errors, answers, "MailingWantsService" RequireBoolean errors, answers, "MailingWantsService"
RequireBoolean errors, answers, "MailingWantsSorting"


RequireNonNegativeInteger errors, answers, "PurplePrecinctCount" RequireNonNegativeInteger errors, answers, "PurplePrecinctCount"
RequireNonNegativeInteger errors, answers, "PurpleExtraEnvelopeQty" RequireNonNegativeInteger errors, answers, "PurpleExtraEnvelopeQty"
RequireNonNegativeInteger errors, answers, "MailingEstimatedQuantity"
RequireNonNegativeInteger errors, answers, "SecrecySleevesQty" RequireNonNegativeInteger errors, answers, "SecrecySleevesQty"
RequireNonNegativeInteger errors, answers, "IVotedStickerRolls" RequireNonNegativeInteger errors, answers, "IVotedStickerRolls"
RequireNonNegativeInteger errors, answers, "FutureVoterStickerRolls" RequireNonNegativeInteger errors, answers, "FutureVoterStickerRolls"


RequireValidDate errors, answers, "PurpleDeliveryDate"
RequireValidDate errors, answers, "BlueDeliveryDate"
RequireValidDate errors, answers, "MailingPickupDate" RequireValidDate errors, answers, "MailingPickupDate"


If UBound(errors) >= 0 Then If UBound(errors) >= 0 Then
@@ -445,38 +469,39 @@ Class OrderApiController_Class


' Purple envelope ' Purple envelope
model.PurpleWantsQuote = AnswerValue(answers, "PurpleWantsQuote") model.PurpleWantsQuote = AnswerValue(answers, "PurpleWantsQuote")
model.PurplePrintOption = AnswerValue(answers, "PurplePrintOption")
model.PurpleEnvelopeStock = AnswerValue(answers, "PurpleEnvelopeStock") model.PurpleEnvelopeStock = AnswerValue(answers, "PurpleEnvelopeStock")
model.PurpleEnvelopeProvider = AnswerValue(answers, "PurpleEnvelopeProvider")
model.PurplePrintOption = AnswerValue(answers, "PurplePrintOption")
model.PurpleWantsBlueEnvelopes = AnswerValue(answers, "PurpleWantsBlueEnvelopes") model.PurpleWantsBlueEnvelopes = AnswerValue(answers, "PurpleWantsBlueEnvelopes")
model.PurpleBlueProvider = AnswerValue(answers, "PurpleBlueProvider")
model.PurpleBlueProviderOther = AnswerValue(answers, "PurpleBlueProviderOther")
model.PurplePrintStyle = AnswerValue(answers, "PurplePrintStyle") model.PurplePrintStyle = AnswerValue(answers, "PurplePrintStyle")
model.PurpleColorCodingBy = AnswerValue(answers, "PurpleColorCodingBy") model.PurpleColorCodingBy = AnswerValue(answers, "PurpleColorCodingBy")
model.PurplePrecinctCount = AnswerValue(answers, "PurplePrecinctCount") model.PurplePrecinctCount = AnswerValue(answers, "PurplePrecinctCount")
model.PurpleColorNames = AnswerValue(answers, "PurpleColorNames")
model.PurpleTrackMIBallot = AnswerValue(answers, "PurpleTrackMIBallot") model.PurpleTrackMIBallot = AnswerValue(answers, "PurpleTrackMIBallot")
model.PurpleExtraEnvelopeQty = AnswerValue(answers, "PurpleExtraEnvelopeQty") model.PurpleExtraEnvelopeQty = AnswerValue(answers, "PurpleExtraEnvelopeQty")
model.PurpleDeliveryDate = AnswerValue(answers, "PurpleDeliveryDate")


' Blue envelope ' Blue envelope
model.BlueWantsQuote = AnswerValue(answers, "BlueWantsQuote") model.BlueWantsQuote = AnswerValue(answers, "BlueWantsQuote")
model.BlueEnvelopeProvider = AnswerValue(answers, "BlueEnvelopeProvider")
model.BluePrintPermit = AnswerValue(answers, "BluePrintPermit") model.BluePrintPermit = AnswerValue(answers, "BluePrintPermit")
model.BluePermitNumber = AnswerValue(answers, "BluePermitNumber")
model.BluePermitOwnership = AnswerValue(answers, "BluePermitOwnership")
model.BlueHasNonprofitStatus = AnswerValue(answers, "BlueHasNonprofitStatus")
model.BlueNonprofitAuthCode = AnswerValue(answers, "BlueNonprofitAuthCode")
model.BluePermitCity = AnswerValue(answers, "BluePermitCity") model.BluePermitCity = AnswerValue(answers, "BluePermitCity")
model.BluePermitClass = AnswerValue(answers, "BluePermitClass")
model.BluePrintReturnAddress = AnswerValue(answers, "BluePrintReturnAddress")
model.BlueDeliveryDate = AnswerValue(answers, "BlueDeliveryDate")
model.BluePermitNumber = AnswerValue(answers, "BluePermitNumber")


' Mailing service ' Mailing service
model.MailingWantsService = AnswerValue(answers, "MailingWantsService") model.MailingWantsService = AnswerValue(answers, "MailingWantsService")
model.MailingPostageOption = AnswerValue(answers, "MailingPostageOption") model.MailingPostageOption = AnswerValue(answers, "MailingPostageOption")
model.MailingHasNonprofitStatus = AnswerValue(answers, "MailingHasNonprofitStatus") model.MailingHasNonprofitStatus = AnswerValue(answers, "MailingHasNonprofitStatus")
model.MailingWantsSorting = AnswerValue(answers, "MailingWantsSorting")
model.MailingEstimatedQuantity = AnswerValue(answers, "MailingEstimatedQuantity")
model.MailingPickupDate = AnswerValue(answers, "MailingPickupDate") model.MailingPickupDate = AnswerValue(answers, "MailingPickupDate")


' Additional items ' Additional items
model.SecrecySleevesQty = AnswerValue(answers, "SecrecySleevesQty") model.SecrecySleevesQty = AnswerValue(answers, "SecrecySleevesQty")
model.IVotedStickerRolls = AnswerValue(answers, "IVotedStickerRolls") model.IVotedStickerRolls = AnswerValue(answers, "IVotedStickerRolls")
model.FutureVoterStickerRolls = AnswerValue(answers, "FutureVoterStickerRolls") model.FutureVoterStickerRolls = AnswerValue(answers, "FutureVoterStickerRolls")
model.SpecialRequests = AnswerValue(answers, "SpecialRequests")
End Sub End Sub


' Returns the value for key in a parsed aspJSON Dictionary, or Null if the question was ' Returns the value for key in a parsed aspJSON Dictionary, or Null if the question was


+ 9
- 9
app/models/OrderDetailsRepository.asp Просмотреть файл

@@ -1,6 +1,6 @@
<% <%
' Auto-generated Repository for table [OrderDetails] ' Auto-generated Repository for table [OrderDetails]
' Generated on 7/28/2026 2:53:42 PM
' Generated on 8/4/2026 3:40:46 PM
' Generator: GenerateRepo.vbs v1.0 ' Generator: GenerateRepo.vbs v1.0
' '
' Dependencies: ' Dependencies:
@@ -13,7 +13,7 @@
Class OrderDetailsRepository_Class Class OrderDetailsRepository_Class


Public Function FindByID(id) Public Function FindByID(id)
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleColorCodingBy], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SubmittedAt] FROM [OrderDetails] WHERE [OrderDetailID] = ?"
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BlueHasNonprofitStatus], [BlueNonprofitAuthCode], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePermitOwnership], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingEstimatedQuantity], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleBlueProvider], [PurpleBlueProviderOther], [PurpleColorCodingBy], [PurpleColorNames], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SpecialRequests], [SubmittedAt] FROM [OrderDetails] WHERE [OrderDetailID] = ?"
Dim rs : Set rs = DAL.Query(sql, Array(id)) Dim rs : Set rs = DAL.Query(sql, Array(id))
If rs.EOF Then If rs.EOF Then
Err.Raise 1, "OrderDetailsRepository_Class", RecordNotFoundException("OrderDetailID", id) Err.Raise 1, "OrderDetailsRepository_Class", RecordNotFoundException("OrderDetailID", id)
@@ -28,7 +28,7 @@ Class OrderDetailsRepository_Class
End Function End Function


Public Function Find(where_kvarray, order_string_or_array) Public Function Find(where_kvarray, order_string_or_array)
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleColorCodingBy], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SubmittedAt] FROM [OrderDetails]"
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BlueHasNonprofitStatus], [BlueNonprofitAuthCode], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePermitOwnership], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingEstimatedQuantity], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleBlueProvider], [PurpleBlueProviderOther], [PurpleColorCodingBy], [PurpleColorNames], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SpecialRequests], [SubmittedAt] FROM [OrderDetails]"
Dim where_keys, where_values, i Dim where_keys, where_values, i
If Not IsEmpty(where_kvarray) Then If Not IsEmpty(where_kvarray) Then
KVUnzip where_kvarray, where_keys, where_values KVUnzip where_kvarray, where_keys, where_values
@@ -52,7 +52,7 @@ Class OrderDetailsRepository_Class
End Function End Function


Public Function FindPaged(where_kvarray, order_string_or_array, per_page, page_num, ByRef page_count, ByRef record_count) Public Function FindPaged(where_kvarray, order_string_or_array, per_page, page_num, ByRef page_count, ByRef record_count)
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleColorCodingBy], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SubmittedAt] FROM [OrderDetails]"
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BlueHasNonprofitStatus], [BlueNonprofitAuthCode], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePermitOwnership], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingEstimatedQuantity], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleBlueProvider], [PurpleBlueProviderOther], [PurpleColorCodingBy], [PurpleColorNames], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SpecialRequests], [SubmittedAt] FROM [OrderDetails]"
Dim where_keys, where_values, i Dim where_keys, where_values, i
If Not IsEmpty(where_kvarray) Then If Not IsEmpty(where_kvarray) Then
KVUnzip where_kvarray, where_keys, where_values KVUnzip where_kvarray, where_keys, where_values
@@ -77,7 +77,7 @@ Class OrderDetailsRepository_Class
End Function End Function


Public Function SearchTablePaged(columns_array, search_value, order_string_or_array, per_page, page_num, ByRef page_count, ByRef record_count) Public Function SearchTablePaged(columns_array, search_value, order_string_or_array, per_page, page_num, ByRef page_count, ByRef record_count)
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleColorCodingBy], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SubmittedAt] FROM [OrderDetails]"
Dim sql : sql = "Select [BlueDeliveryDate], [BlueEnvelopeProvider], [BlueHasNonprofitStatus], [BlueNonprofitAuthCode], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePermitOwnership], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingEstimatedQuantity], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderDetailID], [OrderID], [Phone], [PurpleBlueProvider], [PurpleBlueProviderOther], [PurpleColorCodingBy], [PurpleColorNames], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SpecialRequests], [SubmittedAt] FROM [OrderDetails]"
Dim i, params() Dim i, params()
If IsArray(columns_array) And UBound(columns_array) >= 0 Then If IsArray(columns_array) And UBound(columns_array) >= 0 Then
sql = sql & " WHERE " sql = sql & " WHERE "
@@ -112,8 +112,8 @@ Class OrderDetailsRepository_Class
End Function End Function


Public Sub AddNew(ByRef model) Public Sub AddNew(ByRef model)
Dim sql : sql = "INSERT INTO [OrderDetails] ([BlueDeliveryDate], [BlueEnvelopeProvider], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderID], [Phone], [PurpleColorCodingBy], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SubmittedAt]) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
DAL.Execute sql, Array(model.BlueDeliveryDate, model.BlueEnvelopeProvider, model.BluePermitCity, model.BluePermitClass, model.BluePermitNumber, model.BluePrintPermit, model.BluePrintReturnAddress, model.BlueWantsQuote, model.ContactName, model.FutureVoterStickerRolls, model.IVotedStickerRolls, model.MailingHasNonprofitStatus, model.MailingPickupDate, model.MailingPostageOption, model.MailingWantsService, model.MailingWantsSorting, model.Municipality, model.OrderID, model.Phone, model.PurpleColorCodingBy, model.PurpleDeliveryDate, model.PurpleEnvelopeProvider, model.PurpleEnvelopeStock, model.PurpleExtraEnvelopeQty, model.PurplePrecinctCount, model.PurplePrintOption, model.PurplePrintStyle, model.PurpleTrackMIBallot, model.PurpleWantsBlueEnvelopes, model.PurpleWantsQuote, model.SecrecySleevesQty, model.SubmittedAt)
Dim sql : sql = "INSERT INTO [OrderDetails] ([BlueDeliveryDate], [BlueEnvelopeProvider], [BlueHasNonprofitStatus], [BlueNonprofitAuthCode], [BluePermitCity], [BluePermitClass], [BluePermitNumber], [BluePermitOwnership], [BluePrintPermit], [BluePrintReturnAddress], [BlueWantsQuote], [ContactName], [FutureVoterStickerRolls], [IVotedStickerRolls], [MailingEstimatedQuantity], [MailingHasNonprofitStatus], [MailingPickupDate], [MailingPostageOption], [MailingWantsService], [MailingWantsSorting], [Municipality], [OrderID], [Phone], [PurpleBlueProvider], [PurpleBlueProviderOther], [PurpleColorCodingBy], [PurpleColorNames], [PurpleDeliveryDate], [PurpleEnvelopeProvider], [PurpleEnvelopeStock], [PurpleExtraEnvelopeQty], [PurplePrecinctCount], [PurplePrintOption], [PurplePrintStyle], [PurpleTrackMIBallot], [PurpleWantsBlueEnvelopes], [PurpleWantsQuote], [SecrecySleevesQty], [SpecialRequests], [SubmittedAt]) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
DAL.Execute sql, Array(model.BlueDeliveryDate, model.BlueEnvelopeProvider, model.BlueHasNonprofitStatus, model.BlueNonprofitAuthCode, model.BluePermitCity, model.BluePermitClass, model.BluePermitNumber, model.BluePermitOwnership, model.BluePrintPermit, model.BluePrintReturnAddress, model.BlueWantsQuote, model.ContactName, model.FutureVoterStickerRolls, model.IVotedStickerRolls, model.MailingEstimatedQuantity, model.MailingHasNonprofitStatus, model.MailingPickupDate, model.MailingPostageOption, model.MailingWantsService, model.MailingWantsSorting, model.Municipality, model.OrderID, model.Phone, model.PurpleBlueProvider, model.PurpleBlueProviderOther, model.PurpleColorCodingBy, model.PurpleColorNames, model.PurpleDeliveryDate, model.PurpleEnvelopeProvider, model.PurpleEnvelopeStock, model.PurpleExtraEnvelopeQty, model.PurplePrecinctCount, model.PurplePrintOption, model.PurplePrintStyle, model.PurpleTrackMIBallot, model.PurpleWantsBlueEnvelopes, model.PurpleWantsQuote, model.SecrecySleevesQty, model.SpecialRequests, model.SubmittedAt)
' Retrieve the newly inserted ID ' Retrieve the newly inserted ID
On Error Resume Next On Error Resume Next
@@ -132,8 +132,8 @@ Class OrderDetailsRepository_Class
End Sub End Sub


Public Sub Update(model) Public Sub Update(model)
Dim sql : sql = "UPDATE [OrderDetails] SET [BlueDeliveryDate] = ?, [BlueEnvelopeProvider] = ?, [BluePermitCity] = ?, [BluePermitClass] = ?, [BluePermitNumber] = ?, [BluePrintPermit] = ?, [BluePrintReturnAddress] = ?, [BlueWantsQuote] = ?, [ContactName] = ?, [FutureVoterStickerRolls] = ?, [IVotedStickerRolls] = ?, [MailingHasNonprofitStatus] = ?, [MailingPickupDate] = ?, [MailingPostageOption] = ?, [MailingWantsService] = ?, [MailingWantsSorting] = ?, [Municipality] = ?, [OrderID] = ?, [Phone] = ?, [PurpleColorCodingBy] = ?, [PurpleDeliveryDate] = ?, [PurpleEnvelopeProvider] = ?, [PurpleEnvelopeStock] = ?, [PurpleExtraEnvelopeQty] = ?, [PurplePrecinctCount] = ?, [PurplePrintOption] = ?, [PurplePrintStyle] = ?, [PurpleTrackMIBallot] = ?, [PurpleWantsBlueEnvelopes] = ?, [PurpleWantsQuote] = ?, [SecrecySleevesQty] = ?, [SubmittedAt] = ? WHERE [OrderDetailID] = ?"
DAL.Execute sql, Array(model.BlueDeliveryDate, model.BlueEnvelopeProvider, model.BluePermitCity, model.BluePermitClass, model.BluePermitNumber, model.BluePrintPermit, model.BluePrintReturnAddress, model.BlueWantsQuote, model.ContactName, model.FutureVoterStickerRolls, model.IVotedStickerRolls, model.MailingHasNonprofitStatus, model.MailingPickupDate, model.MailingPostageOption, model.MailingWantsService, model.MailingWantsSorting, model.Municipality, model.OrderID, model.Phone, model.PurpleColorCodingBy, model.PurpleDeliveryDate, model.PurpleEnvelopeProvider, model.PurpleEnvelopeStock, model.PurpleExtraEnvelopeQty, model.PurplePrecinctCount, model.PurplePrintOption, model.PurplePrintStyle, model.PurpleTrackMIBallot, model.PurpleWantsBlueEnvelopes, model.PurpleWantsQuote, model.SecrecySleevesQty, model.SubmittedAt, model.OrderDetailID)
Dim sql : sql = "UPDATE [OrderDetails] SET [BlueDeliveryDate] = ?, [BlueEnvelopeProvider] = ?, [BlueHasNonprofitStatus] = ?, [BlueNonprofitAuthCode] = ?, [BluePermitCity] = ?, [BluePermitClass] = ?, [BluePermitNumber] = ?, [BluePermitOwnership] = ?, [BluePrintPermit] = ?, [BluePrintReturnAddress] = ?, [BlueWantsQuote] = ?, [ContactName] = ?, [FutureVoterStickerRolls] = ?, [IVotedStickerRolls] = ?, [MailingEstimatedQuantity] = ?, [MailingHasNonprofitStatus] = ?, [MailingPickupDate] = ?, [MailingPostageOption] = ?, [MailingWantsService] = ?, [MailingWantsSorting] = ?, [Municipality] = ?, [OrderID] = ?, [Phone] = ?, [PurpleBlueProvider] = ?, [PurpleBlueProviderOther] = ?, [PurpleColorCodingBy] = ?, [PurpleColorNames] = ?, [PurpleDeliveryDate] = ?, [PurpleEnvelopeProvider] = ?, [PurpleEnvelopeStock] = ?, [PurpleExtraEnvelopeQty] = ?, [PurplePrecinctCount] = ?, [PurplePrintOption] = ?, [PurplePrintStyle] = ?, [PurpleTrackMIBallot] = ?, [PurpleWantsBlueEnvelopes] = ?, [PurpleWantsQuote] = ?, [SecrecySleevesQty] = ?, [SpecialRequests] = ?, [SubmittedAt] = ? WHERE [OrderDetailID] = ?"
DAL.Execute sql, Array(model.BlueDeliveryDate, model.BlueEnvelopeProvider, model.BlueHasNonprofitStatus, model.BlueNonprofitAuthCode, model.BluePermitCity, model.BluePermitClass, model.BluePermitNumber, model.BluePermitOwnership, model.BluePrintPermit, model.BluePrintReturnAddress, model.BlueWantsQuote, model.ContactName, model.FutureVoterStickerRolls, model.IVotedStickerRolls, model.MailingEstimatedQuantity, model.MailingHasNonprofitStatus, model.MailingPickupDate, model.MailingPostageOption, model.MailingWantsService, model.MailingWantsSorting, model.Municipality, model.OrderID, model.Phone, model.PurpleBlueProvider, model.PurpleBlueProviderOther, model.PurpleColorCodingBy, model.PurpleColorNames, model.PurpleDeliveryDate, model.PurpleEnvelopeProvider, model.PurpleEnvelopeStock, model.PurpleExtraEnvelopeQty, model.PurplePrecinctCount, model.PurplePrintOption, model.PurplePrintStyle, model.PurpleTrackMIBallot, model.PurpleWantsBlueEnvelopes, model.PurpleWantsQuote, model.SecrecySleevesQty, model.SpecialRequests, model.SubmittedAt, model.OrderDetailID)
End Sub End Sub


Public Sub Delete(id) Public Sub Delete(id)


+ 155
- 7
app/models/POBO_OrderDetails.asp Просмотреть файл

@@ -1,6 +1,6 @@
<% <%
' Auto-generated POBO for table [OrderDetails] ' Auto-generated POBO for table [OrderDetails]
' Generated on 7/28/2026 2:53:42 PM
' Generated on 8/4/2026 3:40:46 PM
' Generator: GenerateRepo.vbs v1.0 ' Generator: GenerateRepo.vbs v1.0
' '
' Dependencies: core/helpers.asp (QuoteValue function) ' Dependencies: core/helpers.asp (QuoteValue function)
@@ -12,15 +12,19 @@ Class POBO_OrderDetails


Private pBlueDeliveryDate Private pBlueDeliveryDate
Private pBlueEnvelopeProvider Private pBlueEnvelopeProvider
Private pBlueHasNonprofitStatus
Private pBlueNonprofitAuthCode
Private pBluePermitCity Private pBluePermitCity
Private pBluePermitClass Private pBluePermitClass
Private pBluePermitNumber Private pBluePermitNumber
Private pBluePermitOwnership
Private pBluePrintPermit Private pBluePrintPermit
Private pBluePrintReturnAddress Private pBluePrintReturnAddress
Private pBlueWantsQuote Private pBlueWantsQuote
Private pContactName Private pContactName
Private pFutureVoterStickerRolls Private pFutureVoterStickerRolls
Private pIVotedStickerRolls Private pIVotedStickerRolls
Private pMailingEstimatedQuantity
Private pMailingHasNonprofitStatus Private pMailingHasNonprofitStatus
Private pMailingPickupDate Private pMailingPickupDate
Private pMailingPostageOption Private pMailingPostageOption
@@ -30,7 +34,10 @@ Class POBO_OrderDetails
Private pOrderDetailID Private pOrderDetailID
Private pOrderID Private pOrderID
Private pPhone Private pPhone
Private pPurpleBlueProvider
Private pPurpleBlueProviderOther
Private pPurpleColorCodingBy Private pPurpleColorCodingBy
Private pPurpleColorNames
Private pPurpleDeliveryDate Private pPurpleDeliveryDate
Private pPurpleEnvelopeProvider Private pPurpleEnvelopeProvider
Private pPurpleEnvelopeStock Private pPurpleEnvelopeStock
@@ -42,30 +49,38 @@ Class POBO_OrderDetails
Private pPurpleWantsBlueEnvelopes Private pPurpleWantsBlueEnvelopes
Private pPurpleWantsQuote Private pPurpleWantsQuote
Private pSecrecySleevesQty Private pSecrecySleevesQty
Private pSpecialRequests
Private pSubmittedAt Private pSubmittedAt


Private Sub Class_Initialize() Private Sub Class_Initialize()
pBlueDeliveryDate = Null pBlueDeliveryDate = Null
pBlueEnvelopeProvider = Null pBlueEnvelopeProvider = Null
pBlueHasNonprofitStatus = Null
pBlueNonprofitAuthCode = Null
pBluePermitCity = Null pBluePermitCity = Null
pBluePermitClass = Null pBluePermitClass = Null
pBluePermitNumber = Null pBluePermitNumber = Null
pBluePermitOwnership = Null
pBluePrintPermit = False pBluePrintPermit = False
pBluePrintReturnAddress = False pBluePrintReturnAddress = False
pBlueWantsQuote = False pBlueWantsQuote = False
pContactName = Null pContactName = Null
pFutureVoterStickerRolls = 0 pFutureVoterStickerRolls = 0
pIVotedStickerRolls = 0 pIVotedStickerRolls = 0
pMailingEstimatedQuantity = 0
pMailingHasNonprofitStatus = Null pMailingHasNonprofitStatus = Null
pMailingPickupDate = Null pMailingPickupDate = Null
pMailingPostageOption = Null pMailingPostageOption = Null
pMailingWantsService = False
pMailingWantsSorting = False
pMailingWantsService = Null
pMailingWantsSorting = Null
pMunicipality = Null pMunicipality = Null
pOrderDetailID = 0 pOrderDetailID = 0
pOrderID = 0 pOrderID = 0
pPhone = Null pPhone = Null
pPurpleBlueProvider = Null
pPurpleBlueProviderOther = Null
pPurpleColorCodingBy = Null pPurpleColorCodingBy = Null
pPurpleColorNames = Null
pPurpleDeliveryDate = Null pPurpleDeliveryDate = Null
pPurpleEnvelopeProvider = Null pPurpleEnvelopeProvider = Null
pPurpleEnvelopeStock = Null pPurpleEnvelopeStock = Null
@@ -73,12 +88,13 @@ Class POBO_OrderDetails
pPurplePrecinctCount = 0 pPurplePrecinctCount = 0
pPurplePrintOption = Null pPurplePrintOption = Null
pPurplePrintStyle = Null pPurplePrintStyle = Null
pPurpleTrackMIBallot = False
pPurpleWantsBlueEnvelopes = False
pPurpleWantsQuote = False
pPurpleTrackMIBallot = Null
pPurpleWantsBlueEnvelopes = Null
pPurpleWantsQuote = Null
pSecrecySleevesQty = 0 pSecrecySleevesQty = 0
pSpecialRequests = Null
pSubmittedAt = #1/1/1970# pSubmittedAt = #1/1/1970#
Properties = Array("BlueDeliveryDate","BlueEnvelopeProvider","BluePermitCity","BluePermitClass","BluePermitNumber","BluePrintPermit","BluePrintReturnAddress","BlueWantsQuote","ContactName","FutureVoterStickerRolls","IVotedStickerRolls","MailingHasNonprofitStatus","MailingPickupDate","MailingPostageOption","MailingWantsService","MailingWantsSorting","Municipality","OrderDetailID","OrderID","Phone","PurpleColorCodingBy","PurpleDeliveryDate","PurpleEnvelopeProvider","PurpleEnvelopeStock","PurpleExtraEnvelopeQty","PurplePrecinctCount","PurplePrintOption","PurplePrintStyle","PurpleTrackMIBallot","PurpleWantsBlueEnvelopes","PurpleWantsQuote","SecrecySleevesQty","SubmittedAt")
Properties = Array("BlueDeliveryDate","BlueEnvelopeProvider","BlueHasNonprofitStatus","BlueNonprofitAuthCode","BluePermitCity","BluePermitClass","BluePermitNumber","BluePermitOwnership","BluePrintPermit","BluePrintReturnAddress","BlueWantsQuote","ContactName","FutureVoterStickerRolls","IVotedStickerRolls","MailingEstimatedQuantity","MailingHasNonprofitStatus","MailingPickupDate","MailingPostageOption","MailingWantsService","MailingWantsSorting","Municipality","OrderDetailID","OrderID","Phone","PurpleBlueProvider","PurpleBlueProviderOther","PurpleColorCodingBy","PurpleColorNames","PurpleDeliveryDate","PurpleEnvelopeProvider","PurpleEnvelopeStock","PurpleExtraEnvelopeQty","PurplePrecinctCount","PurplePrintOption","PurplePrintStyle","PurpleTrackMIBallot","PurpleWantsBlueEnvelopes","PurpleWantsQuote","SecrecySleevesQty","SpecialRequests","SubmittedAt")
End Sub End Sub


Public Property Get PrimaryKey() Public Property Get PrimaryKey()
@@ -123,6 +139,36 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get BlueHasNonprofitStatus()
BlueHasNonprofitStatus = pBlueHasNonprofitStatus
End Property

Public Property Let BlueHasNonprofitStatus(val)
On Error Resume Next
If IsNull(val) Then
pBlueHasNonprofitStatus = Null
Else
pBlueHasNonprofitStatus = CBool(val)
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.BlueHasNonprofitStatus", "Invalid value for BlueHasNonprofitStatus: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get BlueNonprofitAuthCode()
BlueNonprofitAuthCode = pBlueNonprofitAuthCode
End Property

Public Property Let BlueNonprofitAuthCode(val)
On Error Resume Next
pBlueNonprofitAuthCode = val ' kept as text - authorization codes may have leading zeros
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.BlueNonprofitAuthCode", "Invalid value for BlueNonprofitAuthCode: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get BluePermitCity() Public Property Get BluePermitCity()
BluePermitCity = pBluePermitCity BluePermitCity = pBluePermitCity
End Property End Property
@@ -170,6 +216,23 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get BluePermitOwnership()
BluePermitOwnership = pBluePermitOwnership
End Property

Public Property Let BluePermitOwnership(val)
On Error Resume Next
If IsNumeric(val) Then
pBluePermitOwnership = CDbl(val)
Else
pBluePermitOwnership = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.BluePermitOwnership", "Invalid value for BluePermitOwnership: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get BluePrintPermit() Public Property Get BluePrintPermit()
BluePrintPermit = pBluePrintPermit BluePrintPermit = pBluePrintPermit
End Property End Property
@@ -272,6 +335,23 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get MailingEstimatedQuantity()
MailingEstimatedQuantity = pMailingEstimatedQuantity
End Property

Public Property Let MailingEstimatedQuantity(val)
On Error Resume Next
If IsNumeric(val) Then
pMailingEstimatedQuantity = CDbl(val)
Else
pMailingEstimatedQuantity = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.MailingEstimatedQuantity", "Invalid value for MailingEstimatedQuantity: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get MailingHasNonprofitStatus() Public Property Get MailingHasNonprofitStatus()
MailingHasNonprofitStatus = pMailingHasNonprofitStatus MailingHasNonprofitStatus = pMailingHasNonprofitStatus
End Property End Property
@@ -421,6 +501,40 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get PurpleBlueProvider()
PurpleBlueProvider = pPurpleBlueProvider
End Property

Public Property Let PurpleBlueProvider(val)
On Error Resume Next
If IsNumeric(val) Then
pPurpleBlueProvider = CDbl(val)
Else
pPurpleBlueProvider = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.PurpleBlueProvider", "Invalid value for PurpleBlueProvider: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get PurpleBlueProviderOther()
PurpleBlueProviderOther = pPurpleBlueProviderOther
End Property

Public Property Let PurpleBlueProviderOther(val)
On Error Resume Next
If IsNumeric(val) Then
pPurpleBlueProviderOther = CDbl(val)
Else
pPurpleBlueProviderOther = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.PurpleBlueProviderOther", "Invalid value for PurpleBlueProviderOther: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get PurpleColorCodingBy() Public Property Get PurpleColorCodingBy()
PurpleColorCodingBy = pPurpleColorCodingBy PurpleColorCodingBy = pPurpleColorCodingBy
End Property End Property
@@ -438,6 +552,23 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get PurpleColorNames()
PurpleColorNames = pPurpleColorNames
End Property

Public Property Let PurpleColorNames(val)
On Error Resume Next
If IsNumeric(val) Then
pPurpleColorNames = CDbl(val)
Else
pPurpleColorNames = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.PurpleColorNames", "Invalid value for PurpleColorNames: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get PurpleDeliveryDate() Public Property Get PurpleDeliveryDate()
PurpleDeliveryDate = pPurpleDeliveryDate PurpleDeliveryDate = pPurpleDeliveryDate
End Property End Property
@@ -625,6 +756,23 @@ Class POBO_OrderDetails
On Error GoTo 0 On Error GoTo 0
End Property End Property


Public Property Get SpecialRequests()
SpecialRequests = pSpecialRequests
End Property

Public Property Let SpecialRequests(val)
On Error Resume Next
If IsNumeric(val) Then
pSpecialRequests = CDbl(val)
Else
pSpecialRequests = val
End If
If Err.Number <> 0 Then
Err.Raise Err.Number, "POBO_OrderDetails.SpecialRequests", "Invalid value for SpecialRequests: " & Err.Description
End If
On Error GoTo 0
End Property

Public Property Get SubmittedAt() Public Property Get SubmittedAt()
SubmittedAt = pSubmittedAt SubmittedAt = pSubmittedAt
End Property End Property


+ 230
- 68
app/views/Order/continue.asp Просмотреть файл

@@ -18,6 +18,20 @@


<div id="surveyContainer" style="max-width: 760px; margin: 0 auto 64px; padding: 0 16px;"></div> <div id="surveyContainer" style="max-width: 760px; margin: 0 auto 64px; padding: 0 16px;"></div>


<div id="colorPickerOverlay" style="display:none; position:fixed; inset:0; background:rgba(36,16,58,0.55); z-index:1000; align-items:center; justify-content:center; padding:16px;">
<div style="background:#fff; border-radius:14px; max-width:640px; width:100%; max-height:85vh; display:flex; flex-direction:column; overflow:hidden; box-shadow:0 12px 40px rgba(36,16,58,0.35);">
<div style="display:flex; align-items:center; justify-content:space-between; padding:20px 24px; border-bottom:1px solid #f0e7f8;">
<h3 style="margin:0; color:#201a27; font-size:18px;">Choose your colors</h3>
<button type="button" id="colorPickerCloseBtn" aria-label="Close" style="background:none; border:none; font-size:22px; line-height:1; color:#6d6574; cursor:pointer; padding:4px 8px;">&times;</button>
</div>
<div id="colorPickerGrid" style="overflow-y:auto; padding:20px 24px; display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:12px;"></div>
<div style="display:flex; justify-content:flex-end; gap:10px; padding:16px 24px; border-top:1px solid #f0e7f8;">
<button type="button" id="colorPickerCancelBtn" class="button button-secondary">Cancel</button>
<button type="button" id="colorPickerApplyBtn" class="button button-primary">Apply</button>
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/survey-core@2.5.36/survey.core.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/survey-core@2.5.36/survey.core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/survey-js-ui@2.5.36/survey-js-ui.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/survey-js-ui@2.5.36/survey-js-ui.min.js"></script>
<script> <script>
@@ -28,12 +42,16 @@
var csrfToken = "<%= H(csrfToken) %>"; var csrfToken = "<%= H(csrfToken) %>";


// Election-materials order form. Field (name) values match the OrderDetails table // Election-materials order form. Field (name) values match the OrderDetails table
// columns 1:1 - see db/migrations/20260728145000_create_order_details_table.asp.
// Content and branching sourced from docs/lucid/*.pdf.
// columns 1:1 - see db/migrations/20260728145000_create_order_details_table.asp and
// db/migrations/20260804153857_revise_order_details_columns.asp.
// Content and branching sourced from docs/lucid/*.pdf (the "(1)" files are the current
// revision - see docs/lucid for both the original and revised versions).
var surveyJson = { var surveyJson = {
showProgressBar: "top", showProgressBar: "top",
showQuestionNumbers: "off", showQuestionNumbers: "off",
completeText: "Submit Order", completeText: "Submit Order",
checkErrorsMode: "onNextPage",
completedHtml: "<h3>Thank you for submitting your order.</h3>",
pages: [ pages: [
{ {
name: "contact", name: "contact",
@@ -46,53 +64,72 @@
}, },
{ {
name: "purpleEnvelope", name: "purpleEnvelope",
title: "2. Purple Ballot Envelope Quote Request",
title: "2. Purple Ballot Envelope Order Form",
elements: [ elements: [
{ {
type: "boolean", name: "PurpleWantsQuote", labelTrue: "Yes", labelFalse: "No", type: "boolean", name: "PurpleWantsQuote", labelTrue: "Yes", labelFalse: "No",
title: "Would you like a quote for KCI to print your purple AV envelopes?"
},
{
type: "radiogroup", name: "PurplePrintOption",
title: "Would you like KCI to print addresses on your purple envelopes or return postage only?",
visibleIf: "{PurpleWantsQuote} = true",
choices: [
{ value: "AddressesAndPostage", text: "Addresses and return postage" },
{ value: "PostageOnly", text: "Return postage only" }
]
title: "Would you like for KCI to print your purple AV envelopes?",
isRequired: true
}, },
{ {
type: "radiogroup", name: "PurpleEnvelopeStock", type: "radiogroup", name: "PurpleEnvelopeStock",
title: "Are you planning to use KCI's purple envelopes or from your own stock?", title: "Are you planning to use KCI's purple envelopes or from your own stock?",
visibleIf: "{PurplePrintOption} = 'AddressesAndPostage'",
visibleIf: "{PurpleWantsQuote} = true",
isRequired: true,
choices: [ choices: [
{ value: "KCIStock", text: "KCI's stock" }, { value: "KCIStock", text: "KCI's stock" },
{ value: "OwnStock", text: "My own stock" } { value: "OwnStock", text: "My own stock" }
] ]
}, },
{ {
type: "text", name: "PurpleEnvelopeProvider",
title: "Who is your purple envelope provider?",
visibleIf: "{PurpleEnvelopeStock} = 'OwnStock'"
type: "radiogroup", name: "PurplePrintOption",
title: "Would you like KCI to print addresses on your purple envelopes or state of Michigan permit only?",
visibleIf: "{PurpleWantsQuote} = true",
isRequired: true,
choices: [
{ value: "AddressesAndPermit", text: "Addresses and state of Michigan permit" },
{ value: "PermitOnly", text: "State of Michigan permit only" }
]
}, },
{ {
type: "boolean", name: "PurpleWantsBlueEnvelopes", labelTrue: "Yes", labelFalse: "No", type: "boolean", name: "PurpleWantsBlueEnvelopes", labelTrue: "Yes", labelFalse: "No",
title: "Are you planning to use KCI blue envelopes?", title: "Are you planning to use KCI blue envelopes?",
visibleIf: "{PurplePrintOption} = 'AddressesAndPostage'"
visibleIf: "{PurplePrintOption} = 'AddressesAndPermit'",
isRequired: true
},
{
type: "radiogroup", name: "PurpleBlueProvider",
title: "Who is your blue envelope provider?",
visibleIf: "{PurpleWantsBlueEnvelopes} = false",
isRequired: true,
choices: [
{ value: "ElectionSource", text: "ElectionSource" },
{ value: "PSI", text: "PSI" },
{ value: "Spectrum", text: "Spectrum" },
{ value: "Other", text: "Other" }
]
},
{
type: "text", name: "PurpleBlueProviderOther",
title: "Please specify your blue envelope provider",
visibleIf: "{PurpleBlueProvider} = 'Other'",
isRequired: true
}, },
{ {
type: "radiogroup", name: "PurplePrintStyle", type: "radiogroup", name: "PurplePrintStyle",
title: "Would you like your envelopes printed with color coding or black only?",
visibleIf: "{PurplePrintOption} = 'AddressesAndPostage'",
title: "Would you like your envelopes printed with color coding or black ink only?",
visibleIf: "{PurplePrintOption} = 'AddressesAndPermit'",
isRequired: true,
choices: [ choices: [
{ value: "ColorCoding", text: "Color Coding" }, { value: "ColorCoding", text: "Color Coding" },
{ value: "BlackOnly", text: "Black Only" }
{ value: "BlackOnly", text: "Black Ink Only" }
] ]
}, },
{ {
type: "radiogroup", name: "PurpleColorCodingBy", type: "radiogroup", name: "PurpleColorCodingBy",
title: "Color coding by precinct or by election?", title: "Color coding by precinct or by election?",
visibleIf: "{PurplePrintStyle} = 'ColorCoding'", visibleIf: "{PurplePrintStyle} = 'ColorCoding'",
isRequired: true,
choices: [ choices: [
{ value: "Precinct", text: "Precinct" }, { value: "Precinct", text: "Precinct" },
{ value: "Election", text: "Election" } { value: "Election", text: "Election" }
@@ -101,91 +138,114 @@
{ {
type: "text", name: "PurplePrecinctCount", title: "How many precincts?", type: "text", name: "PurplePrecinctCount", title: "How many precincts?",
inputType: "number", min: 0, inputType: "number", min: 0,
visibleIf: "{PurpleColorCodingBy} = 'Precinct'"
visibleIf: "{PurpleColorCodingBy} = 'Precinct'",
isRequired: true
},
{
type: "html",
visibleIf: "{PurplePrintStyle} = 'ColorCoding'",
html: "<button type=\"button\" id=\"openColorPickerBtn\" class=\"button button-secondary\">Choose Colors&hellip;</button>"
},
{
type: "text", name: "PurpleColorNames", readOnly: true,
title: "Which colors would you like to use?",
description: "Use the \"Choose Colors…\" button above to pick from KCI's available envelope colors.",
visibleIf: "{PurplePrintStyle} = 'ColorCoding'",
isRequired: true
}, },
{ {
type: "boolean", name: "PurpleTrackMIBallot", labelTrue: "Yes", labelFalse: "No", type: "boolean", name: "PurpleTrackMIBallot", labelTrue: "Yes", labelFalse: "No",
title: "Would you like to track ballots using TrackMI Ballot?", title: "Would you like to track ballots using TrackMI Ballot?",
visibleIf: "{PurplePrintOption} = 'AddressesAndPostage'"
visibleIf: "{PurplePrintOption} = 'AddressesAndPermit'",
isRequired: true
}, },
{ {
type: "text", name: "PurpleExtraEnvelopeQty", type: "text", name: "PurpleExtraEnvelopeQty",
title: "How many extra purple envelopes would you like? (If none, please put zero)", title: "How many extra purple envelopes would you like? (If none, please put zero)",
inputType: "number", min: 0, inputType: "number", min: 0,
visibleIf: "{PurplePrintOption} = 'AddressesAndPostage'"
visibleIf: "{PurplePrintOption} = 'AddressesAndPermit'",
isRequired: true
}, },
{ {
type: "text", name: "PurpleDeliveryDate", inputType: "date",
title: "Please provide a date you would like these purple envelopes delivered.",
visibleIf: "{PurpleWantsQuote} = true"
type: "html",
visibleIf: "{PurpleWantsQuote} = true",
html: "<p>Purple envelopes are usually delivered or shipped 3 to 5 days after proof is approved.</p>"
} }
] ]
}, },
{ {
name: "blueEnvelope", name: "blueEnvelope",
title: "3. Blue AV Envelope Quote Request",
title: "3. Blue AV Envelope Order Form",
elements: [ elements: [
{ {
type: "boolean", name: "BlueWantsQuote", labelTrue: "Yes", labelFalse: "No", type: "boolean", name: "BlueWantsQuote", labelTrue: "Yes", labelFalse: "No",
title: "Would you like to purchase blue AV envelopes from KCI?"
title: "Would you like to purchase blue AV envelopes from KCI?",
isRequired: true
}, },
{ {
type: "radiogroup", name: "BlueEnvelopeProvider",
title: "Are you planning to use KCI's blue envelopes or another provider's?",
type: "boolean", name: "BluePrintPermit", labelTrue: "Yes", labelFalse: "No",
title: "Would you like KCI to print a permit on your blue envelope?",
visibleIf: "{BlueWantsQuote} = true", visibleIf: "{BlueWantsQuote} = true",
choices: [
{ value: "KCI", text: "KCI" },
{ value: "OtherProvider", text: "Other provider" }
]
isRequired: true
}, },
{ {
type: "boolean", name: "BluePrintPermit", labelTrue: "Yes", labelFalse: "No",
title: "Would you like KCI to print a permit on your blue envelope?",
visibleIf: "{BlueEnvelopeProvider} = 'KCI'"
type: "radiogroup", name: "BluePermitOwnership",
title: "Will you be using KCI's permit or your own?",
visibleIf: "{BluePrintPermit} = true",
isRequired: true,
choices: [
{ value: "KCIPermit", text: "KCI permit" },
{ value: "OwnPermit", text: "My organization's permit" }
]
}, },
{ {
type: "text", name: "BluePermitNumber", title: "Permit Number",
visibleIf: "{BluePrintPermit} = true"
type: "html",
visibleIf: "{BluePermitOwnership} = 'KCIPermit'",
html: "<p><strong>Please note, envelopes with KCI's permit MUST be mailed from KCI.</strong></p>"
}, },
{ {
type: "text", name: "BluePermitCity", title: "City of permit holder",
visibleIf: "{BluePrintPermit} = true"
type: "boolean", name: "BlueHasNonprofitStatus", labelTrue: "Yes", labelFalse: "No",
title: "Does your organization have confirmed nonprofit status with USPS?",
visibleIf: "{BluePermitOwnership} = 'OwnPermit'",
isRequired: true
}, },
{ {
type: "radiogroup", name: "BluePermitClass", title: "NP or STD",
visibleIf: "{BluePrintPermit} = true",
choices: [
{ value: "NP", text: "NP" },
{ value: "STD", text: "STD" }
]
type: "text", name: "BlueNonprofitAuthCode",
title: "Please provide your nonprofit authorization code.",
visibleIf: "{BlueHasNonprofitStatus} = true",
isRequired: true
}, },
{ {
type: "boolean", name: "BluePrintReturnAddress", labelTrue: "Yes", labelFalse: "No",
title: "Would you like KCI to print return address information on the back of the blue envelope?",
visibleIf: "{BlueEnvelopeProvider} = 'KCI'"
type: "text", name: "BluePermitCity", title: "City of permit holder",
description: "Please provide the following information.",
visibleIf: "{BlueHasNonprofitStatus} = false",
isRequired: true
}, },
{ {
type: "text", name: "BlueDeliveryDate", inputType: "date",
title: "Please provide a date you would like the blue envelopes delivered.",
visibleIf: "{BlueWantsQuote} = true"
type: "text", name: "BluePermitNumber", title: "Permit Number",
visibleIf: "{BlueHasNonprofitStatus} = false",
isRequired: true
} }
] ]
}, },
{ {
name: "mailingService", name: "mailingService",
title: "4. Ballot Mailing Service Quote Request",
title: "4. Ballot Mailing Service",
elements: [ elements: [
{ {
type: "boolean", name: "MailingWantsService", labelTrue: "Yes", labelFalse: "No", type: "boolean", name: "MailingWantsService", labelTrue: "Yes", labelFalse: "No",
title: "Would you like to save postage and have KCI mail your ballots?"
title: "Would you like to save postage and have KCI mail your ballots?",
isRequired: true
}, },
{ {
type: "radiogroup", name: "MailingPostageOption", type: "radiogroup", name: "MailingPostageOption",
title: "Would you like KCI to apply postage?", title: "Would you like KCI to apply postage?",
visibleIf: "{MailingWantsService} = true", visibleIf: "{MailingWantsService} = true",
isRequired: true,
choices: [ choices: [
{ value: "FirstClass", text: "Yes, at First Class Rate" },
{ value: "NonprofitRate", text: "Yes, at Nonprofit Rate" },
{ value: "FirstClass", text: "Yes, at First Class Rate ($0.721/pc.)" },
{ value: "NonprofitRate", text: "Yes, at Nonprofit Rate ($0.263/pc.)" },
{ value: "PresortStandard", text: "Yes, at Presort Standard Rate ($0.473/pc.)" },
{ value: "No", text: "No" } { value: "No", text: "No" }
] ]
}, },
@@ -193,6 +253,7 @@
type: "radiogroup", name: "MailingHasNonprofitStatus", type: "radiogroup", name: "MailingHasNonprofitStatus",
title: "Do you have Nonprofit Status with the USPS?", title: "Do you have Nonprofit Status with the USPS?",
visibleIf: "{MailingPostageOption} = 'NonprofitRate'", visibleIf: "{MailingPostageOption} = 'NonprofitRate'",
isRequired: true,
choices: [ choices: [
{ value: "Yes", text: "Yes" }, { value: "Yes", text: "Yes" },
{ value: "No", text: "No" }, { value: "No", text: "No" },
@@ -200,12 +261,29 @@
] ]
}, },
{ {
type: "boolean", name: "MailingWantsSorting", labelTrue: "Yes", labelFalse: "No",
title: "Would you like KCI to sort your ballots?"
type: "text", name: "MailingEstimatedQuantity",
title: "Please provide your estimated quantity.",
inputType: "number", min: 0,
visibleIf: "{MailingWantsService} = true",
isRequired: true
}, },
{ {
type: "text", name: "MailingPickupDate", inputType: "date",
title: "What is your preferred (first) pickup date?"
type: "dropdown", name: "MailingPickupDate",
title: "What is your preferred (first) pickup date?",
visibleIf: "{MailingWantsService} = true",
isRequired: true,
choices: [
{ value: "2026-09-21", text: "September 21, 2026" },
{ value: "2026-09-22", text: "September 22, 2026" },
{ value: "2026-09-23", text: "September 23, 2026" },
{ value: "2026-09-24", text: "September 24, 2026" },
{ value: "2026-09-25", text: "September 25, 2026" },
{ value: "2026-09-28", text: "September 28, 2026" },
{ value: "2026-09-29", text: "September 29, 2026" },
{ value: "2026-09-30", text: "September 30, 2026" },
{ value: "2026-10-01", text: "October 1, 2026" },
{ value: "2026-10-02", text: "October 2, 2026" }
]
} }
] ]
}, },
@@ -215,15 +293,22 @@
elements: [ elements: [
{ {
type: "text", name: "SecrecySleevesQty", title: "Secrecy Sleeves (quantity)", type: "text", name: "SecrecySleevesQty", title: "Secrecy Sleeves (quantity)",
inputType: "number", min: 0, defaultValue: 0
inputType: "number", min: 0, defaultValue: 0,
isRequired: true
}, },
{ {
type: "text", name: "IVotedStickerRolls", title: "\"I Voted\" Stickers (rolls of 250)",
inputType: "number", min: 0, defaultValue: 0
type: "text", name: "IVotedStickerRolls", title: "\"I Voted\" Stickers - number of rolls (rolls of 250)",
inputType: "number", min: 0, defaultValue: 0,
isRequired: true
}, },
{ {
type: "text", name: "FutureVoterStickerRolls", title: "\"Future Voter\" Stickers (rolls of 500)",
inputType: "number", min: 0, defaultValue: 0
type: "text", name: "FutureVoterStickerRolls", title: "\"Future Voter\" Stickers - number of rolls (rolls of 500)",
inputType: "number", min: 0, defaultValue: 0,
isRequired: true
},
{
type: "comment", name: "SpecialRequests",
title: "We will send you a copy of your price quote upon completion of this order form. If you have any special requests for any of your orders, please let us know here."
} }
] ]
} }
@@ -232,6 +317,83 @@


var survey = new Survey.Model(surveyJson); var survey = new Survey.Model(surveyJson);


// Color picker modal for the "Which colors would you like to use?" question. Swatches are
// the pre-converted PNGs in public/images/purple-envelope-colors/ (converted from the
// original public/images/Purple_ballot_envelopes colors/*.bmp - those BMPs were ~400KB
// each; PNG compresses these flat-color swatches down to ~1-4KB each).
(function () {
var COLOR_FILES = [
"Aqua", "Black", "Blue", "Brown", "BurlyWood", "Chocolate", "Clay", "Coral",
"CornflowerBlue", "Crimson", "DarkOrange", "DeepPink", "DeepSkyBlue", "DimGray",
"DodgerBlue", "FireBrick", "ForestGreen", "Fuchsia", "Gold", "Goldenrod", "Green",
"HotPink", "Indigo", "LightSeaGreen", "Lime", "LimeGreen", "LtGreen", "MediumOrchid",
"MediumPurple", "MediumTurquoise", "MintGreen", "Navy", "Olive", "OliveDrab", "Orange",
"OrangeRed", "Orchid", "PastelBlue", "PastelPink", "PastelPurple", "PastelYellow",
"Peru", "Pink", "Purple", "Red", "RoyalBlue", "SaddleBrown", "SeaGreen", "Sienna",
"Silver", "SkyBlue", "SteelBlue", "Tan", "Teal", "Tomato", "Turquoise", "Violet",
"White", "Yellow"
];
var colorImageBaseUrl = "<%= H(Routes().AppURL & "images/purple-envelope-colors/") %>";
var overlay = document.getElementById("colorPickerOverlay");
var grid = document.getElementById("colorPickerGrid");

function colorLabel(fileName) {
return fileName.replace(/([a-z])([A-Z])/g, "$1 $2");
}

COLOR_FILES.forEach(function (fileName) {
var label = colorLabel(fileName);
var item = document.createElement("label");
item.style.cssText = "display:flex; flex-direction:column; gap:6px; border:1px solid #f0e7f8; border-radius:8px; padding:8px; cursor:pointer;";
item.innerHTML =
'<img src="' + colorImageBaseUrl + encodeURIComponent(fileName) + '.png" alt="" ' +
'style="width:100%; height:36px; border-radius:4px; object-fit:cover; border:1px solid #e5d9f2;" />' +
'<span style="display:flex; align-items:center; gap:6px; font-size:13px; color:#201a27;">' +
'<input type="checkbox" class="color-picker-checkbox" value="' + label.replace(/"/g, "&quot;") + '" /> ' +
label + "</span>";
grid.appendChild(item);
});

function openColorPicker() {
var current = (survey.getValue("PurpleColorNames") || "")
.split(",")
.map(function (s) { return s.trim(); })
.filter(Boolean);
var currentSet = {};
current.forEach(function (c) { currentSet[c] = true; });
var checkboxes = grid.querySelectorAll(".color-picker-checkbox");
checkboxes.forEach(function (cb) { cb.checked = !!currentSet[cb.value]; });
overlay.style.display = "flex";
}

function closeColorPicker() {
overlay.style.display = "none";
}

function applyColorPicker() {
var checked = grid.querySelectorAll(".color-picker-checkbox:checked");
var selected = Array.prototype.map.call(checked, function (cb) { return cb.value; });
survey.setValue("PurpleColorNames", selected.join(", "));
closeColorPicker();
}

document.getElementById("colorPickerCloseBtn").addEventListener("click", closeColorPicker);
document.getElementById("colorPickerCancelBtn").addEventListener("click", closeColorPicker);
document.getElementById("colorPickerApplyBtn").addEventListener("click", applyColorPicker);
overlay.addEventListener("click", function (event) {
if (event.target === overlay) closeColorPicker();
});

// The "Choose Colors..." button is rendered by SurveyJS as an html question, so it
// doesn't exist in the DOM until that page is shown - delegate from a stable ancestor.
document.addEventListener("click", function (event) {
if (event.target && event.target.id === "openColorPickerBtn") {
event.preventDefault();
openColorPicker();
}
});
})();

survey.onComplete.add(function (sender) { survey.onComplete.add(function (sender) {
fetch(submitUrl, { fetch(submitUrl, {
method: "POST", method: "POST",
@@ -251,7 +413,7 @@
if (result.ok && result.body && result.body.success) { if (result.ok && result.body && result.body.success) {
container.innerHTML = container.innerHTML =
'<p style="text-align:center; padding: 32px 0;">' + '<p style="text-align:center; padding: 32px 0;">' +
"Thanks! Your order details have been submitted." +
"Thank you for submitting your order." +
"</p>"; "</p>";
} else { } else {
alert((result.body && result.body.error) || "Something went wrong submitting your order. Please try again."); alert((result.body && result.body.error) || "Something went wrong submitting your order. Please try again.");


+ 59
- 0
db/migrations/20260804153857_revise_order_details_columns.asp Просмотреть файл

@@ -0,0 +1,59 @@
<%
'=======================================================================================================================
' MIGRATION: revise_order_details_columns
'=======================================================================================================================
' This migration was auto-generated. Add your migration logic below.
'
' The migration object provides these helper methods:
' - migration.ExecuteSQL(sql) - Execute raw SQL
' - migration.CreateTable(name, columns) - Create a table
' - migration.DropTable(name) - Drop a table
' - migration.AddColumn(table, column, type) - Add a column
' - migration.DropColumn(table, column) - Drop a column
' - migration.CreateIndex(name, table, columns) - Create an index
' - migration.DropIndex(name, table) - Drop an index
'
' For complex operations, use migration.DB to access the database directly:
' migration.DB.Execute "INSERT INTO users (name) VALUES (?)", Array("John")
'

'-----------------------------------------------------------------------------------------------------------------------
' UP - Apply the migration
'-----------------------------------------------------------------------------------------------------------------------
Sub Migration_Up(migration)
' Fields added by the revised order-form PDFs (docs/lucid/*"(1).pdf"). Additive only -
' columns made obsolete by the revision (BluePermitClass, BluePrintReturnAddress,
' BlueDeliveryDate, MailingWantsSorting, PurpleEnvelopeProvider) are left in place rather
' than dropped, since the table already has real test data in it.

' Purple Ballot Envelope section
migration.AddColumn "OrderDetails", "PurpleColorNames", "VARCHAR(255)"
migration.AddColumn "OrderDetails", "PurpleBlueProvider", "VARCHAR(50)"
migration.AddColumn "OrderDetails", "PurpleBlueProviderOther", "VARCHAR(255)"

' Blue AV Envelope section - new permit-ownership/nonprofit-status sub-flow
migration.AddColumn "OrderDetails", "BluePermitOwnership", "VARCHAR(20)"
migration.AddColumn "OrderDetails", "BlueHasNonprofitStatus", "YESNO"
migration.AddColumn "OrderDetails", "BlueNonprofitAuthCode", "VARCHAR(100)"

' Ballot Mailing Service section
migration.AddColumn "OrderDetails", "MailingEstimatedQuantity", "INTEGER"

' General - end-of-form special requests
migration.AddColumn "OrderDetails", "SpecialRequests", "MEMO"
End Sub

'-----------------------------------------------------------------------------------------------------------------------
' DOWN - Rollback the migration
'-----------------------------------------------------------------------------------------------------------------------
Sub Migration_Down(migration)
migration.DropColumn "OrderDetails", "PurpleColorNames"
migration.DropColumn "OrderDetails", "PurpleBlueProvider"
migration.DropColumn "OrderDetails", "PurpleBlueProviderOther"
migration.DropColumn "OrderDetails", "BluePermitOwnership"
migration.DropColumn "OrderDetails", "BlueHasNonprofitStatus"
migration.DropColumn "OrderDetails", "BlueNonprofitAuthCode"
migration.DropColumn "OrderDetails", "MailingEstimatedQuantity"
migration.DropColumn "OrderDetails", "SpecialRequests"
End Sub
%>

Двоичные данные
docs/lucid/Election Materials Order Form #1 (1).pdf Просмотреть файл


Двоичные данные
docs/lucid/Election Materials Request #3 (1).pdf Просмотреть файл


Двоичные данные
docs/lucid/Election Materials Request Form #2 (1).pdf Просмотреть файл


Двоичные данные
public/images/purple-envelope-colors/Aqua.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 772B

Двоичные данные
public/images/purple-envelope-colors/Black.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 522B

Двоичные данные
public/images/purple-envelope-colors/Blue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 773B

Двоичные данные
public/images/purple-envelope-colors/Brown.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/BurlyWood.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Chocolate.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Clay.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 852B

Двоичные данные
public/images/purple-envelope-colors/Coral.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/CornflowerBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Crimson.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 852B

Двоичные данные
public/images/purple-envelope-colors/DarkOrange.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 773B

Двоичные данные
public/images/purple-envelope-colors/DeepPink.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/DeepSkyBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 774B

Двоичные данные
public/images/purple-envelope-colors/DimGray.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 847B

Двоичные данные
public/images/purple-envelope-colors/DodgerBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/FireBrick.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/ForestGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/Fuchsia.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 844B

Двоичные данные
public/images/purple-envelope-colors/Gold.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Goldenrod.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Green.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 773B

Двоичные данные
public/images/purple-envelope-colors/HotPink.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/Indigo.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/LightSeaGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Lime.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 773B

Двоичные данные
public/images/purple-envelope-colors/LimeGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/LtGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/MediumOrchid.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/MediumPurple.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/MediumTurquoise.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/MintGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Navy.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 775B

Двоичные данные
public/images/purple-envelope-colors/Olive.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 772B

Двоичные данные
public/images/purple-envelope-colors/OliveDrab.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Orange.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 774B

Двоичные данные
public/images/purple-envelope-colors/OrangeRed.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 774B

Двоичные данные
public/images/purple-envelope-colors/Orchid.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/PastelBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/PastelPink.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 852B

Двоичные данные
public/images/purple-envelope-colors/PastelPurple.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/PastelYellow.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/Peru.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Pink.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Purple.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 844B

Двоичные данные
public/images/purple-envelope-colors/Red.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 773B

Двоичные данные
public/images/purple-envelope-colors/RoyalBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/SaddleBrown.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/SeaGreen.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Sienna.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Silver.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 847B

Двоичные данные
public/images/purple-envelope-colors/SkyBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/SteelBlue.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Tan.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 852B

Двоичные данные
public/images/purple-envelope-colors/Teal.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 772B

Двоичные данные
public/images/purple-envelope-colors/Tomato.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 851B

Двоичные данные
public/images/purple-envelope-colors/Turquoise.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 852B

Двоичные данные
public/images/purple-envelope-colors/Violet.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 850B

Двоичные данные
public/images/purple-envelope-colors/White.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 846B

Двоичные данные
public/images/purple-envelope-colors/Yellow.png Просмотреть файл

До После
Ширина: 900  |  Высота: 150  |  Размер: 772B

Загрузка…
Отмена
Сохранить

Powered by TurnKey Linux.