| @@ -99,13 +99,173 @@ Class KitController | |||
| set Model.Kit = KitRepository.SwitchBoardPurpleEnvelopeEditFindById(id) | |||
| set Model.StidDropDown = SettingsRepository.GetStidDropDownRS() | |||
| set Model.ColorsDropDown = ColorsRepository.GetColorsDropDownRS() | |||
| set Model.Precincts = InkjetRecordsRepository.GetDistinctPrecinctsByKitId(id) | |||
| set Model.Precincts = SortPrecinctColorRows(InkjetRecordsRepository.GetDistinctPrecinctsByKitId(id)) | |||
| set Model.PrecinctBallotRanges = SortPrecinctBallotRangeRows(InkjetRecordsRepository.GetPrecinctBallotRangesByKitId(id)) | |||
| On Error Resume Next | |||
| Model.PurpleEnvelopeElectionLabel = FormatPurpleEnvelopeElectionLabel(SettingsRepository.FindByName("Electiondate")) | |||
| If Err.Number <> 0 Then | |||
| Model.PurpleEnvelopeElectionLabel = "" | |||
| Err.Clear | |||
| End If | |||
| On Error GoTo 0 | |||
| Model.Title = "Purple Envelopes for " | |||
| HTMLSecurity.SetAntiCSRFToken "KitEditForm" | |||
| HTMLSecurity.SetAntiCSRFToken "ColorAssignForm" | |||
| %> <!--#include file="../../Views/Kit/SwitchBoardPurpleEnvelopeEdit.asp"--> <% | |||
| End Sub | |||
| Private Function FormatPurpleEnvelopeElectionLabel(ByVal rawValue) | |||
| FormatPurpleEnvelopeElectionLabel = Trim(rawValue & "") | |||
| If Len(FormatPurpleEnvelopeElectionLabel) = 0 Then Exit Function | |||
| On Error Resume Next | |||
| dim parsedDate : parsedDate = CDate(rawValue) | |||
| If Err.Number = 0 Then | |||
| FormatPurpleEnvelopeElectionLabel = MonthName(Month(parsedDate), True) & "-" & CStr(Year(parsedDate)) | |||
| Else | |||
| Err.Clear | |||
| End If | |||
| On Error GoTo 0 | |||
| End Function | |||
| Private Function SortPrecinctColorRows(ByVal rs) | |||
| dim list : set list = new LinkedList_Class | |||
| If rs.EOF Then | |||
| set SortPrecinctColorRows = list | |||
| Exit Function | |||
| End If | |||
| dim items() | |||
| dim itemCount : itemCount = -1 | |||
| Do Until rs.EOF | |||
| itemCount = itemCount + 1 | |||
| ReDim Preserve items(itemCount) | |||
| dim row : set row = new PrecinctColorRow_ViewModel_Class | |||
| row.PRECINCT = rs("PRECINCT") | |||
| If IsNull(rs("ColorId")) Then | |||
| row.ColorId = "" | |||
| Else | |||
| row.ColorId = rs("ColorId") | |||
| End If | |||
| Set items(itemCount) = row | |||
| rs.MoveNext | |||
| Loop | |||
| SortPrecinctItems items | |||
| dim i | |||
| For i = 0 To UBound(items) | |||
| list.Push items(i) | |||
| Next | |||
| set SortPrecinctColorRows = list | |||
| End Function | |||
| Private Function SortPrecinctBallotRangeRows(ByVal rs) | |||
| dim list : set list = new LinkedList_Class | |||
| If rs.EOF Then | |||
| set SortPrecinctBallotRangeRows = list | |||
| Exit Function | |||
| End If | |||
| dim items() | |||
| dim itemCount : itemCount = -1 | |||
| Do Until rs.EOF | |||
| itemCount = itemCount + 1 | |||
| ReDim Preserve items(itemCount) | |||
| dim row : set row = new PrecinctBallotRangeRow_ViewModel_Class | |||
| row.PRECINCT = rs("PRECINCT") | |||
| row.LowBallotNumber = rs("LowBallotNumber") | |||
| row.HighBallotNumber = rs("HighBallotNumber") | |||
| Set items(itemCount) = row | |||
| rs.MoveNext | |||
| Loop | |||
| SortPrecinctItems items | |||
| dim i | |||
| For i = 0 To UBound(items) | |||
| list.Push items(i) | |||
| Next | |||
| set SortPrecinctBallotRangeRows = list | |||
| End Function | |||
| Private Sub SortPrecinctItems(ByRef items) | |||
| If Not IsArray(items) Then Exit Sub | |||
| dim i, j | |||
| For i = 0 To UBound(items) - 1 | |||
| For j = i + 1 To UBound(items) | |||
| If PrecinctSortsBefore(items(j).PRECINCT, items(i).PRECINCT) Then | |||
| dim temp : set temp = items(i) | |||
| Set items(i) = items(j) | |||
| Set items(j) = temp | |||
| End If | |||
| Next | |||
| Next | |||
| End Sub | |||
| Private Function PrecinctSortsBefore(ByVal leftPrecinct, ByVal rightPrecinct) | |||
| dim leftType, leftNumber, leftSuffix, leftNormalized | |||
| dim rightType, rightNumber, rightSuffix, rightNormalized | |||
| ParsePrecinctSortParts leftPrecinct, leftType, leftNumber, leftSuffix, leftNormalized | |||
| ParsePrecinctSortParts rightPrecinct, rightType, rightNumber, rightSuffix, rightNormalized | |||
| If leftType <> rightType Then | |||
| PrecinctSortsBefore = (leftType < rightType) | |||
| Exit Function | |||
| End If | |||
| If leftType = 0 Then | |||
| If leftNumber <> rightNumber Then | |||
| PrecinctSortsBefore = (leftNumber < rightNumber) | |||
| Exit Function | |||
| End If | |||
| If leftSuffix <> rightSuffix Then | |||
| PrecinctSortsBefore = (leftSuffix < rightSuffix) | |||
| Exit Function | |||
| End If | |||
| End If | |||
| If leftNormalized <> rightNormalized Then | |||
| PrecinctSortsBefore = (leftNormalized < rightNormalized) | |||
| Else | |||
| PrecinctSortsBefore = (UCase(Trim(leftPrecinct & "")) < UCase(Trim(rightPrecinct & ""))) | |||
| End If | |||
| End Function | |||
| Private Sub ParsePrecinctSortParts(ByVal precinct, ByRef precinctType, ByRef numericPart, ByRef suffixPart, ByRef normalizedText) | |||
| dim rawPrecinct : rawPrecinct = Trim(precinct & "") | |||
| dim leadingDigits : leadingDigits = "" | |||
| dim i, currentChar | |||
| For i = 1 To Len(rawPrecinct) | |||
| currentChar = Mid(rawPrecinct, i, 1) | |||
| If currentChar >= "0" And currentChar <= "9" Then | |||
| leadingDigits = leadingDigits & currentChar | |||
| Else | |||
| Exit For | |||
| End If | |||
| Next | |||
| If Len(leadingDigits) > 0 Then | |||
| precinctType = 0 | |||
| numericPart = CLng(leadingDigits) | |||
| suffixPart = UCase(Trim(Mid(rawPrecinct, Len(leadingDigits) + 1))) | |||
| normalizedText = CStr(numericPart) & "|" & suffixPart | |||
| Else | |||
| precinctType = 1 | |||
| numericPart = 0 | |||
| suffixPart = UCase(rawPrecinct) | |||
| normalizedText = suffixPart | |||
| End If | |||
| End Sub | |||
| Public Sub Index | |||
| dim page_size : page_size = 10 | |||
| @@ -340,6 +340,16 @@ Class InkjetRecordsRepository_Class | |||
| set GetDistinctPrecinctsByKitId = rs | |||
| End Function | |||
| Public Function GetPrecinctBallotRangesByKitId(KitID) | |||
| dim sql : sql = "SELECT [PRECINCT], MIN(VAL([BALLOT_NUMBER])) AS [LowBallotNumber], MAX(VAL([BALLOT_NUMBER])) AS [HighBallotNumber] " &_ | |||
| "FROM [InkjetRecords] " &_ | |||
| "WHERE [KitID] = ? " &_ | |||
| "GROUP BY [PRECINCT] " &_ | |||
| "ORDER BY VAL([PRECINCT]) ASC, [PRECINCT] ASC" | |||
| dim rs : set rs = DAL.Query(sql, KitID) | |||
| set GetPrecinctBallotRangesByKitId = rs | |||
| End Function | |||
| Public Sub UpdateColorForKit(KitID, ColorId) | |||
| dim sql : sql = "UPDATE [InkjetRecords] SET [ColorId] = ? WHERE [KitID] = ?" | |||
| DAL.Execute sql, Array(ColorId, KitID) | |||
| @@ -22,6 +22,19 @@ Class SwitchBoard_ViewModel_Class | |||
| Public StidDropDown | |||
| Public ColorsDropDown | |||
| Public Precincts | |||
| Public PrecinctBallotRanges | |||
| Public PurpleEnvelopeElectionLabel | |||
| End Class | |||
| Class PrecinctColorRow_ViewModel_Class | |||
| Public PRECINCT | |||
| Public ColorId | |||
| End Class | |||
| Class PrecinctBallotRangeRow_ViewModel_Class | |||
| Public PRECINCT | |||
| Public LowBallotNumber | |||
| Public HighBallotNumber | |||
| End Class | |||
| Class SwitchBoard_PurpleEnvelopesViewModel_Class | |||
| @@ -1,6 +1,92 @@ | |||
| <h2><%= H(Model.Title & " " & Model.Kit.Jurisdiction) %></h2> | |||
| <%= HTML.Hidden("nonce", HTMLSecurity.GetAntiCSRFToken("KitEditForm")) %> | |||
| <%= HTML.Hidden("Id", Model.Kit.ID) %> | |||
| <style> | |||
| .purple-envelope-report { | |||
| max-width: 720px; | |||
| margin-top: 1.5rem; | |||
| } | |||
| .purple-envelope-report .report-title, | |||
| .purple-envelope-report .report-election-date { | |||
| text-align: center; | |||
| } | |||
| .purple-envelope-report .report-title { | |||
| font-size: 1.4rem; | |||
| margin-bottom: 1rem; | |||
| } | |||
| .purple-envelope-report .report-election-date { | |||
| font-size: 1.15rem; | |||
| margin-bottom: 1rem; | |||
| } | |||
| .purple-envelope-report, | |||
| .purple-envelope-report table, | |||
| .purple-envelope-report th, | |||
| .purple-envelope-report td { | |||
| font-size: 10pt; | |||
| } | |||
| .purple-envelope-report table th.num, | |||
| .purple-envelope-report table td.num { | |||
| text-align: right; | |||
| } | |||
| .print-page-spacer { | |||
| display: none; | |||
| } | |||
| @media print { | |||
| @page { | |||
| size: auto; | |||
| margin: 0; | |||
| } | |||
| body * { | |||
| visibility: hidden; | |||
| } | |||
| #purple-envelope-report-print, | |||
| #purple-envelope-report-print * { | |||
| visibility: visible; | |||
| } | |||
| #purple-envelope-report-print { | |||
| position: absolute; | |||
| left: 0; | |||
| top: 0; | |||
| width: 100%; | |||
| padding: 0.45in 0.25in 0.25in 0.25in; | |||
| box-sizing: border-box; | |||
| } | |||
| .d-print-none { | |||
| display: none !important; | |||
| } | |||
| .purple-envelope-report { | |||
| max-width: none; | |||
| margin-top: 0; | |||
| } | |||
| .purple-envelope-report thead { | |||
| display: table-header-group; | |||
| } | |||
| .print-page-spacer { | |||
| display: table-row; | |||
| } | |||
| .print-page-spacer th { | |||
| border: 0 !important; | |||
| height: 0.2in; | |||
| padding: 0 !important; | |||
| background: transparent !important; | |||
| } | |||
| } | |||
| </style> | |||
| <div class="row"> | |||
| <div class="col-md-6"> | |||
| <h2>Job Number: <%= Model.Kit.JobNumber %></h2> | |||
| @@ -65,15 +151,17 @@ | |||
| </thead> | |||
| <tbody> | |||
| <% | |||
| dim precinctRS : set precinctRS = Model.Precincts | |||
| dim precinctIt : set precinctIt = Model.Precincts.Iterator | |||
| dim precinctRow | |||
| dim colorsRS | |||
| Do Until precinctRS.EOF | |||
| Do While precinctIt.HasNext | |||
| set precinctRow = precinctIt.GetNext() | |||
| %> | |||
| <tr> | |||
| <td><%= H(precinctRS("PRECINCT")) %></td> | |||
| <td><%= H(precinctRow.PRECINCT) %></td> | |||
| <td> | |||
| <% If Not IsNull(precinctRS("ColorId")) AND Len(precinctRS("ColorId")) > 0 Then %> | |||
| <% dim currentColor : set currentColor = ColorsRepository.FindByID(precinctRS("ColorId")) %> | |||
| <% If Not IsNull(precinctRow.ColorId) AND Len(precinctRow.ColorId) > 0 Then %> | |||
| <% dim currentColor : set currentColor = ColorsRepository.FindByID(precinctRow.ColorId) %> | |||
| <%= H(currentColor.Name) %> | |||
| <% Else %> | |||
| <em>Not assigned</em> | |||
| @@ -83,11 +171,10 @@ | |||
| <% | |||
| set colorsRS = ColorsRepository.GetColorsDropDownRS() | |||
| %> | |||
| <%= HTML.DropDownListExt("PrecinctColor_" & precinctRS("PRECINCT"), precinctRS("ColorId"), colorsRS, "ID", "Name", Array("Class","form-select form-select-sm")) %> | |||
| <%= HTML.DropDownListExt("PrecinctColor_" & precinctRow.PRECINCT, precinctRow.ColorId, colorsRS, "ID", "Name", Array("Class","form-select form-select-sm")) %> | |||
| </td> | |||
| </tr> | |||
| <% | |||
| precinctRS.MoveNext | |||
| Loop | |||
| %> | |||
| </tbody> | |||
| @@ -101,3 +188,55 @@ | |||
| <% END IF %> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-12" id="purple-envelope-report-print"> | |||
| <div class="card mb-3 purple-envelope-report"> | |||
| <div class="card-header d-flex justify-content-between align-items-center"> | |||
| <strong>Purple Envelope Ballot Range Report</strong> | |||
| <button type="button" class="btn btn-secondary btn-sm d-print-none" onclick="window.print();">Print Report</button> | |||
| </div> | |||
| <div class="card-body"> | |||
| <div class="report-title"><%= H(Model.Kit.Jurisdiction & " " & Model.Kit.JCode) %></div> | |||
| <% If Len(Trim(Model.PurpleEnvelopeElectionLabel & "")) > 0 Then %> | |||
| <div class="report-election-date"><%= H(Model.PurpleEnvelopeElectionLabel) %></div> | |||
| <% End If %> | |||
| <table class="table table-striped table-bordered mb-0"> | |||
| <thead> | |||
| <tr class="print-page-spacer" aria-hidden="true"> | |||
| <th colspan="3"></th> | |||
| </tr> | |||
| <tr> | |||
| <th>Precinct</th> | |||
| <th class="num">Low Ballot Number</th> | |||
| <th class="num">High Ballot Number</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <% | |||
| dim ballotRangeIt : set ballotRangeIt = Model.PrecinctBallotRanges.Iterator | |||
| dim ballotRangeRow | |||
| If ballotRangeIt.HasNext Then | |||
| Do While ballotRangeIt.HasNext | |||
| set ballotRangeRow = ballotRangeIt.GetNext() | |||
| %> | |||
| <tr> | |||
| <td><%= H(ballotRangeRow.PRECINCT) %></td> | |||
| <td class="num"><%= H(ballotRangeRow.LowBallotNumber) %></td> | |||
| <td class="num"><%= H(ballotRangeRow.HighBallotNumber) %></td> | |||
| </tr> | |||
| <% | |||
| Loop | |||
| Else | |||
| %> | |||
| <tr> | |||
| <td colspan="3">No precinct ballot data found for this kit.</td> | |||
| </tr> | |||
| <% | |||
| End If | |||
| %> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
Powered by TurnKey Linux.