Add PC-machine relationships API and report, fix shopfloor dashboard
- Add getPCMachineRelationships API endpoint for PC-to-machine mappings - Add pcmachinerelationships.asp report page with copy table/CSV/JSON export - Fix shopfloor dashboard to immediately hide deactivated notifications - Add Firewall (machinetypeid 46) support to network device pages - Add model migration warning banner to networkdevices.asp - Create SQL script for hybrid model/machine type view Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
69
api.asp
69
api.asp
@@ -61,6 +61,8 @@ Select Case action
|
|||||||
GetUDCManualTiming()
|
GetUDCManualTiming()
|
||||||
Case "getDeployableApps"
|
Case "getDeployableApps"
|
||||||
GetDeployableApps()
|
GetDeployableApps()
|
||||||
|
Case "getPCMachineRelationships"
|
||||||
|
GetPCMachineRelationships()
|
||||||
Case Else
|
Case Else
|
||||||
SendError "Invalid action: " & action
|
SendError "Invalid action: " & action
|
||||||
End Select
|
End Select
|
||||||
@@ -943,6 +945,73 @@ Sub GetShopfloorPCs()
|
|||||||
Response.Write "{""success"":true,""count"":" & pcCount & ",""data"":[" & pcList & "]}"
|
Response.Write "{""success"":true,""count"":" & pcCount & ",""data"":[" & pcList & "]}"
|
||||||
End Sub
|
End Sub
|
||||||
|
|
||||||
|
Sub GetPCMachineRelationships()
|
||||||
|
' Returns PCs that have relationships to machines (equipment) with machine numbers
|
||||||
|
' Used for identifying which PCs control which shop floor machines
|
||||||
|
On Error Resume Next
|
||||||
|
|
||||||
|
Dim rsRel, strSQL, relList, relCount, relData
|
||||||
|
|
||||||
|
strSQL = "SELECT " & _
|
||||||
|
"pc.machineid AS pc_id, " & _
|
||||||
|
"pc.machinenumber AS hostname, " & _
|
||||||
|
"c.address AS ip, " & _
|
||||||
|
"eq.machineid AS machine_id, " & _
|
||||||
|
"eq.machinenumber AS machine_number, " & _
|
||||||
|
"v.vendor AS vendor, " & _
|
||||||
|
"m.modelnumber AS model " & _
|
||||||
|
"FROM machinerelationships mr " & _
|
||||||
|
"JOIN machines eq ON mr.machineid = eq.machineid " & _
|
||||||
|
"JOIN machines pc ON mr.related_machineid = pc.machineid " & _
|
||||||
|
"LEFT JOIN communications c ON pc.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1 " & _
|
||||||
|
"LEFT JOIN models m ON eq.modelnumberid = m.modelnumberid " & _
|
||||||
|
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
|
||||||
|
"WHERE mr.isactive = 1 " & _
|
||||||
|
"AND pc.pctypeid IS NOT NULL " & _
|
||||||
|
"AND eq.machinenumber IS NOT NULL AND eq.machinenumber != '' " & _
|
||||||
|
"AND eq.machinenumber REGEXP '^[0-9]{4}$' " & _
|
||||||
|
"AND eq.machinenumber NOT IN ('0612', '0613', '0614', '0615') " & _
|
||||||
|
"AND (v.vendor IS NULL OR v.vendor != 'WJDT') " & _
|
||||||
|
"AND (m.modelnumber IS NULL OR m.modelnumber != 'TBD') " & _
|
||||||
|
"ORDER BY eq.machinenumber"
|
||||||
|
|
||||||
|
Set rsRel = objConn.Execute(strSQL)
|
||||||
|
|
||||||
|
If Err.Number <> 0 Then
|
||||||
|
SendError "Database error: " & Err.Description
|
||||||
|
Exit Sub
|
||||||
|
End If
|
||||||
|
|
||||||
|
' Build JSON array
|
||||||
|
relList = ""
|
||||||
|
relCount = 0
|
||||||
|
|
||||||
|
Do While Not rsRel.EOF
|
||||||
|
If relList <> "" Then relList = relList & ","
|
||||||
|
|
||||||
|
relData = "{"
|
||||||
|
relData = relData & """pc_id"":" & rsRel("pc_id") & ","
|
||||||
|
relData = relData & """hostname"":""" & EscapeJSON(rsRel("hostname") & "") & ""","
|
||||||
|
relData = relData & """ip"":""" & EscapeJSON(rsRel("ip") & "") & ""","
|
||||||
|
relData = relData & """machine_id"":" & rsRel("machine_id") & ","
|
||||||
|
relData = relData & """machine_number"":""" & EscapeJSON(rsRel("machine_number") & "") & ""","
|
||||||
|
relData = relData & """vendor"":""" & EscapeJSON(rsRel("vendor") & "") & ""","
|
||||||
|
relData = relData & """model"":""" & EscapeJSON(rsRel("model") & "") & """"
|
||||||
|
relData = relData & "}"
|
||||||
|
|
||||||
|
relList = relList & relData
|
||||||
|
relCount = relCount + 1
|
||||||
|
|
||||||
|
rsRel.MoveNext
|
||||||
|
Loop
|
||||||
|
|
||||||
|
rsRel.Close
|
||||||
|
Set rsRel = Nothing
|
||||||
|
|
||||||
|
' Send response
|
||||||
|
Response.Write "{""success"":true,""count"":" & relCount & ",""data"":[" & relList & "]}"
|
||||||
|
End Sub
|
||||||
|
|
||||||
Sub GetHighUptimePCs()
|
Sub GetHighUptimePCs()
|
||||||
' Returns list of PCs with uptime >= specified days (for reboot management)
|
' Returns list of PCs with uptime >= specified days (for reboot management)
|
||||||
On Error Resume Next
|
On Error Resume Next
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ Response.AddHeader "Cache-Control", "no-cache, no-store, must-revalidate"
|
|||||||
|
|
||||||
Dim strSQL, jsonOutput, isFirstCurrent, isFirstUpcoming
|
Dim strSQL, jsonOutput, isFirstCurrent, isFirstUpcoming
|
||||||
Dim businessUnitFilter
|
Dim businessUnitFilter
|
||||||
|
Dim st, et, isCurrent, isResolved, isUpcoming
|
||||||
|
Dim typeName, empSsoRaw, ssoArr, idx
|
||||||
|
Dim singleSSO, singleName, singlePicture
|
||||||
|
Dim empName, empPicture
|
||||||
|
Dim upTypeName, upEmpSsoRaw, upSsoArr, upIdx
|
||||||
|
Dim upSingleSSO, upSingleName, upSinglePicture
|
||||||
|
Dim upEmpName, upEmpPicture
|
||||||
|
|
||||||
' Get business unit filter from query string
|
' Get business unit filter from query string
|
||||||
businessUnitFilter = Request.QueryString("businessunit")
|
businessUnitFilter = Request.QueryString("businessunit")
|
||||||
@@ -16,11 +23,12 @@ strSQL = "SELECT n.notificationid, n.notification, n.starttime, n.endtime, " & _
|
|||||||
"n.ticketnumber, n.link, n.isactive, n.isshopfloor, n.businessunitid, " & _
|
"n.ticketnumber, n.link, n.isactive, n.isshopfloor, n.businessunitid, " & _
|
||||||
"n.employeesso, nt.typename, nt.typecolor, bu.businessunit, " & _
|
"n.employeesso, nt.typename, nt.typecolor, bu.businessunit, " & _
|
||||||
"CASE " & _
|
"CASE " & _
|
||||||
" WHEN n.starttime <= NOW() AND (n.endtime IS NULL OR n.endtime >= NOW()) THEN 1 " & _
|
" WHEN n.starttime <= NOW() AND (n.endtime IS NULL OR n.endtime >= NOW()) AND n.isactive = 1 THEN 1 " & _
|
||||||
" WHEN n.endtime IS NOT NULL AND n.endtime < NOW() AND DATE_ADD(n.endtime, INTERVAL 30 MINUTE) >= NOW() THEN 1 " & _
|
" WHEN n.endtime IS NOT NULL AND n.endtime < NOW() AND DATE_ADD(n.endtime, INTERVAL 30 MINUTE) >= NOW() THEN 1 " & _
|
||||||
" ELSE 0 " & _
|
" ELSE 0 " & _
|
||||||
"END as is_current, " & _
|
"END as is_current, " & _
|
||||||
"CASE " & _
|
"CASE " & _
|
||||||
|
" WHEN n.isactive = 0 THEN 1 " & _
|
||||||
" WHEN n.endtime IS NOT NULL AND n.endtime < NOW() THEN 1 " & _
|
" WHEN n.endtime IS NOT NULL AND n.endtime < NOW() THEN 1 " & _
|
||||||
" ELSE 0 " & _
|
" ELSE 0 " & _
|
||||||
"END as is_resolved, " & _
|
"END as is_resolved, " & _
|
||||||
@@ -32,10 +40,9 @@ strSQL = "SELECT n.notificationid, n.notification, n.starttime, n.endtime, " & _
|
|||||||
"FROM notifications n " & _
|
"FROM notifications n " & _
|
||||||
"LEFT JOIN notificationtypes nt ON n.notificationtypeid = nt.notificationtypeid " & _
|
"LEFT JOIN notificationtypes nt ON n.notificationtypeid = nt.notificationtypeid " & _
|
||||||
"LEFT JOIN businessunits bu ON n.businessunitid = bu.businessunitid " & _
|
"LEFT JOIN businessunits bu ON n.businessunitid = bu.businessunitid " & _
|
||||||
"WHERE n.isshopfloor = 1 AND (" & _
|
"WHERE n.isshopfloor = 1 AND n.isactive = 1 AND (" & _
|
||||||
" n.isactive = 1 OR " & _
|
" n.endtime IS NULL OR " & _
|
||||||
" (n.isactive = 0 AND n.endtime IS NOT NULL AND " & _
|
" DATE_ADD(n.endtime, INTERVAL 30 MINUTE) >= NOW()" & _
|
||||||
" DATE_ADD(n.endtime, INTERVAL 30 MINUTE) >= NOW())" & _
|
|
||||||
")"
|
")"
|
||||||
|
|
||||||
' Add business unit filter
|
' Add business unit filter
|
||||||
@@ -51,11 +58,10 @@ strSQL = strSQL & " ORDER BY n.notificationid DESC"
|
|||||||
|
|
||||||
Set rs = objConn.Execute(strSQL)
|
Set rs = objConn.Execute(strSQL)
|
||||||
|
|
||||||
jsonOutput = "{""success"":true,""timestamp"":""" & FormatDateTime(Now(), 2) & " " & FormatDateTime(Now(), 4) & """,""current"":["
|
jsonOutput = "{""success"":true,""version"":""v2"",""timestamp"":""" & FormatDateTime(Now(), 2) & " " & FormatDateTime(Now(), 4) & """,""current"":["
|
||||||
isFirstCurrent = True
|
isFirstCurrent = True
|
||||||
|
|
||||||
Do While Not rs.EOF
|
Do While Not rs.EOF
|
||||||
Dim st, et, isCurrent, isResolved
|
|
||||||
st = rs("starttime")
|
st = rs("starttime")
|
||||||
et = rs("endtime")
|
et = rs("endtime")
|
||||||
isCurrent = rs("is_current")
|
isCurrent = rs("is_current")
|
||||||
@@ -63,17 +69,14 @@ Do While Not rs.EOF
|
|||||||
|
|
||||||
If isCurrent = 1 Then
|
If isCurrent = 1 Then
|
||||||
' Check if this is a Recognition with multiple employees
|
' Check if this is a Recognition with multiple employees
|
||||||
Dim typeName, empSsoRaw
|
|
||||||
typeName = rs("typename") & ""
|
typeName = rs("typename") & ""
|
||||||
empSsoRaw = rs("employeesso") & ""
|
empSsoRaw = rs("employeesso") & ""
|
||||||
|
|
||||||
If LCase(typeName) = "recognition" And Len(empSsoRaw) > 0 And InStr(empSsoRaw, ",") > 0 Then
|
If LCase(typeName) = "recognition" And Len(empSsoRaw) > 0 And InStr(empSsoRaw, ",") > 0 Then
|
||||||
' Split into individual cards for each employee
|
' Split into individual cards for each employee
|
||||||
Dim ssoArr, idx
|
|
||||||
ssoArr = Split(empSsoRaw, ",")
|
ssoArr = Split(empSsoRaw, ",")
|
||||||
|
|
||||||
For idx = 0 To UBound(ssoArr)
|
For idx = 0 To UBound(ssoArr)
|
||||||
Dim singleSSO, singleName, singlePicture
|
|
||||||
singleSSO = Trim(ssoArr(idx))
|
singleSSO = Trim(ssoArr(idx))
|
||||||
singleName = LookupSingleEmployeeName(singleSSO)
|
singleName = LookupSingleEmployeeName(singleSSO)
|
||||||
singlePicture = LookupSingleEmployeePicture(singleSSO)
|
singlePicture = LookupSingleEmployeePicture(singleSSO)
|
||||||
@@ -128,7 +131,6 @@ Do While Not rs.EOF
|
|||||||
jsonOutput = jsonOutput & """typecolor"":""" & JSEscape(rs("typecolor") & "") & ""","
|
jsonOutput = jsonOutput & """typecolor"":""" & JSEscape(rs("typecolor") & "") & ""","
|
||||||
jsonOutput = jsonOutput & """businessunit"":" & StrOrNull(rs("businessunit")) & ","
|
jsonOutput = jsonOutput & """businessunit"":" & StrOrNull(rs("businessunit")) & ","
|
||||||
' Handle employeesso - can be SSO or NAME:customname
|
' Handle employeesso - can be SSO or NAME:customname
|
||||||
Dim empName, empPicture
|
|
||||||
If Left(empSsoRaw, 5) = "NAME:" Then
|
If Left(empSsoRaw, 5) = "NAME:" Then
|
||||||
' Custom name - extract name, no picture
|
' Custom name - extract name, no picture
|
||||||
empName = Mid(empSsoRaw, 6)
|
empName = Mid(empSsoRaw, 6)
|
||||||
@@ -156,24 +158,20 @@ jsonOutput = jsonOutput & "],""upcoming"":["
|
|||||||
isFirstUpcoming = True
|
isFirstUpcoming = True
|
||||||
|
|
||||||
Do While Not rs.EOF
|
Do While Not rs.EOF
|
||||||
Dim isUpcoming
|
|
||||||
st = rs("starttime")
|
st = rs("starttime")
|
||||||
et = rs("endtime")
|
et = rs("endtime")
|
||||||
isUpcoming = rs("is_upcoming")
|
isUpcoming = rs("is_upcoming")
|
||||||
|
|
||||||
If isUpcoming = 1 Then
|
If isUpcoming = 1 Then
|
||||||
' Check if this is a Recognition with multiple employees
|
' Check if this is a Recognition with multiple employees
|
||||||
Dim upTypeName, upEmpSsoRaw
|
|
||||||
upTypeName = rs("typename") & ""
|
upTypeName = rs("typename") & ""
|
||||||
upEmpSsoRaw = rs("employeesso") & ""
|
upEmpSsoRaw = rs("employeesso") & ""
|
||||||
|
|
||||||
If LCase(upTypeName) = "recognition" And Len(upEmpSsoRaw) > 0 And InStr(upEmpSsoRaw, ",") > 0 Then
|
If LCase(upTypeName) = "recognition" And Len(upEmpSsoRaw) > 0 And InStr(upEmpSsoRaw, ",") > 0 Then
|
||||||
' Split into individual cards for each employee
|
' Split into individual cards for each employee
|
||||||
Dim upSsoArr, upIdx
|
|
||||||
upSsoArr = Split(upEmpSsoRaw, ",")
|
upSsoArr = Split(upEmpSsoRaw, ",")
|
||||||
|
|
||||||
For upIdx = 0 To UBound(upSsoArr)
|
For upIdx = 0 To UBound(upSsoArr)
|
||||||
Dim upSingleSSO, upSingleName, upSinglePicture
|
|
||||||
upSingleSSO = Trim(upSsoArr(upIdx))
|
upSingleSSO = Trim(upSsoArr(upIdx))
|
||||||
upSingleName = LookupSingleEmployeeName(upSingleSSO)
|
upSingleName = LookupSingleEmployeeName(upSingleSSO)
|
||||||
upSinglePicture = LookupSingleEmployeePicture(upSingleSSO)
|
upSinglePicture = LookupSingleEmployeePicture(upSingleSSO)
|
||||||
@@ -216,7 +214,6 @@ Do While Not rs.EOF
|
|||||||
jsonOutput = jsonOutput & """typecolor"":""" & JSEscape(rs("typecolor") & "") & ""","
|
jsonOutput = jsonOutput & """typecolor"":""" & JSEscape(rs("typecolor") & "") & ""","
|
||||||
jsonOutput = jsonOutput & """businessunit"":" & StrOrNull(rs("businessunit")) & ","
|
jsonOutput = jsonOutput & """businessunit"":" & StrOrNull(rs("businessunit")) & ","
|
||||||
' Handle employeesso - can be SSO or NAME:customname
|
' Handle employeesso - can be SSO or NAME:customname
|
||||||
Dim upEmpName, upEmpPicture
|
|
||||||
If Left(upEmpSsoRaw, 5) = "NAME:" Then
|
If Left(upEmpSsoRaw, 5) = "NAME:" Then
|
||||||
' Custom name - extract name, no picture
|
' Custom name - extract name, no picture
|
||||||
upEmpName = Mid(upEmpSsoRaw, 6)
|
upEmpName = Mid(upEmpSsoRaw, 6)
|
||||||
|
|||||||
@@ -240,7 +240,10 @@
|
|||||||
strSQL2 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
|
strSQL2 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
|
||||||
Set rsMachineTypes = objConn.Execute(strSQL2)
|
Set rsMachineTypes = objConn.Execute(strSQL2)
|
||||||
While Not rsMachineTypes.EOF
|
While Not rsMachineTypes.EOF
|
||||||
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
|
' Pre-select Firewall (46) as the default for this form
|
||||||
|
Dim mtSelected
|
||||||
|
If CStr(rsMachineTypes("machinetypeid")) = "46" Then mtSelected = " selected" Else mtSelected = ""
|
||||||
|
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'" & mtSelected & ">" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
|
||||||
rsMachineTypes.MoveNext
|
rsMachineTypes.MoveNext
|
||||||
Wend
|
Wend
|
||||||
rsMachineTypes.Close
|
rsMachineTypes.Close
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ strSQL = "SELECT m.machineid, m.machinenumber, m.alias, m.serialnumber, " &_
|
|||||||
"AND m.isactive = 1 " &_
|
"AND m.isactive = 1 " &_
|
||||||
"AND m.mapleft IS NOT NULL " &_
|
"AND m.mapleft IS NOT NULL " &_
|
||||||
"AND m.maptop IS NOT NULL " &_
|
"AND m.maptop IS NOT NULL " &_
|
||||||
"AND mt.machinetypeid NOT IN (1, 16, 17, 18, 19, 20) " &_
|
"AND mt.machinetypeid NOT IN (1, 16, 17, 18, 19, 20, 46) " &_
|
||||||
"AND mt.machinetypeid < 33 " &_
|
"AND mt.machinetypeid < 33 " &_
|
||||||
"ORDER BY mt.machinetype, m.machinenumber ASC"
|
"ORDER BY mt.machinetype, m.machinenumber ASC"
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ Set rsM = objConn.Execute("SELECT m.machineid, m.machinenumber, m.alias, m.maple
|
|||||||
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
|
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
|
||||||
"WHERE m.pctypeid IS NULL " &_
|
"WHERE m.pctypeid IS NULL " &_
|
||||||
"AND m.isactive = 1 " &_
|
"AND m.isactive = 1 " &_
|
||||||
"AND mt.machinetypeid NOT IN (1, 16, 17, 18, 19, 20) " &_
|
"AND mt.machinetypeid NOT IN (1, 16, 17, 18, 19, 20, 46) " &_
|
||||||
"AND mt.machinetypeid < 33 " &_
|
"AND mt.machinetypeid < 33 " &_
|
||||||
"ORDER BY m.machinenumber")
|
"ORDER BY m.machinenumber")
|
||||||
Do While Not rsM.EOF
|
Do While Not rsM.EOF
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
<a class="dropdown-item" href="deviceidf.asp?id=0"><i class="zmdi zmdi-city-alt"></i> Add IDF</a>
|
<a class="dropdown-item" href="deviceidf.asp?id=0"><i class="zmdi zmdi-city-alt"></i> Add IDF</a>
|
||||||
<a class="dropdown-item" href="deviceserver.asp?id=0"><i class="zmdi zmdi-storage"></i> Add Server</a>
|
<a class="dropdown-item" href="deviceserver.asp?id=0"><i class="zmdi zmdi-storage"></i> Add Server</a>
|
||||||
<a class="dropdown-item" href="deviceswitch.asp?id=0"><i class="zmdi zmdi-device-hub"></i> Add Switch</a>
|
<a class="dropdown-item" href="deviceswitch.asp?id=0"><i class="zmdi zmdi-device-hub"></i> Add Switch</a>
|
||||||
|
<a class="dropdown-item" href="devicefirewall.asp?id=0"><i class="zmdi zmdi-shield-security"></i> Add Firewall</a>
|
||||||
<a class="dropdown-item" href="devicecamera.asp?id=0"><i class="zmdi zmdi-videocam"></i> Add Camera</a>
|
<a class="dropdown-item" href="devicecamera.asp?id=0"><i class="zmdi zmdi-videocam"></i> Add Camera</a>
|
||||||
<a class="dropdown-item" href="deviceaccesspoint.asp?id=0"><i class="zmdi zmdi-wifi"></i> Add Access Point</a>
|
<a class="dropdown-item" href="deviceaccesspoint.asp?id=0"><i class="zmdi zmdi-wifi"></i> Add Access Point</a>
|
||||||
<a class="dropdown-item" href="addprinter.asp"><i class="zmdi zmdi-print"></i> Add Printer</a>
|
<a class="dropdown-item" href="addprinter.asp"><i class="zmdi zmdi-print"></i> Add Printer</a>
|
||||||
@@ -47,6 +48,107 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Model Migration Warning - Devices needing vendor/model updates -->
|
||||||
|
<%
|
||||||
|
' Check for devices that need model fixes
|
||||||
|
Dim rsModelIssues, modelIssueCount
|
||||||
|
Dim strModelIssueSQL
|
||||||
|
strModelIssueSQL = "SELECT " & _
|
||||||
|
"ma.machineid, " & _
|
||||||
|
"COALESCE(ma.alias, ma.machinenumber) as device_name, " & _
|
||||||
|
"mt_machine.machinetype as current_type, " & _
|
||||||
|
"ma.machinetypeid as machine_typeid, " & _
|
||||||
|
"mo.modelnumber, " & _
|
||||||
|
"CASE " & _
|
||||||
|
" WHEN ma.modelnumberid IS NULL THEN 'No model assigned' " & _
|
||||||
|
" WHEN mo.machinetypeid IS NULL THEN 'Model has no type set' " & _
|
||||||
|
" WHEN mo.machinetypeid NOT IN (16,17,18,19,20,46) THEN 'Model has incorrect type' " & _
|
||||||
|
" ELSE 'OK' " & _
|
||||||
|
"END as issue " & _
|
||||||
|
"FROM machines ma " & _
|
||||||
|
"JOIN machinetypes mt_machine ON ma.machinetypeid = mt_machine.machinetypeid " & _
|
||||||
|
"LEFT JOIN models mo ON ma.modelnumberid = mo.modelnumberid " & _
|
||||||
|
"WHERE ma.machinetypeid IN (16,17,18,19,20,46) " & _
|
||||||
|
"AND ma.isactive = 1 " & _
|
||||||
|
"AND (ma.modelnumberid IS NULL OR mo.machinetypeid IS NULL OR mo.machinetypeid NOT IN (16,17,18,19,20,46)) " & _
|
||||||
|
"ORDER BY mt_machine.machinetype, ma.alias"
|
||||||
|
Set rsModelIssues = objConn.Execute(strModelIssueSQL)
|
||||||
|
|
||||||
|
' Count issues
|
||||||
|
modelIssueCount = 0
|
||||||
|
If Not rsModelIssues.EOF Then
|
||||||
|
rsModelIssues.MoveFirst
|
||||||
|
Do While Not rsModelIssues.EOF
|
||||||
|
modelIssueCount = modelIssueCount + 1
|
||||||
|
rsModelIssues.MoveNext
|
||||||
|
Loop
|
||||||
|
rsModelIssues.MoveFirst
|
||||||
|
End If
|
||||||
|
|
||||||
|
If modelIssueCount > 0 Then
|
||||||
|
%>
|
||||||
|
<div class="alert alert-warning alert-dismissible fade show" role="alert" style="margin-bottom:20px;">
|
||||||
|
<h5 class="alert-heading"><i class="zmdi zmdi-alert-triangle"></i> Model Migration Required</h5>
|
||||||
|
<p><strong><%=modelIssueCount%> device(s)</strong> need vendor/model updates to complete the migration from machine-level type assignment to model-level type assignment.</p>
|
||||||
|
<hr>
|
||||||
|
<p class="mb-0">
|
||||||
|
<a class="btn btn-sm btn-warning" data-toggle="collapse" href="#modelIssuesList" role="button">
|
||||||
|
<i class="zmdi zmdi-eye"></i> Show Devices Needing Updates
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<div class="collapse mt-3" id="modelIssuesList">
|
||||||
|
<table class="table table-sm table-bordered" style="background:#fff; color:#333;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Device</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Current Model</th>
|
||||||
|
<th>Issue</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<%
|
||||||
|
Dim editUrl
|
||||||
|
Do While Not rsModelIssues.EOF
|
||||||
|
Select Case rsModelIssues("current_type")
|
||||||
|
Case "IDF"
|
||||||
|
editUrl = "deviceidf.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case "Server"
|
||||||
|
editUrl = "deviceserver.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case "Switch"
|
||||||
|
editUrl = "deviceswitch.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case "Firewall"
|
||||||
|
editUrl = "devicefirewall.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case "Camera"
|
||||||
|
editUrl = "devicecamera.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case "Access Point"
|
||||||
|
editUrl = "deviceaccesspoint.asp?id=" & rsModelIssues("machineid")
|
||||||
|
Case Else
|
||||||
|
editUrl = "displaydevice.asp?id=" & rsModelIssues("machineid")
|
||||||
|
End Select
|
||||||
|
%>
|
||||||
|
<tr>
|
||||||
|
<td><%=Server.HTMLEncode(rsModelIssues("device_name") & "")%></td>
|
||||||
|
<td><%=Server.HTMLEncode(rsModelIssues("current_type") & "")%></td>
|
||||||
|
<td><%If IsNull(rsModelIssues("modelnumber")) Or rsModelIssues("modelnumber") = "" Then Response.Write("<em>None</em>") Else Response.Write(Server.HTMLEncode(rsModelIssues("modelnumber") & ""))%></td>
|
||||||
|
<td><span class="badge badge-warning"><%=Server.HTMLEncode(rsModelIssues("issue") & "")%></span></td>
|
||||||
|
<td><a href="<%=editUrl%>" class="btn btn-xs btn-primary"><i class="zmdi zmdi-edit"></i> Edit</a></td>
|
||||||
|
</tr>
|
||||||
|
<%
|
||||||
|
rsModelIssues.MoveNext
|
||||||
|
Loop
|
||||||
|
%>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%
|
||||||
|
End If
|
||||||
|
rsModelIssues.Close
|
||||||
|
Set rsModelIssues = Nothing
|
||||||
|
%>
|
||||||
|
|
||||||
<!-- Filter Tabs -->
|
<!-- Filter Tabs -->
|
||||||
<%
|
<%
|
||||||
Dim filterType
|
Dim filterType
|
||||||
@@ -89,6 +191,11 @@
|
|||||||
<i class="zmdi zmdi-device-hub"></i> Switches
|
<i class="zmdi zmdi-device-hub"></i> Switches
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <%If filterType="Firewall" Then Response.Write("active")%>" href="networkdevices.asp?filter=Firewall">
|
||||||
|
<i class="zmdi zmdi-shield-security"></i> Firewalls
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
@@ -102,8 +209,8 @@ If filterType = "IDF" Then
|
|||||||
Response.Write("<th scope='col'><i class='zmdi zmdi-pin'></i></th>")
|
Response.Write("<th scope='col'><i class='zmdi zmdi-pin'></i></th>")
|
||||||
Response.Write("<th scope='col'>Name</th>")
|
Response.Write("<th scope='col'>Name</th>")
|
||||||
Response.Write("<th scope='col'>Description</th>")
|
Response.Write("<th scope='col'>Description</th>")
|
||||||
ElseIf filterType = "Server" Or filterType = "Switch" Then
|
ElseIf filterType = "Server" Or filterType = "Switch" Or filterType = "Firewall" Then
|
||||||
' Server/Switch columns: Location, Name, Vendor, Model, Serial, IP Address, FQDN, Description
|
' Server/Switch/Firewall columns: Location, Name, Vendor, Model, Serial, IP Address, FQDN, Description
|
||||||
Response.Write("<th scope='col'><i class='zmdi zmdi-pin'></i></th>")
|
Response.Write("<th scope='col'><i class='zmdi zmdi-pin'></i></th>")
|
||||||
Response.Write("<th scope='col'>Name</th>")
|
Response.Write("<th scope='col'>Name</th>")
|
||||||
Response.Write("<th scope='col'>Vendor</th>")
|
Response.Write("<th scope='col'>Vendor</th>")
|
||||||
@@ -255,7 +362,7 @@ End If
|
|||||||
End If
|
End If
|
||||||
Response.Write("</td>")
|
Response.Write("</td>")
|
||||||
|
|
||||||
ElseIf filterType = "Server" Or filterType = "Switch" Then
|
ElseIf filterType = "Server" Or filterType = "Switch" Or filterType = "Firewall" Then
|
||||||
' Vendor, Model, Serial, IP Address, FQDN, Description, Actions
|
' Vendor, Model, Serial, IP Address, FQDN, Description, Actions
|
||||||
Response.Write("<td>")
|
Response.Write("<td>")
|
||||||
If Not IsNull(rs("vendor")) Then
|
If Not IsNull(rs("vendor")) Then
|
||||||
@@ -475,6 +582,9 @@ End If
|
|||||||
Case "Switch":
|
Case "Switch":
|
||||||
noDataMessage = "No switches found."
|
noDataMessage = "No switches found."
|
||||||
colspanCount = "8"
|
colspanCount = "8"
|
||||||
|
Case "Firewall":
|
||||||
|
noDataMessage = "No firewalls found."
|
||||||
|
colspanCount = "8"
|
||||||
Case "Camera":
|
Case "Camera":
|
||||||
noDataMessage = "No cameras found."
|
noDataMessage = "No cameras found."
|
||||||
colspanCount = "8"
|
colspanCount = "8"
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ strSQL = "SELECT printers.printerid AS id, machines.machinenumber AS name, machi
|
|||||||
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " &_
|
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " &_
|
||||||
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
|
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
|
||||||
"LEFT JOIN communications c ON m.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1 " &_
|
"LEFT JOIN communications c ON m.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1 " &_
|
||||||
"WHERE m.machinetypeid IN (16, 17, 18, 19, 20) " &_
|
"WHERE m.machinetypeid IN (16, 17, 18, 19, 20, 46) " &_
|
||||||
"AND m.isactive = 1 " &_
|
"AND m.isactive = 1 " &_
|
||||||
"AND m.mapleft IS NOT NULL " &_
|
"AND m.mapleft IS NOT NULL " &_
|
||||||
"AND m.maptop IS NOT NULL " &_
|
"AND m.maptop IS NOT NULL " &_
|
||||||
|
|||||||
158
pcmachinerelationships.asp
Normal file
158
pcmachinerelationships.asp
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<%@ Language=VBScript %>
|
||||||
|
<!--#include file="includes/sql.asp"-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>PC-Machine Relationships</title>
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.6.0/css/bootstrap.min.css">
|
||||||
|
<style>
|
||||||
|
body { padding: 20px; }
|
||||||
|
table { font-size: 14px; }
|
||||||
|
.copy-btn { margin-bottom: 15px; }
|
||||||
|
pre { background: #f8f9fa; padding: 15px; border-radius: 4px; max-height: 400px; overflow: auto; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<h2>PC-Machine Relationships</h2>
|
||||||
|
<p class="text-muted">PCs with relationships to shop floor machines</p>
|
||||||
|
|
||||||
|
<button class="btn btn-primary copy-btn" onclick="copyTable()">Copy Table to Clipboard</button>
|
||||||
|
<button class="btn btn-secondary copy-btn" onclick="copyCSV()">Copy as CSV</button>
|
||||||
|
<button class="btn btn-info copy-btn" onclick="copyJSON()">Copy as JSON</button>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered table-sm" id="dataTable">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Machine #</th>
|
||||||
|
<th>Vendor</th>
|
||||||
|
<th>Model</th>
|
||||||
|
<th>PC Hostname</th>
|
||||||
|
<th>PC IP</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<%
|
||||||
|
Dim strSQL, rs
|
||||||
|
|
||||||
|
strSQL = "SELECT " & _
|
||||||
|
"pc.machineid AS pc_id, " & _
|
||||||
|
"pc.machinenumber AS hostname, " & _
|
||||||
|
"c.address AS ip, " & _
|
||||||
|
"eq.machineid AS machine_id, " & _
|
||||||
|
"eq.machinenumber AS machine_number, " & _
|
||||||
|
"v.vendor AS vendor, " & _
|
||||||
|
"m.modelnumber AS model " & _
|
||||||
|
"FROM machinerelationships mr " & _
|
||||||
|
"JOIN machines eq ON mr.machineid = eq.machineid " & _
|
||||||
|
"JOIN machines pc ON mr.related_machineid = pc.machineid " & _
|
||||||
|
"LEFT JOIN communications c ON pc.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1 " & _
|
||||||
|
"LEFT JOIN models m ON eq.modelnumberid = m.modelnumberid " & _
|
||||||
|
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
|
||||||
|
"WHERE mr.isactive = 1 " & _
|
||||||
|
"AND pc.pctypeid IS NOT NULL " & _
|
||||||
|
"AND eq.machinenumber IS NOT NULL AND eq.machinenumber != '' " & _
|
||||||
|
"AND eq.machinenumber REGEXP '^[0-9]{4}$' " & _
|
||||||
|
"AND eq.machinenumber NOT IN ('0612', '0613', '0614', '0615') " & _
|
||||||
|
"AND (v.vendor IS NULL OR v.vendor != 'WJDT') " & _
|
||||||
|
"AND (m.modelnumber IS NULL OR m.modelnumber != 'TBD') " & _
|
||||||
|
"ORDER BY eq.machinenumber"
|
||||||
|
|
||||||
|
Set rs = objConn.Execute(strSQL)
|
||||||
|
|
||||||
|
Dim rowCount
|
||||||
|
rowCount = 0
|
||||||
|
|
||||||
|
Do While Not rs.EOF
|
||||||
|
rowCount = rowCount + 1
|
||||||
|
%>
|
||||||
|
<tr>
|
||||||
|
<td><%= Server.HTMLEncode(rs("machine_number") & "") %></td>
|
||||||
|
<td><%= Server.HTMLEncode(rs("vendor") & "") %></td>
|
||||||
|
<td><%= Server.HTMLEncode(rs("model") & "") %></td>
|
||||||
|
<td><%= Server.HTMLEncode(rs("hostname") & "") %></td>
|
||||||
|
<td><%= Server.HTMLEncode(rs("ip") & "") %></td>
|
||||||
|
</tr>
|
||||||
|
<%
|
||||||
|
rs.MoveNext
|
||||||
|
Loop
|
||||||
|
rs.Close
|
||||||
|
Set rs = Nothing
|
||||||
|
%>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-muted"><%= rowCount %> records found</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function copyTable() {
|
||||||
|
var table = document.getElementById('dataTable');
|
||||||
|
var text = '';
|
||||||
|
|
||||||
|
// Get headers
|
||||||
|
var headers = table.querySelectorAll('thead th');
|
||||||
|
headers.forEach(function(th, i) {
|
||||||
|
text += th.innerText + (i < headers.length - 1 ? '\t' : '\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get rows
|
||||||
|
var rows = table.querySelectorAll('tbody tr');
|
||||||
|
rows.forEach(function(row) {
|
||||||
|
var cells = row.querySelectorAll('td');
|
||||||
|
cells.forEach(function(td, i) {
|
||||||
|
text += td.innerText + (i < cells.length - 1 ? '\t' : '\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(text).then(function() {
|
||||||
|
alert('Table copied to clipboard!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyCSV() {
|
||||||
|
var table = document.getElementById('dataTable');
|
||||||
|
var csv = '';
|
||||||
|
|
||||||
|
// Get headers
|
||||||
|
var headers = table.querySelectorAll('thead th');
|
||||||
|
headers.forEach(function(th, i) {
|
||||||
|
csv += '"' + th.innerText + '"' + (i < headers.length - 1 ? ',' : '\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get rows
|
||||||
|
var rows = table.querySelectorAll('tbody tr');
|
||||||
|
rows.forEach(function(row) {
|
||||||
|
var cells = row.querySelectorAll('td');
|
||||||
|
cells.forEach(function(td, i) {
|
||||||
|
csv += '"' + td.innerText + '"' + (i < cells.length - 1 ? ',' : '\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(csv).then(function() {
|
||||||
|
alert('CSV copied to clipboard!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyJSON() {
|
||||||
|
var table = document.getElementById('dataTable');
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
var rows = table.querySelectorAll('tbody tr');
|
||||||
|
rows.forEach(function(row) {
|
||||||
|
var cells = row.querySelectorAll('td');
|
||||||
|
data.push({
|
||||||
|
"Name": cells[0].innerText,
|
||||||
|
"IpAddress": cells[4].innerText,
|
||||||
|
"Group": null
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var json = JSON.stringify(data, null, 2);
|
||||||
|
navigator.clipboard.writeText(json).then(function() {
|
||||||
|
alert('JSON copied to clipboard!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1186,15 +1186,40 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback timeout for pendingDataRender
|
||||||
|
let pendingDataTimeout = null;
|
||||||
|
|
||||||
// Render events on the page (with smart delay during transitions)
|
// Render events on the page (with smart delay during transitions)
|
||||||
function renderEvents(data) {
|
function renderEvents(data) {
|
||||||
// If any carousel is mid-transition, delay the render
|
// If any carousel is mid-transition, delay the render
|
||||||
if (isTransitioning || isNonIncidentTransitioning || isRecognitionTransitioning) {
|
if (isTransitioning || isNonIncidentTransitioning || isRecognitionTransitioning) {
|
||||||
console.log('Carousel: Transition in progress, delaying render by 800ms');
|
console.log('Carousel: Transition in progress, delaying render');
|
||||||
pendingDataRender = data;
|
pendingDataRender = data;
|
||||||
|
|
||||||
|
// Fallback: if pendingDataRender isn't processed within 1 second, force render
|
||||||
|
if (pendingDataTimeout) clearTimeout(pendingDataTimeout);
|
||||||
|
pendingDataTimeout = setTimeout(() => {
|
||||||
|
if (pendingDataRender) {
|
||||||
|
console.log('Carousel: Fallback timeout - forcing render of pending data');
|
||||||
|
// Reset all transition flags in case they're stuck
|
||||||
|
isTransitioning = false;
|
||||||
|
isNonIncidentTransitioning = false;
|
||||||
|
isRecognitionTransitioning = false;
|
||||||
|
const dataToRender = pendingDataRender;
|
||||||
|
pendingDataRender = null;
|
||||||
|
renderEvents(dataToRender);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear fallback timeout since we're rendering now
|
||||||
|
if (pendingDataTimeout) {
|
||||||
|
clearTimeout(pendingDataTimeout);
|
||||||
|
pendingDataTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
const container = document.getElementById('eventsContainer');
|
const container = document.getElementById('eventsContainer');
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
@@ -1539,6 +1564,14 @@
|
|||||||
currentItem.classList.remove('exit-up');
|
currentItem.classList.remove('exit-up');
|
||||||
currentItem.classList.add('enter-down');
|
currentItem.classList.add('enter-down');
|
||||||
isNonIncidentTransitioning = false;
|
isNonIncidentTransitioning = false;
|
||||||
|
|
||||||
|
// If there's pending data to render, render it now
|
||||||
|
if (pendingDataRender) {
|
||||||
|
console.log('Non-Incident Carousel: Transition complete, rendering pending data');
|
||||||
|
const dataToRender = pendingDataRender;
|
||||||
|
pendingDataRender = null;
|
||||||
|
renderEvents(dataToRender);
|
||||||
|
}
|
||||||
}, 800);
|
}, 800);
|
||||||
|
|
||||||
currentNonIncidentIndex = nextIndex;
|
currentNonIncidentIndex = nextIndex;
|
||||||
@@ -1681,6 +1714,14 @@
|
|||||||
currentItem.classList.remove('exit-up');
|
currentItem.classList.remove('exit-up');
|
||||||
currentItem.classList.add('enter-down');
|
currentItem.classList.add('enter-down');
|
||||||
isRecognitionTransitioning = false;
|
isRecognitionTransitioning = false;
|
||||||
|
|
||||||
|
// If there's pending data to render, render it now
|
||||||
|
if (pendingDataRender) {
|
||||||
|
console.log('Recognition Carousel: Transition complete, rendering pending data');
|
||||||
|
const dataToRender = pendingDataRender;
|
||||||
|
pendingDataRender = null;
|
||||||
|
renderEvents(dataToRender);
|
||||||
|
}
|
||||||
}, 800);
|
}, 800);
|
||||||
|
|
||||||
currentRecognitionIndex = nextIndex;
|
currentRecognitionIndex = nextIndex;
|
||||||
@@ -1853,6 +1894,10 @@
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
|
// Debug: log recognition count
|
||||||
|
const recCount = data.current ? data.current.filter(e => e.typecolor === 'recognition').length : 0;
|
||||||
|
console.log(`Fetch: Got ${recCount} recognitions, ${data.current ? data.current.length : 0} total current events`);
|
||||||
|
|
||||||
renderEvents(data);
|
renderEvents(data);
|
||||||
updateLastUpdateTime();
|
updateLastUpdateTime();
|
||||||
setConnectionStatus(true);
|
setConnectionStatus(true);
|
||||||
|
|||||||
81
sql/update_network_devices_view.sql
Normal file
81
sql/update_network_devices_view.sql
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- FILE: update_network_devices_view.sql
|
||||||
|
-- PURPOSE: Update vw_network_devices to use model's machinetypeid (with fallback)
|
||||||
|
-- DATE: 2026-01-29
|
||||||
|
--
|
||||||
|
-- DESCRIPTION:
|
||||||
|
-- This update changes vw_network_devices to prefer model.machinetypeid over
|
||||||
|
-- machines.machinetypeid (deprecating the latter). Uses a hybrid approach:
|
||||||
|
-- - If model has a valid network device machinetypeid (16,17,18,19,20,46), use it
|
||||||
|
-- - Otherwise fall back to machines.machinetypeid for backward compatibility
|
||||||
|
--
|
||||||
|
-- Also adds Firewall (machinetypeid=46) to the list of network device types.
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW vw_network_devices AS
|
||||||
|
-- Printers (from separate printers table)
|
||||||
|
SELECT
|
||||||
|
'Printer' AS device_type,
|
||||||
|
p.printerid AS device_id,
|
||||||
|
p.printerwindowsname AS device_name,
|
||||||
|
p.modelid AS modelid,
|
||||||
|
m.modelnumber AS modelnumber,
|
||||||
|
v.vendor AS vendor,
|
||||||
|
p.serialnumber AS serialnumber,
|
||||||
|
p.ipaddress AS ipaddress,
|
||||||
|
NULL AS description,
|
||||||
|
p.maptop AS maptop,
|
||||||
|
p.mapleft AS mapleft,
|
||||||
|
p.isactive AS isactive,
|
||||||
|
NULL AS idfid,
|
||||||
|
NULL AS idfname,
|
||||||
|
NULL AS macaddress,
|
||||||
|
p.fqdn AS fqdn
|
||||||
|
FROM printers p
|
||||||
|
LEFT JOIN models m ON p.modelid = m.modelnumberid
|
||||||
|
LEFT JOIN vendors v ON m.vendorid = v.vendorid
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
-- Network devices from machines table
|
||||||
|
-- HYBRID: Use model's machinetypeid if valid network device type,
|
||||||
|
-- otherwise fall back to machine's machinetypeid
|
||||||
|
SELECT
|
||||||
|
mt.machinetype AS device_type,
|
||||||
|
ma.machineid AS device_id,
|
||||||
|
COALESCE(ma.alias, ma.machinenumber) AS device_name,
|
||||||
|
ma.modelnumberid AS modelid,
|
||||||
|
mo.modelnumber AS modelnumber,
|
||||||
|
ve.vendor AS vendor,
|
||||||
|
ma.serialnumber AS serialnumber,
|
||||||
|
c.address AS ipaddress,
|
||||||
|
ma.machinenotes AS description,
|
||||||
|
ma.maptop AS maptop,
|
||||||
|
ma.mapleft AS mapleft,
|
||||||
|
ma.isactive AS isactive,
|
||||||
|
NULL AS idfid,
|
||||||
|
NULL AS idfname,
|
||||||
|
c.macaddress AS macaddress,
|
||||||
|
ma.fqdn AS fqdn
|
||||||
|
FROM machines ma
|
||||||
|
LEFT JOIN models mo ON ma.modelnumberid = mo.modelnumberid
|
||||||
|
JOIN machinetypes mt ON mt.machinetypeid = COALESCE(
|
||||||
|
-- Prefer model's machinetypeid if it's a valid network device type
|
||||||
|
CASE WHEN mo.machinetypeid IN (16,17,18,19,20,46) THEN mo.machinetypeid ELSE NULL END,
|
||||||
|
-- Fall back to machine's machinetypeid
|
||||||
|
ma.machinetypeid
|
||||||
|
)
|
||||||
|
LEFT JOIN vendors ve ON mo.vendorid = ve.vendorid
|
||||||
|
LEFT JOIN communications c ON ma.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1
|
||||||
|
WHERE COALESCE(
|
||||||
|
CASE WHEN mo.machinetypeid IN (16,17,18,19,20,46) THEN mo.machinetypeid ELSE NULL END,
|
||||||
|
ma.machinetypeid
|
||||||
|
) IN (16, 17, 18, 19, 20, 46);
|
||||||
|
|
||||||
|
-- Network device type IDs:
|
||||||
|
-- 16 = Access Point
|
||||||
|
-- 17 = IDF
|
||||||
|
-- 18 = Camera
|
||||||
|
-- 19 = Switch
|
||||||
|
-- 20 = Server
|
||||||
|
-- 46 = Firewall (newly added)
|
||||||
Reference in New Issue
Block a user