Files
shopdb/usbhistory.asp
cproudlock e382a3246e Fix dualpath propagation, getShopfloorPCs filtering, USB management, and printer features
- Fix dualpath PC propagation direction (Equipment->PC) in api.asp and db_helpers.asp
- Fix early exit in CreatePCMachineRelationship preventing propagation
- Fix getShopfloorPCs to filter machinetypeid IN (33,34,35) instead of >= 33
- Fix getShopfloorPCs to show equipment numbers via GROUP_CONCAT subquery
- Add detailed PropagateDP logging for dualpath debugging
- Default "Show on Shopfloor Dashboard" checkbox to checked in addnotification.asp
- Add USB label batch printing, single USB labels, and USB history pages
- Add printer supplies tracking and toner report enhancements
- Add uptime map visualization page
- Add dashboard/lobby display SQL migration
- Update CLAUDE.md with IIS 401 workaround documentation
- Update TODO.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 10:44:55 -05:00

270 lines
9.1 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
<!-- DataTables CSS -->
<link rel="stylesheet" href="assets/plugins/datatables/dataTables.bootstrap4.min.css">
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
' Check for filter parameters
Dim filterMachineId, filterSSO
filterMachineId = Trim(Request.QueryString("machineid"))
filterSSO = Trim(Request.QueryString("sso"))
%>
<body class="bg-theme <%Response.Write(theme)%>">
<!-- start loader -->
<div id="pageloader-overlay" class="visible incoming"><div class="loader-wrapper-outer"><div class="loader-wrapper-inner" ><div class="loader"></div></div></div></div>
<!-- end loader -->
<!-- Start wrapper-->
<div id="wrapper">
<!--#include file="./includes/leftsidebar.asp"-->
<!--Start topbar header-->
<!--#include file="./includes/topbarheader.asp"-->
<!--End topbar header-->
<div class="clearfix"></div>
<div class="content-wrapper">
<div class="container-fluid">
<div class="row mt-3">
<div class="col-xl-auto">
<div class="card">
<div class="card-body">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;">
<h5 class="card-title" style="margin:0;">
<i class="zmdi zmdi-time"></i> USB Checkout History
<% If filterMachineId <> "" Then %>
<span class="badge badge-info">Filtered by Device</span>
<% End If %>
<% If filterSSO <> "" Then %>
<span class="badge badge-info">Filtered by SSO: <%=Server.HTMLEncode(filterSSO)%></span>
<% End If %>
</h5>
<div>
<% If filterMachineId <> "" Or filterSSO <> "" Then %>
<a href="./usbhistory.asp" class="btn btn-secondary btn-sm">
<i class="zmdi zmdi-close"></i> Clear Filters
</a>
<% End If %>
<a href="./displayusb.asp" class="btn btn-primary btn-sm">
<i class="zmdi zmdi-usb"></i> View USB Devices
</a>
</div>
</div>
<div class="table-responsive">
<table id="historyTable" class="table table-hover table-striped">
<thead>
<tr>
<th scope="col">USB Serial</th>
<th scope="col">USB Name</th>
<th scope="col">SSO</th>
<th scope="col">Checkout Time</th>
<th scope="col">Check-in Time</th>
<th scope="col">Duration</th>
<th scope="col">Wiped</th>
<th scope="col">Reason</th>
</tr>
</thead>
<tbody>
<%
Dim strSQL, rs
' Build query with optional filters
strSQL = "SELECT uc.*, m.serialnumber, m.alias, " & _
"TIMESTAMPDIFF(MINUTE, uc.checkout_time, COALESCE(uc.checkin_time, NOW())) AS duration_minutes " & _
"FROM usbcheckouts uc " & _
"JOIN machines m ON uc.machineid = m.machineid " & _
"WHERE 1=1 "
' Apply filters
If filterMachineId <> "" And IsNumeric(filterMachineId) Then
strSQL = strSQL & "AND uc.machineid = " & CLng(filterMachineId) & " "
End If
If filterSSO <> "" Then
' Use parameterized query for SSO filter
strSQL = strSQL & "AND uc.sso = '" & Replace(filterSSO, "'", "''") & "' "
End If
strSQL = strSQL & "ORDER BY uc.checkout_time DESC"
Set rs = objConn.Execute(strSQL)
Dim rowCount
rowCount = 0
While Not rs.EOF
rowCount = rowCount + 1
Dim serialNum, usbAlias, sso, checkoutTime, checkinTime, durationMinutes, wasWiped, reason
Dim durationText, wipedText, wipedClass, statusClass
serialNum = rs("serialnumber") & ""
usbAlias = rs("alias") & ""
sso = rs("sso") & ""
reason = rs("checkout_reason") & ""
If IsNull(rs("duration_minutes")) Or rs("duration_minutes") = "" Then
durationMinutes = 0
Else
durationMinutes = CLng(rs("duration_minutes"))
End If
' Format checkout time (MM/DD/YYYY h:mm AM/PM)
If Not IsNull(rs("checkout_time")) Then
checkoutTime = Month(rs("checkout_time")) & "/" & Day(rs("checkout_time")) & "/" & Year(rs("checkout_time")) & " " & FormatDateTime(rs("checkout_time"), 3)
Else
checkoutTime = "-"
End If
' Format check-in time and determine status (MM/DD/YYYY h:mm AM/PM)
If Not IsNull(rs("checkin_time")) Then
checkinTime = Month(rs("checkin_time")) & "/" & Day(rs("checkin_time")) & "/" & Year(rs("checkin_time")) & " " & FormatDateTime(rs("checkin_time"), 3)
statusClass = ""
Else
checkinTime = "<span class='badge badge-dark'>Still Out</span>"
statusClass = ""
End If
' Format duration
If durationMinutes < 60 Then
durationText = durationMinutes & " min"
ElseIf durationMinutes < 1440 Then
durationText = Int(durationMinutes / 60) & "h " & (durationMinutes Mod 60) & "m"
Else
durationText = Int(durationMinutes / 1440) & "d " & Int((durationMinutes Mod 1440) / 60) & "h"
End If
' Format wiped status
If IsNull(rs("was_wiped")) Then
wipedText = "-"
wipedClass = ""
ElseIf rs("was_wiped") = 1 Then
wipedText = "<span class='badge badge-success'>Yes</span>"
wipedClass = ""
Else
wipedText = "<span class='badge badge-danger'>No</span>"
wipedClass = ""
End If
%>
<tr class="<%=statusClass%>">
<td>
<a href="./usbhistory.asp?machineid=<%=rs("machineid")%>" title="Filter by this device">
<code><%=Server.HTMLEncode(serialNum)%></code>
</a>
</td>
<td><%=Server.HTMLEncode(usbAlias)%></td>
<td>
<a href="./search.asp?search=<%=Server.URLEncode(sso)%>" title="View profile for this SSO">
<strong><%=Server.HTMLEncode(sso)%></strong>
</a>
</td>
<td><%=checkoutTime%></td>
<td><%=checkinTime%></td>
<td><%=durationText%></td>
<td><%=wipedText%></td>
<td>
<% If reason <> "" Then %>
<span title="<%=Server.HTMLEncode(reason)%>"><%=Server.HTMLEncode(Left(reason, 40))%><% If Len(reason) > 40 Then Response.Write("...") End If %></span>
<% Else %>
<span class="text-muted">-</span>
<% End If %>
</td>
</tr>
<%
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
If rowCount = 0 Then
%>
<tr>
<td colspan="8" class="text-center text-muted">
<i class="zmdi zmdi-info zmdi-hc-2x"></i><br>
No checkout history found.
<% If filterMachineId <> "" Or filterSSO <> "" Then %>
<br><a href="./usbhistory.asp">Show all history</a>
<% End If %>
</td>
</tr>
<%
End If
%>
</tbody>
</table>
</div>
<div class="mt-3 text-muted">
<small>
<i class="zmdi zmdi-info"></i>
Total: <%=rowCount%> checkout record(s)
<% If filterMachineId <> "" Or filterSSO <> "" Then %> (filtered)<% End If %>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End container-fluid-->
</div><!--End content-wrapper-->
<!--Start Back To Top Button-->
<a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i> </a>
<!--End Back To Top Button-->
<!--Start footer-->
<footer class="footer">
<div class="container">
<div class="text-center">
</div>
</div>
</footer>
<!--End footer-->
</div><!--End wrapper-->
<!-- Bootstrap core JavaScript-->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<!-- simplebar js -->
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- DataTables js -->
<script src="assets/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="assets/plugins/datatables/dataTables.bootstrap4.min.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<script>
$(document).ready(function() {
$('#historyTable').DataTable({
"order": [[3, "desc"]], // Sort by checkout time descending
"pageLength": 50,
"language": {
"emptyTable": "No checkout history found"
}
});
});
</script>
</body>
</html>