% ' 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 %>
No downtime incidents found for <%=periodLabel%>
| Type | Incidents | Total Time | Avg Time | % of Total |
|---|---|---|---|---|
| <%=Server.HTMLEncode(typeNames(i))%> | <%=typeCounts(i)%> | <%=hoursDisplay%> | <%=avgDisplay%> | <%=pctDisplay%> |