| @@ -99,13 +99,173 @@ Class KitController | |||||
| set Model.Kit = KitRepository.SwitchBoardPurpleEnvelopeEditFindById(id) | set Model.Kit = KitRepository.SwitchBoardPurpleEnvelopeEditFindById(id) | ||||
| set Model.StidDropDown = SettingsRepository.GetStidDropDownRS() | set Model.StidDropDown = SettingsRepository.GetStidDropDownRS() | ||||
| set Model.ColorsDropDown = ColorsRepository.GetColorsDropDownRS() | 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 " | Model.Title = "Purple Envelopes for " | ||||
| HTMLSecurity.SetAntiCSRFToken "KitEditForm" | HTMLSecurity.SetAntiCSRFToken "KitEditForm" | ||||
| HTMLSecurity.SetAntiCSRFToken "ColorAssignForm" | HTMLSecurity.SetAntiCSRFToken "ColorAssignForm" | ||||
| %> <!--#include file="../../Views/Kit/SwitchBoardPurpleEnvelopeEdit.asp"--> <% | %> <!--#include file="../../Views/Kit/SwitchBoardPurpleEnvelopeEdit.asp"--> <% | ||||
| End Sub | 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 | Public Sub Index | ||||
| dim page_size : page_size = 10 | dim page_size : page_size = 10 | ||||
| @@ -340,6 +340,16 @@ Class InkjetRecordsRepository_Class | |||||
| set GetDistinctPrecinctsByKitId = rs | set GetDistinctPrecinctsByKitId = rs | ||||
| End Function | 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) | Public Sub UpdateColorForKit(KitID, ColorId) | ||||
| dim sql : sql = "UPDATE [InkjetRecords] SET [ColorId] = ? WHERE [KitID] = ?" | dim sql : sql = "UPDATE [InkjetRecords] SET [ColorId] = ? WHERE [KitID] = ?" | ||||
| DAL.Execute sql, Array(ColorId, KitID) | DAL.Execute sql, Array(ColorId, KitID) | ||||
| @@ -22,6 +22,19 @@ Class SwitchBoard_ViewModel_Class | |||||
| Public StidDropDown | Public StidDropDown | ||||
| Public ColorsDropDown | Public ColorsDropDown | ||||
| Public Precincts | 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 | End Class | ||||
| Class SwitchBoard_PurpleEnvelopesViewModel_Class | Class SwitchBoard_PurpleEnvelopesViewModel_Class | ||||
| @@ -1,6 +1,92 @@ | |||||
| <h2><%= H(Model.Title & " " & Model.Kit.Jurisdiction) %></h2> | <h2><%= H(Model.Title & " " & Model.Kit.Jurisdiction) %></h2> | ||||
| <%= HTML.Hidden("nonce", HTMLSecurity.GetAntiCSRFToken("KitEditForm")) %> | <%= HTML.Hidden("nonce", HTMLSecurity.GetAntiCSRFToken("KitEditForm")) %> | ||||
| <%= HTML.Hidden("Id", Model.Kit.ID) %> | <%= 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="row"> | ||||
| <div class="col-md-6"> | <div class="col-md-6"> | ||||
| <h2>Job Number: <%= Model.Kit.JobNumber %></h2> | <h2>Job Number: <%= Model.Kit.JobNumber %></h2> | ||||
| @@ -65,15 +151,17 @@ | |||||
| </thead> | </thead> | ||||
| <tbody> | <tbody> | ||||
| <% | <% | ||||
| dim precinctRS : set precinctRS = Model.Precincts | |||||
| dim precinctIt : set precinctIt = Model.Precincts.Iterator | |||||
| dim precinctRow | |||||
| dim colorsRS | dim colorsRS | ||||
| Do Until precinctRS.EOF | |||||
| Do While precinctIt.HasNext | |||||
| set precinctRow = precinctIt.GetNext() | |||||
| %> | %> | ||||
| <tr> | <tr> | ||||
| <td><%= H(precinctRS("PRECINCT")) %></td> | |||||
| <td><%= H(precinctRow.PRECINCT) %></td> | |||||
| <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) %> | <%= H(currentColor.Name) %> | ||||
| <% Else %> | <% Else %> | ||||
| <em>Not assigned</em> | <em>Not assigned</em> | ||||
| @@ -83,11 +171,10 @@ | |||||
| <% | <% | ||||
| set colorsRS = ColorsRepository.GetColorsDropDownRS() | 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> | </td> | ||||
| </tr> | </tr> | ||||
| <% | <% | ||||
| precinctRS.MoveNext | |||||
| Loop | Loop | ||||
| %> | %> | ||||
| </tbody> | </tbody> | ||||
| @@ -101,3 +188,55 @@ | |||||
| <% END IF %> | <% END IF %> | ||||
| </div> | </div> | ||||
| </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.