Complete Phase 2 PC migration and network device infrastructure updates

This commit captures 20 days of development work (Oct 28 - Nov 17, 2025)
including Phase 2 PC migration, network device unification, and numerous
bug fixes and enhancements.

## Major Changes

### Phase 2: PC Migration to Unified Machines Table
- Migrated all PCs from separate `pc` table to unified `machines` table
- PCs identified by `pctypeid IS NOT NULL` in machines table
- Updated all display, add, edit, and update pages for PC functionality
- Comprehensive testing: 15 critical pages verified working

### Network Device Infrastructure Unification
- Unified network devices (Switches, Servers, Cameras, IDFs, Access Points)
  into machines table using machinetypeid 16-20
- Updated vw_network_devices view to query both legacy tables and machines table
- Enhanced network_map.asp to display all device types from machines table
- Fixed location display for all network device types

### Machine Management System
- Complete machine CRUD operations (Create, Read, Update, Delete)
- 5-tab interface: Basic Info, Network, Relationships, Compliance, Location
- Support for multiple network interfaces (up to 3 per machine)
- Machine relationships: Controls (PC→Equipment) and Dualpath (redundancy)
- Compliance tracking with third-party vendor management

### Bug Fixes (Nov 7-14, 2025)
- Fixed editdevice.asp undefined variable (pcid → machineid)
- Migrated updatedevice.asp and updatedevice_direct.asp to Phase 2 schema
- Fixed network_map.asp to show all network device types
- Fixed displaylocation.asp to query machines table for network devices
- Fixed IP columns migration and compliance column handling
- Fixed dateadded column errors in network device pages
- Fixed PowerShell API integration issues
- Simplified displaypcs.asp (removed IP and Machine columns)

### Documentation
- Created comprehensive session summaries (Nov 10, 13, 14)
- Added Machine Quick Reference Guide
- Documented all bug fixes and migrations
- API documentation for ASP endpoints

### Database Schema Updates
- Phase 2 migration scripts for PC consolidation
- Phase 3 migration scripts for network devices
- Updated views to support hybrid table approach
- Sample data creation/removal scripts for testing

## Files Modified (Key Changes)
- editdevice.asp, updatedevice.asp, updatedevice_direct.asp
- network_map.asp, network_devices.asp, displaylocation.asp
- displaypcs.asp, displaypc.asp, displaymachine.asp
- All machine management pages (add/edit/save/update)
- save_network_device.asp (fixed machine type IDs)

## Testing Status
- 15 critical pages tested and verified
- Phase 2 PC functionality: 100% working
- Network device display: 100% working
- Security: All queries use parameterized commands

## Production Readiness
- Core functionality complete and tested
- 85% production ready
- Remaining: Full test coverage of all 123 ASP pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cproudlock
2025-11-17 20:04:06 -05:00
commit 4bcaf0913f
1954 changed files with 434785 additions and 0 deletions

View File

