<% ' Downtime Report - Calculate total downtime from notifications ' Based on starttime and endtime with period filter (week/month/year) Dim periodFilter, periodDays, periodLabel, sqlDateFilter periodFilter = Request.QueryString("period") ' Default to current month if no filter specified If periodFilter = "" Or periodFilter = "month" Then periodFilter = "month" periodDays = 30 periodLabel = "This Month" sqlDateFilter = "n.starttime >= DATE_SUB(NOW(), INTERVAL 30 DAY)" ElseIf periodFilter = "week" Then periodDays = 7 periodLabel = "This Week" sqlDateFilter = "n.starttime >= DATE_SUB(NOW(), INTERVAL 7 DAY)" ElseIf periodFilter = "year" Then periodDays = 365 periodLabel = "This Year" sqlDateFilter = "n.starttime >= DATE_SUB(NOW(), INTERVAL 1 YEAR)" Else ' Default fallback periodFilter = "month" periodDays = 30 periodLabel = "This Month" sqlDateFilter = "n.starttime >= DATE_SUB(NOW(), INTERVAL 30 DAY)" End If ' Query to get downtime by notification type - exclude TBD strSQL_Downtime = "SELECT " & _ "nt.typename, " & _ "nt.typecolor, " & _ "COUNT(n.notificationid) as incident_count, " & _ "SUM(TIMESTAMPDIFF(MINUTE, n.starttime, n.endtime)) as total_minutes " & _ "FROM notifications n " & _ "INNER JOIN notificationtypes nt ON n.notificationtypeid = nt.notificationtypeid " & _ "WHERE " & sqlDateFilter & " " & _ "AND n.starttime IS NOT NULL " & _ "AND n.endtime IS NOT NULL " & _ "AND n.endtime > n.starttime " & _ "AND nt.typename <> 'TBD' " & _ "GROUP BY nt.notificationtypeid, nt.typename, nt.typecolor " & _ "ORDER BY total_minutes DESC" Set rsDowntime = objconn.Execute(strSQL_Downtime) ' Calculate totals Dim totalIncidents, totalMinutes totalIncidents = 0 totalMinutes = 0 ' Build arrays for chart data Dim typeNames(), typeCounts(), typeMinutes(), typeColors() ReDim typeNames(20) ' Max 20 types ReDim typeCounts(20) ReDim typeMinutes(20) ReDim typeColors(20) Dim dtIndex dtIndex = 0 Dim dbColor, dtOpacity Do While Not rsDowntime.EOF If dtIndex < 20 Then typeNames(dtIndex) = rsDowntime("typename") & "" typeCounts(dtIndex) = CLng(rsDowntime("incident_count")) If Not IsNull(rsDowntime("total_minutes")) Then typeMinutes(dtIndex) = CLng(rsDowntime("total_minutes")) Else typeMinutes(dtIndex) = 0 End If ' Use white/semi-transparent colors to match other charts If dtIndex = 0 Then typeColors(dtIndex) = "#ffffff" Else dtOpacity = FormatNumber(1 - (dtIndex * 0.15), 2) typeColors(dtIndex) = "rgba(255, 255, 255, " & dtOpacity & ")" End If totalIncidents = totalIncidents + typeCounts(dtIndex) totalMinutes = totalMinutes + typeMinutes(dtIndex) dtIndex = dtIndex + 1 End If rsDowntime.MoveNext Loop rsDowntime.Close Set rsDowntime = Nothing Dim actualTypeCount actualTypeCount = dtIndex ' Convert total minutes to hours for display Dim totalHours, avgMinutesPerIncident If totalMinutes > 0 Then totalHours = FormatNumber(CDbl(totalMinutes) / 60, 1) Else totalHours = "0.0" End If If totalIncidents > 0 Then avgMinutesPerIncident = FormatNumber(CDbl(totalMinutes) / CDbl(totalIncidents), 0) Else avgMinutesPerIncident = "0" End If ' Build data strings for chart Dim chartLabels, chartData, chartColors chartLabels = "" chartData = "" chartColors = "" For i = 0 To actualTypeCount - 1 If chartLabels <> "" Then chartLabels = chartLabels & ", " chartData = chartData & ", " chartColors = chartColors & ", " End If chartLabels = chartLabels & """" & Replace(typeNames(i), """", "\""") & """" chartData = chartData & typeMinutes(i) chartColors = chartColors & """" & typeColors(i) & """" Next ' If no data, show message Dim hasData hasData = (actualTypeCount > 0) %> <% If hasData Then %> <% End If %>
Downtime Report - <%=periodLabel%>
<% If hasData Then %>
<% Else %>

No downtime incidents found for <%=periodLabel%>

<% End If %>
<% If hasData Then %>
<% Dim hoursDisplay, avgDisplay, pctDisplay For i = 0 To actualTypeCount - 1 hoursDisplay = FormatNumber(CDbl(typeMinutes(i)) / 60, 1) & "h" If typeCounts(i) > 0 Then avgDisplay = FormatNumber(CDbl(typeMinutes(i)) / CDbl(typeCounts(i)), 0) & "m" Else avgDisplay = "0m" End If If totalMinutes > 0 Then pctDisplay = FormatNumber(CDbl(typeMinutes(i)) / CDbl(totalMinutes) * 100, 1) & "%" Else pctDisplay = "0%" End If %> <% Next %>
Type Incidents Total Time Avg Time % of Total
<%=Server.HTMLEncode(typeNames(i))%> <%=typeCounts(i)%> <%=hoursDisplay%> <%=avgDisplay%> <%=pctDisplay%>
<% End If %>