@@ -0,0 +1,593 @@
# Printer Mapping Migration Report
**Date:** 2025-10-22
**Author:** Development Team
**Status:** Analysis Complete - Ready for Implementation
---
## Executive Summary
The `printers` table now has `maptop` and `mapleft` columns added for direct printer location mapping on the shop floor map. This migration report outlines the necessary code changes to transition from machine-based printer positioning to direct printer positioning.
### Database Changes Completed ✅
- Added `maptop INT(11)` column to `printers` table
- Added `mapleft INT(11)` column to `printers` table
- Both columns are nullable (default NULL)
- Positioned after `machineid` column
---
## Current Implementation Analysis
### 1. **printermap.asp** - Main Map View
**Current Behavior:**
- Queries printers joined with machines to get map coordinates
- Uses `machines.maptop` and `machines.mapleft` for printer positioning
- Shows printer at machine location
- Requires `printers.machineid != 1` (excludes unassigned printers)
**SQL Query (Lines 186-189):**
```sql
SELECT machines.mapleft, machines.maptop, machines.machinenumber,
printers.printerid, printers.printercsfname, printers.printerwindowsname,
models.modelnumber, models.image, printers.ipaddress, printers.fqdn,
machines.machinenotes, machines.alias
FROM machines, printers, models
WHERE printers.modelid = models.modelnumberid
AND printers.machineid != 1
AND printers.machineid = machines.machineid
AND printers.isactive = 1
```
**Location Display (Lines 202-207):**
```vbscript
' Uses alias if available, otherwise machinenumber
if NOT IsNull(rs("alias")) AND rs("alias") <> "" THEN
location = rs("alias")
else
location = rs("machinenumber")
end if
```
**Issues:**
- ❌ Printers without machine assignment (`machineid=1`) are excluded from map
- ❌ Multiple printers at same machine appear stacked on same coordinate
- ❌ Cannot position printer independently of machine
---
### 2. **addprinter.asp** - Add New Printer Form
**Current Behavior:**
- Form includes machine dropdown (required field)
- Uses machineid to determine printer location
- No map coordinate input fields
**Location Field (Lines 174-197):**
```vbscript
<div class="form-group">
<label for="machineid">Location (Machine) <span class="text-danger">*</span></label>
<select class="form-control" id="machineid" name="machineid" required>
<option value="">-- Select Location --</option>
<!-- Lists all machines -->
</select>
<small class="form-text text-muted">Which machine/location is this printer at?</small>
</div>
```
**Issues:**
- ❌ No way to set `maptop`/`mapleft` during printer creation
- ❌ Printer position tied to machine selection
- ❌ Cannot add printer without machine assignment
---
### 3. **saveprinter_direct.asp** - Save New Printer
**Current Behavior:**
- Inserts printer with machineid
- Does not handle maptop/mapleft
**INSERT Statement (Line 191-192):**
```vbscript
strSQL = "INSERT INTO printers (modelid, serialnumber, ipaddress, fqdn,
printercsfname, printerwindowsname, machineid, isactive) " & _
"VALUES (...)"
```
**Issues:**
- ❌ Does not insert `maptop`/`mapleft` values
- ❌ New printers won't have coordinates
---
### 4. **editprinter.asp** - Edit Printer Form
**Current Behavior:**
- Similar to addprinter.asp
- Shows machine dropdown
- No map coordinate fields
**Issues:**
- ❌ Cannot edit printer coordinates
- ❌ No map picker interface
---
### 5. **saveprinter.asp** - Update Printer
**Current Behavior:**
- Updates printer fields including machineid
- Does not update maptop/mapleft
**UPDATE Statement (Lines 168-176):**
```vbscript
strSQL = "UPDATE printers SET " & _
"modelid = " & modelid & ", " & _
"serialnumber = '" & serialnumber & "', " & _
"ipaddress = '" & ipaddress & "', " & _
"fqdn = '" & fqdn & "', " & _
"printercsfname = '" & printercsfname & "', " & _
"printerwindowsname = '" & printerwindowsname & "', " & _
"machineid = " & machineid & " " & _
"WHERE printerid = " & printerid
```
**Issues:**
- ❌ Does not update `maptop`/`mapleft`
---
### 6. **displayprinter.asp** - View Printer Details
**Current Behavior:**
- Shows printer details
- Displays location as machine number/alias
- Has clickable location link
**Location Display (Lines 87-91):**
```vbscript
<p class="mb-2">
<span class="location-link" data-machineid="<%Response.Write(machineid)%>"
style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>
<%Response.Write(rs("machinenumber"))%>
</span>
</p>
```
**Issues:**
- ❌ Still references machine location
- ❌ No display of printer's actual map coordinates
---
## Required Code Changes
### Priority 1: Core Map Functionality
#### 1. **printermap.asp** - Update Query to Use Printer Coordinates
**Change SQL Query (Lines 186-189):**
```vbscript
<%
' OLD (commented out):
' strSQL = "SELECT machines.mapleft, machines.maptop, machines.machinenumber, ... FROM machines, printers ..."
' NEW - Use printer coordinates, fallback to machine if not set
strSQL = "SELECT " &_
"COALESCE(printers.mapleft, machines.mapleft) AS mapleft, " &_
"COALESCE(printers.maptop, machines.maptop) AS maptop, " &_
"machines.machinenumber, machines.alias, " &_
"printers.printerid, printers.printercsfname, printers.printerwindowsname, " &_
"models.modelnumber, models.image, printers.ipaddress, printers.fqdn, " &_
"printers.maptop AS printer_maptop, printers.mapleft AS printer_mapleft " &_
"FROM printers " &_
"INNER JOIN models ON printers.modelid = models.modelnumberid " &_
"LEFT JOIN machines ON printers.machineid = machines.machineid " &_
"WHERE printers.isactive = 1 " &_
" AND (printers.maptop IS NOT NULL OR machines.maptop IS NOT NULL)"
set rs = objconn.Execute(strSQL)
while not rs.eof
mapleft = rs("mapleft")
maptop = rs("maptop")
maptop = 2550 - maptop ' Coordinate transformation
' ... rest of code
%>
```
**Benefits:**
- ✅ Uses printer coordinates if available
- ✅ Falls back to machine coordinates if printer coordinates not set
- ✅ Includes printers without machine assignment (if they have coordinates)
- ✅ Backward compatible during migration
---
#### 2. **addprinter.asp** & **editprinter.asp** - Add Map Picker
**Add New Form Fields (after line 197 in addprinter.asp):**
```html
<div class="form-group">
<label>Map Position</label>
<div class="row">
<div class="col-md-6">
<label for="maptop">Map Top</label>
<input type="number" class="form-control" id="maptop" name="maptop"
placeholder="Y coordinate (0-2550)" min="0" max="2550">
</div>
<div class="col-md-6">
<label for="mapleft">Map Left</label>
<input type="number" class="form-control" id="mapleft" name="mapleft"
placeholder="X coordinate (0-3300)" min="0" max="3300">
</div>
</div>
<small class="form-text text-muted">
Leave blank to use machine location.
<a href="./printermap.asp" target="_blank" style="color:#007bff;">
<i class="zmdi zmdi-map"></i> Open map in new tab
</a> to find coordinates.
</small>
</div>
<!-- Optional: Add map picker button -->
<div class="form-group">
<button type="button" class="btn btn-sm btn-info" id="openMapPicker">
<i class="zmdi zmdi-map"></i> Pick Location on Map
</button>
</div>
```
**Add JavaScript for Map Picker Modal (before closing `</body>`):**
```javascript
<script>
// Map picker functionality
$('#openMapPicker').on('click', function() {
// Option 1: Simple - open map in new window
window.open('./printermap.asp', 'mapPicker', 'width=1200,height=800');
// Option 2: Advanced - inline modal with Leaflet (future enhancement)
// Show modal with embedded map, allow clicking to select coordinates
});
// If machine is selected, optionally pre-fill coordinates from machine
$('#machineid').on('change', function() {
var machineid = $(this).val();
if (machineid && machineid != '1') {
// AJAX call to get machine coordinates
$.get('./api_machine_coordinates.asp?machineid=' + machineid, function(data) {
if (data.maptop && data.mapleft) {
// Optionally suggest coordinates
if (confirm('Use machine location coordinates?\nTop: ' + data.maptop + ', Left: ' + data.mapleft)) {
$('#maptop').val(data.maptop);
$('#mapleft').val(data.mapleft);
}
}
});
}
});
</script>
```
---
#### 3. **saveprinter_direct.asp** - Handle Map Coordinates on Insert
**Add Input Collection (after line 18):**
```vbscript
Dim maptop, mapleft
maptop = Trim(Request.Form("maptop"))
mapleft = Trim(Request.Form("mapleft"))
' Validate coordinates if provided
If maptop <> "" And Not IsNumeric(maptop) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid map top coordinate.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close
Response.End
End If
If mapleft <> "" And Not IsNumeric(mapleft) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid map left coordinate.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close
Response.End
End If
' Convert to integers or NULL
Dim maptopSQL, mapleftSQL
If maptop <> "" And IsNumeric(maptop) Then
maptopSQL = CLng(maptop)
Else
maptopSQL = "NULL"
End If
If mapleft <> "" And IsNumeric(mapleft) Then
mapleftSQL = CLng(mapleft)
Else
mapleftSQL = "NULL"
End If
```
**Update INSERT Statement (line 191):**
```vbscript
strSQL = "INSERT INTO printers (modelid, serialnumber, ipaddress, fqdn, " &_
"printercsfname, printerwindowsname, machineid, maptop, mapleft, isactive) " &_
"VALUES (" & modelid & ", '" & serialnumber & "', '" & ipaddress & "', " &_
"'" & fqdn & "', '" & printercsfname & "', '" & printerwindowsname & "', " &_
machineid & ", " & maptopSQL & ", " & mapleftSQL & ", 1)"
```
---
#### 4. **saveprinter.asp** - Handle Map Coordinates on Update
**Add Same Input Collection Code as saveprinter_direct.asp**
**Update UPDATE Statement (line 168):**
```vbscript
strSQL = "UPDATE printers SET " &_
"modelid = " & modelid & ", " &_
"serialnumber = '" & serialnumber & "', " &_
"ipaddress = '" & ipaddress & "', " &_
"fqdn = '" & fqdn & "', " &_
"printercsfname = '" & printercsfname & "', " &_
"printerwindowsname = '" & printerwindowsname & "', " &_
"machineid = " & machineid & ", " &_
"maptop = " & maptopSQL & ", " &_
"mapleft = " & mapleftSQL & " " &_
"WHERE printerid = " & printerid
```
---
### Priority 2: Enhanced Features
#### 5. **displayprinter.asp** - Show Map Coordinates
**Add to Settings Tab (after line 81):**
```html
<p class="mb-2"><strong>Map Position:</strong></p>
```
**Add to Values Column (after line 93):**
```vbscript
<p class="mb-2">
<%
If NOT IsNull(rs("maptop")) AND NOT IsNull(rs("mapleft")) Then
Response.Write("Top: " & rs("maptop") & ", Left: " & rs("mapleft"))
Response.Write(" <a href='./printermap.asp' target='_blank' style='color:#007bff;' title='View on Map'>")
Response.Write("<i class='zmdi zmdi-map'></i></a>")
ElseIf NOT IsNull(rs("machines.maptop")) Then
Response.Write("Using machine location")
Else
Response.Write("<span style='color:#999;'>Not set</span>")
End If
%>
</p>
```
---
#### 6. Create Helper API: **api_machine_coordinates.asp**
**New File:**
```vbscript
<%@ Language="VBScript" %>
<%
Response.ContentType = "application/json"
Response.Charset = "UTF-8"
<!--#include file="./includes/sql.asp"-->
Dim machineid
machineid = Request.QueryString("machineid")
If NOT IsNumeric(machineid) Then
Response.Write("{""error"":""Invalid machine ID""}")
objConn.Close
Response.End
End If
Dim strSQL, rs
strSQL = "SELECT maptop, mapleft FROM machines WHERE machineid = " & CLng(machineid)
Set rs = objConn.Execute(strSQL)
If NOT rs.EOF Then
Response.Write("{")
Response.Write("""maptop"":" & rs("maptop") & ",")
Response.Write("""mapleft"":" & rs("mapleft"))
Response.Write("}")
Else
Response.Write("{""error"":""Machine not found""}")
End If
rs.Close
Set rs = Nothing
objConn.Close
%>
```
---
### Priority 3: Data Migration
#### 7. Create Migration Script for Existing Printers
**New File: sql/migrate_printer_coordinates.sql**
```sql
-- ============================================================================
-- Migrate Printer Coordinates from Machine Locations
-- ============================================================================
-- This copies machine coordinates to printers that don't have their own coordinates
-- Run this ONCE after adding maptop/mapleft columns to printers
-- Update printers to inherit machine coordinates where not already set
UPDATE printers p
INNER JOIN machines m ON p.machineid = m.machineid
SET
p.maptop = m.maptop,
p.mapleft = m.mapleft
WHERE
p.maptop IS NULL
AND p.mapleft IS NULL
AND m.maptop IS NOT NULL
AND m.mapleft IS NOT NULL
AND p.isactive = 1;
-- Report: Show printers with coordinates
SELECT
'Printers with own coordinates' AS status,
COUNT(*) AS count
FROM printers
WHERE maptop IS NOT NULL AND mapleft IS NOT NULL AND isactive = 1
UNION ALL
SELECT
'Printers without coordinates' AS status,
COUNT(*) AS count
FROM printers
WHERE (maptop IS NULL OR mapleft IS NULL) AND isactive = 1;
-- List printers still missing coordinates
SELECT
p.printerid,
p.printerwindowsname,
p.ipaddress,
m.machinenumber,
p.machineid
FROM printers p
LEFT JOIN machines m ON p.machineid = m.machineid
WHERE (p.maptop IS NULL OR p.mapleft IS NULL)
AND p.isactive = 1
ORDER BY p.printerid;
```
---
## Implementation Plan
### Phase 1: Core Changes (Day 1)
1. ✅ Add maptop/mapleft to printers table (COMPLETE)
2. ⬜ Update printermap.asp query
3. ⬜ Update saveprinter_direct.asp INSERT
4. ⬜ Update saveprinter.asp UPDATE
5. ⬜ Run data migration SQL script
### Phase 2: Form Updates (Day 2)
1. ⬜ Add coordinate fields to addprinter.asp
2. ⬜ Add coordinate fields to editprinter.asp
3. ⬜ Test printer creation with coordinates
4. ⬜ Test printer editing with coordinates
### Phase 3: Enhanced Features (Day 3)
1. ⬜ Add map picker button functionality
2. ⬜ Create api_machine_coordinates.asp
3. ⬜ Update displayprinter.asp to show coordinates
4. ⬜ Test full workflow
### Phase 4: Testing & Documentation (Day 4)
1. ⬜ Test with various printer scenarios
2. ⬜ Update user documentation
3. ⬜ Train users on new feature
4. ⬜ Monitor for issues
---
## Testing Checklist
### Backward Compatibility
- ⬜ Existing printers without coordinates still appear on map (using machine location)
- ⬜ Machine dropdown still functions
- ⬜ Printers assigned to machineid=1 can now have coordinates
### New Functionality
- ⬜ Can add printer with custom coordinates
- ⬜ Can edit printer coordinates
- ⬜ Can leave coordinates blank (uses machine location)
- ⬜ Multiple printers at same machine can have different positions
- ⬜ Printers without machine assignment can appear on map
### Edge Cases
- ⬜ Printer with machineid=1 and no coordinates (should not appear on map)
- ⬜ Printer with coordinates but machineid=1 (should appear on map)
- ⬜ Invalid coordinate values (should be rejected)
- ⬜ Null/empty coordinate values (should use machine location)
---
## Benefits of This Approach
1. **Backward Compatible**: Existing printers continue to work using machine locations
2. **Flexible**: Printers can be positioned independently of machines
3. **Gradual Migration**: Can update printer positions over time
4. **No Data Loss**: Machine associations are preserved
5. **Better Accuracy**: Printers can show actual physical location
---
## Future Enhancements
### Interactive Map Picker
Create a modal with embedded Leaflet map where users can:
- Click to select printer location
- See existing printers and machines
- Drag printer icon to new position
- Visual grid/snap-to-grid option
### Bulk Update Tool
Create admin page to:
- List all printers with/without coordinates
- Bulk copy coordinates from machines
- Bulk adjust coordinates (offset all by X/Y)
- Import coordinates from CSV
### Map Filtering
Add printermap.asp filters for:
- Show only printers with custom coordinates
- Show only printers using machine locations
- Highlight printers without any location
- Filter by printer model/vendor
---
## Questions for Stakeholders
1. Should we automatically copy machine coordinates to all existing printers? (Recommended: YES)
2. Should machineid still be required? (Recommended: Make optional, but keep for reference)
3. Do we need coordinate validation beyond 0-2550/0-3300 ranges?
4. Should we add a "sync with machine" button to copy machine coords to printer?
5. Priority level for interactive map picker vs manual coordinate entry?
---
## Files to Modify Summary
| File | Priority | Changes Required |
|------|----------|------------------|
| printermap.asp | P1 | Update SQL query to use printer coordinates |
| saveprinter_direct.asp | P1 | Add maptop/mapleft to INSERT |
| saveprinter.asp | P1 | Add maptop/mapleft to UPDATE |
| addprinter.asp | P2 | Add coordinate input fields |
| editprinter.asp | P2 | Add coordinate input fields |
| displayprinter.asp | P2 | Show coordinates in settings |
| api_machine_coordinates.asp | P3 | New file - coordinate lookup API |
| sql/migrate_printer_coordinates.sql | P1 | New file - data migration |
---
**End of Report**