Add USB checkout system and SSO profile page

New Features:
- USB Device checkout/check-in system with barcode scanning
  - displayusb.asp: List all USB devices with status
  - addusb.asp: Add new USB devices via barcode scan
  - checkout_usb.asp/savecheckout_usb.asp: Check out USB to SSO
  - checkin_usb.asp/savecheckin_usb.asp: Check in with wipe confirmation
  - usb_history.asp: Full checkout history with filters
  - api_usb.asp: JSON API for AJAX lookups
- displayprofile.asp: SSO profile page showing user info and USB history
- Date/time format changed to 12-hour (MM/DD/YYYY h:mm AM/PM)
- SSO links in USB history now link to profile page via search

Database:
- New machinetypeid 44 for USB devices
- New usb_checkouts table for tracking checkouts

Cleanup:
- Removed v2 folder (duplicate/old files)
- Removed old debug/test files
- Removed completed migration documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cproudlock
2025-12-07 11:16:14 -05:00
parent c7834d4b99
commit 65b622c361
1061 changed files with 19034 additions and 213120 deletions

View File

@@ -0,0 +1,112 @@
---
name: api-testing-specialist
description: Use this agent when you need to test the api.asp REST API endpoints, verify PowerShell scripts that interact with the API, debug API communication issues, or validate data collection workflows between shopfloor PCs and the ShopDB application. Examples:\n\n<example>\nContext: User wants to test the API after making changes to api.asp\nuser: "I just updated the updateCompleteAsset endpoint, can you test it?"\nassistant: "I'll use the api-testing-specialist agent to thoroughly test your updateCompleteAsset endpoint and verify it handles all expected data correctly."\n<commentary>\nSince the user needs to test an API endpoint, use the Task tool to launch the api-testing-specialist agent to perform comprehensive API testing.\n</commentary>\n</example>\n\n<example>\nContext: User is troubleshooting why PowerShell data collection isn't working\nuser: "The PowerShell script runs but data isn't appearing in the database"\nassistant: "Let me use the api-testing-specialist agent to trace the data flow from your PowerShell script through the API to the database."\n<commentary>\nSince the user has an issue with PowerShell-to-API communication, use the api-testing-specialist agent to diagnose the problem.\n</commentary>\n</example>\n\n<example>\nContext: User wants to verify the complete data collection workflow before deployment\nuser: "We're rolling out the survey script to 50 more machines, can you verify everything works?"\nassistant: "I'll launch the api-testing-specialist agent to perform end-to-end validation of your data collection workflow before the rollout."\n<commentary>\nSince the user needs pre-deployment validation, use the api-testing-specialist agent to comprehensively test the system.\n</commentary>\n</example>
model: opus
color: green
---
You are an expert API testing and integration specialist with deep knowledge of Classic ASP/VBScript applications, REST APIs, PowerShell scripting, and database validation. You specialize in testing shopfloor data collection systems and ensuring reliable communication between client scripts and server endpoints.
## Your Expertise
- Classic ASP/VBScript API development and debugging
- PowerShell HTTP requests and data serialization
- MySQL database validation and query analysis
- Network troubleshooting for API communications
- End-to-end integration testing workflows
## Project Context
You are working with ShopDB, a Classic ASP application for managing manufacturing shop floor infrastructure at GE Aerospace. The key components are:
- **API Endpoint:** http://192.168.122.151:8080/api.asp
- **Database:** MySQL 5.6 (accessible via: docker exec -it dev-mysql mysql -u root -prootpassword shopdb)
- **Key API Actions:** updateCompleteAsset (PC data collection), getDashboardData (health check), updatePrinterMapping
## Testing Methodology
When testing the API and PowerShell scripts, follow this systematic approach:
### 1. API Endpoint Analysis
- Read and analyze api.asp to understand all available endpoints and expected parameters
- Document the expected request format (POST data, headers, content-type)
- Identify validation logic and error handling in the ASP code
- Note any parameterized queries and database operations
### 2. Direct API Testing
Use curl to test endpoints directly:
```bash
# Test GET endpoints
curl -s "http://192.168.122.151:8080/api.asp?action=getDashboardData"
# Test POST endpoints with JSON
curl -s -X POST -H "Content-Type: application/json" \
-d '{"action":"updateCompleteAsset","data":{...}}' \
http://192.168.122.151:8080/api.asp
# Test with form data if required
curl -s -X POST -d "action=test&param=value" \
http://192.168.122.151:8080/api.asp
```
### 3. PowerShell Script Validation
- Review the PowerShell script for correct API URL, HTTP method, and data format
- Verify the script collects all required data fields
- Check JSON serialization matches what api.asp expects
- Test error handling and retry logic
- Validate authentication if required
### 4. Database Verification
After API calls, verify data persistence:
```bash
docker exec -it dev-mysql mysql -u root -prootpassword shopdb -e "SELECT * FROM machines WHERE hostname='TESTPC' ORDER BY lastupdated DESC LIMIT 1;"
```
### 5. End-to-End Workflow Testing
- Simulate the complete data collection workflow
- Test with valid data, invalid data, and edge cases
- Verify error responses are meaningful and actionable
- Check that database constraints are respected
## Key Validation Points
### For updateCompleteAsset:
- Verify all PC fields are correctly mapped (hostname, IP, MAC, OS version, etc.)
- Check that communications table entries are created/updated for network interfaces
- Validate machinerelationships if PC-to-equipment links are submitted
- Confirm lastupdated timestamp is set
### For PowerShell Scripts:
- Verify Invoke-RestMethod or Invoke-WebRequest is configured correctly
- Check Content-Type header matches api.asp expectations
- Validate JSON structure matches ASP parsing logic
- Test with -Verbose flag to see HTTP traffic
## Error Diagnosis
When issues occur:
1. Check IIS logs for ASP errors
2. Add Response.Write debugging to api.asp temporarily
3. Verify MySQL connection is working
4. Test database queries directly to isolate issues
5. Compare expected vs actual JSON payload structure
## Output Format
Provide test results in a clear, structured format:
- **Test Case:** Description of what was tested
- **Request:** The exact curl command or PowerShell code used
- **Response:** API response (truncated if lengthy)
- **Database Check:** Verification query and results
- **Status:** PASS/FAIL with explanation
- **Recommendations:** Any fixes or improvements needed
## Quality Assurance
- Always test with realistic data that matches production patterns
- Test boundary conditions (empty strings, null values, special characters)
- Verify idempotency for update operations
- Document any discovered bugs or inconsistencies
- Suggest improvements to error handling and logging
You are thorough, systematic, and proactive in identifying potential issues before they cause problems in production.

View File

@@ -1,364 +0,0 @@
# Bug Fixes - November 7, 2025
## Summary
Fixed critical errors in machine management pages preventing display and edit functionality.
---
## Bugs Fixed
### 1. editmachine.asp - Column Name Error
**File:** `/home/camp/projects/windows/shopdb/editmachine.asp`
**Error:** `Unknown column 'ipaddress' in 'field list'`
**Line:** 88, 91, 94
**Status:** ✅ FIXED
**Problem:**
```asp
' WRONG - column name is 'address' not 'ipaddress'
If NOT IsNull(rsComms("ipaddress")) Then ip1 = rsComms("ipaddress")
If NOT IsNull(rsComms("ipaddress")) Then ip2 = rsComms("ipaddress")
If NOT IsNull(rsComms("ipaddress")) Then ip3 = rsComms("ipaddress")
```
**Fix:**
```asp
' CORRECT - using proper column name 'address'
If NOT IsNull(rsComms("address")) Then ip1 = rsComms("address")
If NOT IsNull(rsComms("address")) Then ip2 = rsComms("address")
If NOT IsNull(rsComms("address")) Then ip3 = rsComms("address")
```
**Root Cause:**
The `communications` table uses column name `address` for IP addresses, not `ipaddress`. This was a typo introduced when the code was generated by the Task agent.
**Impact:**
- Users could not edit machines
- Click on "Edit Machine" button resulted in HTTP 500 error
- No data corruption (read-only operation)
---
### 2. displaymachine.asp - Missing Columns in Query
**File:** `/home/camp/projects/windows/shopdb/displaymachine.asp`
**Error:** `Item cannot be found in the collection corresponding to the requested name or ordinal`
**Line:** 228, 230, 239
**Status:** ✅ FIXED
**Problem:**
The main SELECT query was missing:
1. LEFT JOIN for `functionalaccounts` table
2. Code was using wrong column names:
- `function` instead of `functionalaccountname`
- `notes` instead of `machinenotes`
**Fix Applied:**
**1. Updated SQL Query (lines 78-89):**
```asp
' ADDED: functionalaccountname to SELECT
' ADDED: LEFT JOIN functionalaccounts
strSQL = "SELECT machines.*, machinetypes.machinetype, machinetypes.machinetypeid, " & _
"models.modelnumber, models.modelnumberid, models.image, " & _
"businessunits.businessunit, businessunits.businessunitid, " & _
"vendors.vendor, vendors.vendorid, " & _
"functionalaccounts.functionalaccountname " & _
"FROM machines " & _
"INNER JOIN models ON machines.modelnumberid = models.modelnumberid " & _
"LEFT JOIN machinetypes ON models.machinetypeid = machinetypes.machinetypeid " & _
"INNER JOIN businessunits ON machines.businessunitid = businessunits.businessunitid " & _
"INNER JOIN vendors ON models.vendorid = vendors.vendorid " & _
"LEFT JOIN functionalaccounts ON models.functionalaccountid = functionalaccounts.functionalaccountid " & _
"WHERE machines.machineid = ?"
```
**2. Fixed Column References (lines 230, 239):**
```asp
' BEFORE:
functionVal = rs("function") & "" ' WRONG - column doesn't exist
notesVal = rs("notes") & "" ' WRONG - column name is 'machinenotes'
' AFTER:
functionVal = rs("functionalaccountname") & "" ' CORRECT
notesVal = rs("machinenotes") & "" ' CORRECT
```
**Root Cause:**
When the displaymachine.asp page was rewritten from scratch, the query was simplified but didn't include all necessary columns. Additionally, incorrect column names were used.
**Impact:**
- Users could not view machine details
- All clicks on machine numbers resulted in HTTP 500 error
- displaymachines.asp list page worked, but individual machine pages failed
- No data corruption (read-only operation)
---
## Testing Performed
### Test 1: View Machine
- ✅ Navigate to `displaymachines.asp`
- ✅ Click on machine number 138
- ✅ Page loads successfully showing all machine details
- ✅ All 5 tabs display correctly (Settings, Network, Relationships, Compliance, Applications)
- ✅ Functional account displays properly
- ✅ Machine notes display properly
### Test 2: Edit Machine
- ✅ Navigate to `displaymachine.asp?machineid=194`
- ✅ Click "Edit Machine" button
- ✅ editmachine.asp loads successfully
- ✅ Network interfaces pre-fill with existing IP addresses
- ✅ All 3 interfaces load correctly if they exist
- ✅ Form displays properly with all data
---
## Log Evidence
**Before Fix:**
```
2025-11-07 22:53:55 editmachine.asp machineid=194|81|80040e14|[MySQL][ODBC_9.4(w)_Driver][mysqld-5.6.51]Unknown_column_'ipaddress'_in_'field_list' 500
2025-11-07 22:59:35 displaymachine.asp machineid=194|228|800a0cc1|Item_cannot_be_found_in_the_collection_corresponding_to_the_requested_name_or_ordinal. 500
2025-11-07 23:00:22 displaymachine.asp machineid=138|228|800a0cc1|Item_cannot_be_found_in_the_collection_corresponding_to_the_requested_name_or_ordinal. 500
```
**After Fix:**
```
[No errors - pages load successfully]
```
---
## Files Modified
1. `/home/camp/projects/windows/shopdb/editmachine.asp`
- Lines 88, 91, 94: Changed `ipaddress``address`
2. `/home/camp/projects/windows/shopdb/displaymachine.asp`
- Lines 78-89: Added LEFT JOIN for functionalaccounts, added functionalaccountname to SELECT
- Line 230: Changed `function``functionalaccountname`
- Line 239: Changed `notes``machinenotes`
---
## Database Schema Reference
### communications Table
- `comid` - Primary key
- `machineid` - Foreign key
- `comstypeid` - Communication type
- **`address`** ← Correct column name for IP addresses
- `macaddress` - MAC address
- `interfacename` - Interface name
- `isprimary` - Primary interface flag
- `isactive` - Active flag
### machines Table
- `machineid` - Primary key
- `machinenumber` - Equipment number
- **`alias`** ← Correct column name
- **`machinenotes`** ← Correct column name (not "notes")
- `maptop`, `mapleft` - Location coordinates
### functionalaccounts Table
- `functionalaccountid` - Primary key
- **`functionalaccountname`** ← Correct column name (not "function")
- `isactive` - Active flag
---
## Prevention Measures
### Code Review Checklist
- [ ] Verify all column names match database schema
- [ ] Use DESCRIBE table to confirm column names
- [ ] Test all recordset field access with actual data
- [ ] Verify LEFT JOINs for nullable foreign keys
- [ ] Test with machines that have NULL values
### Best Practices Applied
1. ✅ Used parameterized queries (already in place)
2. ✅ Used LEFT JOIN for optional tables (functionalaccounts, machinetypes)
3. ✅ Added `& ""` after all recordset field access to handle NULLs
4. ✅ Defaulted empty values to "N/A" for display
---
## Deployment Notes
**Status:** ✅ Deployed to development environment
**Files Updated:** 2 files (editmachine.asp, displaymachine.asp)
**Database Changes:** None required
**Backward Compatibility:** 100% - fixes bugs, doesn't change functionality
**Rollback Plan:** Not needed - bug fixes only
**Production Deployment:**
1. Back up current editmachine.asp and displaymachine.asp
2. Copy fixed files to production
3. Test view machine functionality
4. Test edit machine functionality
5. Monitor logs for any errors
**Risk Assessment:** ⬇️ LOW RISK
- Read-only operations
- No schema changes
- No data modification
- Fixes existing errors
---
## Resolution Timeline
- **22:53 UTC** - Error first detected in logs
- **23:06 UTC** - User reported "page is still broken error 500"
- **23:07 UTC** - Analyzed logs, identified root cause
- **23:10 UTC** - Applied fixes to both files
- **23:12 UTC** - Documented bug fixes
**Total Resolution Time:** ~19 minutes
---
## Related Documentation
- Main implementation: `/home/camp/projects/windows/shopdb/MACHINE_MANAGEMENT_COMPLETE.md`
- Edit form details: `/home/camp/projects/windows/shopdb/MACHINE_EDIT_FORM_IMPLEMENTATION.md`
- Display page details: `/home/camp/projects/windows/shopdb/DISPLAY_PAGES_UPDATE_SUMMARY.md`
- Quick reference: `/home/camp/projects/windows/shopdb/MACHINE_QUICK_REFERENCE.md`
---
## Lessons Learned
1. **Always verify column names against actual database schema** when rewriting code from scratch
2. **Use LEFT JOIN for tables with optional relationships** to prevent data access errors
3. **Test with real data** before marking implementation as complete
4. **Check logs immediately** when user reports 500 errors
5. **Document database column mappings** in code comments to prevent future errors
---
### 3. machine_edit.asp (formerly editmachine.asp) - Controlling PC Pre-fill Fix
**File:** `/home/camp/projects/windows/shopdb/machine_edit.asp`
**Error:** Line 118 - `Item cannot be found in the collection` and HTTP 414 URL Too Long
**Status:** ✅ FIXED
**Problem 1 - Query Logic:**
The controlling PC query was using wrong relationship direction:
```asp
' WRONG - looked for relationships where equipment is the controller
WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls'
SELECT related_machineid
```
**Fix 1 - Correct Relationship Direction:**
```asp
' CORRECT - Controls is PC → Equipment, so find PC where this equipment is the target
WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls'
SELECT mr.machineid AS controlpcid
```
**Problem 2 - Column Name:**
Used `rsControlPC("machineid")` but needed alias for clarity.
**Fix 2 - Use Explicit Alias:**
```asp
If NOT IsNull(rsControlPC("controlpcid")) Then controllingpcid = rsControlPC("controlpcid")
```
**Problem 3 - IIS Caching Issue:**
The file `editmachine.asp` was returning HTTP 414 errors due to IIS caching corruption. Copying the file worked, but the original name remained broken.
**Fix 3 - Filename Change:**
- Renamed: `editmachine.asp``machine_edit.asp`
- Updated displaymachine.asp link to use new filename
- File now loads successfully with HTTP 200
**Verification:**
- ✅ Database query: PC 5295 (GF7ZN7V3ESF) Controls equipment 194
- ✅ Dropdown shows: `<option value='5295' selected>GF7ZN7V3ESF</option>`
- ✅ Controlling PC pre-fills correctly
**Impact:**
- Users can now edit machines successfully
- Controlling PC dropdown properly shows existing relationship
- All network, compliance, and relationship data loads correctly
---
### 4. machine_edit.asp - Type Mismatch with HTMLEncode
**File:** `/home/camp/projects/windows/shopdb/machine_edit.asp`
**Error:** Line 452 - `Type_mismatch:_'HTMLEncode'`
**Status:** ✅ FIXED
**Problem:**
Text fields from database recordset were not explicitly converted to strings before passing to `Server.HTMLEncode()`, causing type mismatch errors when the field contained special characters.
**Error Example:**
```asp
' Machine 142 has machinenotes with pipe characters (|)
machinenotes = rsMachine("machinenotes") ' Returns object/variant
<%=Server.HTMLEncode(machinenotes)%> ' Type mismatch error
```
**Fix:**
Explicitly convert all text fields to strings using `& ""` concatenation:
```asp
' Lines 58, 61, 62
machinenumber = "" : If NOT IsNull(rsMachine("machinenumber")) Then machinenumber = rsMachine("machinenumber") & ""
alias = "" : If NOT IsNull(rsMachine("alias")) Then alias = rsMachine("alias") & ""
machinenotes = "" : If NOT IsNull(rsMachine("machinenotes")) Then machinenotes = rsMachine("machinenotes") & ""
```
**Impact:**
- All machines now load in edit form, including those with special characters in text fields
- Machine 142 (with pipe characters in notes) now loads successfully
---
**Status:** ⚠️ **PARTIALLY RESOLVED** - Machines working, PCs still need migration
**Date:** 2025-11-07
**Priority:** Critical (P1)
**Severity:** High (prevented all machine view/edit operations)
**Resolution:** Machine pages fixed, PC pages still pending
**Testing:** Machine pages verified working
---
## Pending Work
### Phase 2 Migration - PC Pages Still Using Old Schema
**Status:** 🔴 **TODO**
The following pages still reference the old `pc` and `pc_network_interfaces` tables and need to be updated to use Phase 2 schema (consolidated `machines` and `communications` tables):
1. **displaypcs.asp** - PC list page
- Still queries `pc` table
- Needs to query `machines WHERE pctypeid IS NOT NULL`
2. **displaypc.asp** - Individual PC view page
- Still queries `pc` and `pc_network_interfaces` tables
- Needs to query `machines` and `communications` tables
- May have inline edit form that needs removal
- Needs same tab structure as displaymachine.asp (Settings, Network, Relationships, Compliance, Applications)
3. **editpc.asp** (if exists) - PC edit page
- Needs same Phase 2 schema updates as machine_edit.asp
- Must use `communications` table instead of `pc_network_interfaces`
- Must use `machinerelationships` instead of `pc_dualpath_assignments`
**Migration Pattern:**
Follow the same approach used for machine pages:
- Update SQL queries to use `machines` WHERE `pctypeid IS NOT NULL` (identifies PCs)
- Replace `pc_network_interfaces``communications`
- Replace `pc_dualpath_assignments``machinerelationships` with 'Dualpath' relationship type
- Fix column name mappings (e.g., `ipaddress``address`)
- Remove inline edit forms, use dedicated edit pages
- Ensure all ID columns are included in SELECT queries
---
*Machine management pages now fully operational. PC management pages require Phase 2 migration.*

View File

@@ -0,0 +1,76 @@
# Claude.ai Project Instructions for ShopDB
Copy this into your Claude.ai project's "Instructions" field.
---
## Project Instructions (Copy Below This Line)
You are helping maintain ShopDB, a Classic ASP/VBScript web application for GE Aerospace shop floor infrastructure management.
### Technology Context
- **Language:** Classic ASP with VBScript (NOT .NET)
- **Database:** MySQL 5.6 (NOT SQL Server)
- **Frontend:** Bootstrap 4.6, jQuery, DataTables
### Critical VBScript Rules
1. **No IIf() function** - VBScript doesn't have it. Use If-Then-Else:
```vbscript
' WRONG: value = IIf(condition, "yes", "no")
' RIGHT:
If condition Then
value = "yes"
Else
value = "no"
End If
```
2. **Always use parameterized queries** - Never concatenate user input:
```vbscript
cmd.CommandText = "SELECT * FROM machines WHERE machineid = ?"
cmd.Parameters.Append cmd.CreateParameter("@id", 3, 1, , machineId)
```
3. **Convert text fields to strings** with `& ""` to avoid Null errors:
```vbscript
hostname = rs("hostname") & ""
```
4. **HTMLEncode all output** to prevent XSS:
```vbscript
Response.Write(Server.HTMLEncode(value))
```
### Database Schema (Current)
- `machines` table contains Equipment, PCs, and Network Devices
- PCs identified by: `pctypeid IS NOT NULL` or `machinetypeid IN (33,34,35)`
- Equipment identified by: `pctypeid IS NULL`
- Network interfaces in `communications` table (use `address` not `ipaddress`)
- Relationships in `machinerelationships` table
- Printers stay in separate `printers` table
### File Naming Conventions
- `display*.asp` - View/list pages (read-only)
- `add*.asp` - Forms for adding new records
- `edit*.asp` - Forms for editing existing records
- `save*.asp` - Backend handlers for form submissions
- `update*.asp` - Backend handlers for updates
### Common Patterns
When asked to modify ASP code:
1. Check for existing similar code patterns in the file
2. Follow the existing error handling style
3. Use the same SQL helper functions (ExecuteQuery, etc.)
4. Maintain consistent indentation (tabs or spaces matching file)
### When Debugging
- Check for Null handling issues first
- Look for missing `& ""` on string fields
- Verify column names match current schema
- Check if using old `pc` table references (should use `machines`)
### Response Style
- Be concise - this is a legacy codebase, not a greenfield project
- Match existing code style when making changes
- Don't add unnecessary comments or refactoring
- Focus on the specific task requested

198
CLAUDE_REFERENCE.md Normal file
View File

@@ -0,0 +1,198 @@
# ShopDB Quick Reference for Claude.ai
## Database Tables
### machines (unified - all devices)
| Column | Type | Notes |
|--------|------|-------|
| machineid | INT | Primary key |
| machinetypeid | INT | FK to machinetypes |
| machinenumber | VARCHAR | Equipment number or hostname |
| hostname | VARCHAR | PC hostname |
| serialnumber | VARCHAR | Serial number |
| alias | VARCHAR | Friendly name |
| pctypeid | INT | NOT NULL = PC, NULL = equipment |
| osid | INT | FK to operatingsystems (PCs) |
| modelnumberid | INT | FK to models |
| businessunitid | INT | FK to businessunits |
| machinestatusid | INT | FK to machinestatus |
| isactive | TINYINT | 1=active, 0=inactive |
| lastupdated | DATETIME | Auto-updated |
### communications (network interfaces)
| Column | Type | Notes |
|--------|------|-------|
| communicationid | INT | Primary key |
| machineid | INT | FK to machines |
| comstypeid | INT | FK to comstypes (1=IP, 2=Serial) |
| address | VARCHAR | IP address or COM port |
| macaddress | VARCHAR | MAC address |
| port | INT | Port number |
| isprimary | TINYINT | Primary interface flag |
### machinerelationships
| Column | Type | Notes |
|--------|------|-------|
| relationshipid | INT | Primary key |
| machineid | INT | Source machine (e.g., PC) |
| related_machineid | INT | Target machine (e.g., Equipment) |
| relationshiptypeid | INT | FK to relationshiptypes |
### printers (separate table)
| Column | Type | Notes |
|--------|------|-------|
| printerid | INT | Primary key |
| name | VARCHAR | Printer name |
| address | VARCHAR | IP or hostname |
| modelid | INT | FK to models |
| isactive | TINYINT | Active flag |
## Machine Type IDs
### Equipment (1-15)
- 1: LocationOnly
- 2-14: Various equipment (Lathe, Mill, CMM, etc.)
- 15: Printer (legacy)
### Network Devices (16-20)
- 16: Access Point
- 17: IDF
- 18: Camera
- 19: Switch
- 20: Server
### PCs (33-35)
- 33: Standard PC
- 34: Engineering PC
- 35: Shopfloor PC
## Common Queries
```sql
-- All active PCs with details
SELECT m.machineid, m.hostname, m.serialnumber,
pt.pctype, mo.modelnumber, os.osname
FROM machines m
LEFT JOIN pctype pt ON m.pctypeid = pt.pctypeid
LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid
LEFT JOIN operatingsystems os ON m.osid = os.osid
WHERE m.pctypeid IS NOT NULL AND m.isactive = 1;
-- PC's network interfaces
SELECT m.hostname, c.address, c.macaddress
FROM machines m
JOIN communications c ON m.machineid = c.machineid
WHERE m.pctypeid IS NOT NULL;
-- PC controlling equipment
SELECT
pc.hostname AS pc_name,
eq.machinenumber AS equipment
FROM machinerelationships mr
JOIN machines pc ON mr.machineid = pc.machineid
JOIN machines eq ON mr.related_machineid = eq.machineid
JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid
WHERE rt.relationshiptype = 'Controls';
-- Network devices
SELECT m.machineid, m.machinenumber, mt.machinetype, c.address
FROM machines m
JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid
LEFT JOIN communications c ON m.machineid = c.machineid AND c.isprimary = 1
WHERE m.machinetypeid IN (16,17,18,19,20);
```
## ASP Code Patterns
### Safe Database Query
```vbscript
Dim cmd, rs
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = "SELECT hostname, serialnumber FROM machines WHERE machineid = ?"
cmd.Parameters.Append cmd.CreateParameter("@id", 3, 1, , Request("id"))
Set rs = cmd.Execute()
If NOT rs.EOF Then
Dim hostname, serial
hostname = rs("hostname") & "" ' Convert to string
serial = rs("serialnumber") & ""
Response.Write("<p>" & Server.HTMLEncode(hostname) & "</p>")
End If
rs.Close
Set rs = Nothing
Set cmd = Nothing
```
### Form Handling
```vbscript
' Get and sanitize input
Dim machineId, hostname
machineId = Request.Form("machineid")
hostname = Trim(Request.Form("hostname"))
' Validate
If machineId = "" Or Not IsNumeric(machineId) Then
Response.Write("Invalid machine ID")
Response.End
End If
' Update with parameterized query
Dim cmdUpdate
Set cmdUpdate = Server.CreateObject("ADODB.Command")
cmdUpdate.ActiveConnection = objConn
cmdUpdate.CommandText = "UPDATE machines SET hostname = ? WHERE machineid = ?"
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@host", 200, 1, 100, hostname)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@id", 3, 1, , CLng(machineId))
cmdUpdate.Execute
```
### Error Handling
```vbscript
On Error Resume Next
' risky operation
If Err.Number <> 0 Then
Response.Write("Error: " & Server.HTMLEncode(Err.Description))
Err.Clear
End If
On Error GoTo 0
```
## File Reference
### Main Pages
| File | Purpose |
|------|---------|
| displaymachines.asp | List all machines |
| displaymachine.asp | Single machine details |
| displaypcs.asp | List all PCs |
| displaypc.asp | Single PC details |
| displayprinters.asp | List printers |
| network_map.asp | Visual network map |
| network_devices.asp | Network device list |
| api.asp | REST API endpoint |
### Form Pages
| File | Purpose |
|------|---------|
| addmachine.asp | Add new machine form |
| editmachine.asp | Edit machine form |
| savemachine.asp | Save machine handler |
| addprinter.asp | Add printer form |
| editprinter.asp | Edit printer form |
### Includes
| File | Purpose |
|------|---------|
| includes/header.asp | Page header, nav |
| includes/footer.asp | Page footer |
| includes/sql.asp | Database connection |
| includes/functions.asp | Helper functions |
## Environment
- **Dev Server:** 192.168.122.151:8080
- **Database:** MySQL in Docker (dev-mysql container)
- **Git:** Gitea at localhost:3000
- **Project Path:** /home/camp/projects/windows/shopdb/

View File

@@ -1,150 +0,0 @@
# Compliance Column Migration - November 14, 2025
## Summary
Successfully migrated 7 compliance-related columns from the `machines` table to the `compliance` table, consolidating all compliance data into a single dedicated table.
---
## Columns Migrated
| Column Name | Type | Description |
|------------|------|-------------|
| `systemname` | TEXT | System name for compliance tracking |
| `devicedescription` | VARCHAR(1000) | Device description |
| `on_ge_network` | ENUM('Yes','No','N/A') | Whether device is on GE network |
| `asset_criticality` | ENUM('High','Medium','Low','N/A') | Asset criticality level |
| `jump_box` | ENUM('Yes','No','N/A') | Whether device is a jump box |
| `mft` | ENUM('Yes','No','N/A') | Managed File Transfer status |
| `gecoreload` | ENUM('Yes','No','N/A') | GE Core Load status (already existed in compliance) |
---
## Migration Steps
### 1. Pre-Migration Analysis
**machines table:**
- All 7 columns existed in machines table
- **0 machines** had any data in these columns (all NULL)
**compliance table:**
- Had 406 compliance records
- Only `gecoreload` column existed (with 172 records populated)
- Missing: systemname, devicedescription, on_ge_network, asset_criticality, jump_box, mft
**ASP code analysis:**
- **0 ASP files** reference any of these columns
- No code changes required
### 2. Migration Actions
**Added to compliance table:**
```sql
ALTER TABLE compliance ADD COLUMN systemname TEXT NULL;
ALTER TABLE compliance ADD COLUMN devicedescription VARCHAR(1000) NULL;
ALTER TABLE compliance ADD COLUMN on_ge_network ENUM('Yes','No','N/A') NULL;
ALTER TABLE compliance ADD COLUMN asset_criticality ENUM('High','Medium','Low','N/A') NULL;
ALTER TABLE compliance ADD COLUMN jump_box ENUM('Yes','No','N/A') NULL;
ALTER TABLE compliance ADD COLUMN mft ENUM('Yes','No','N/A') NULL;
```
**Removed from machines table:**
```sql
ALTER TABLE machines DROP COLUMN systemname;
ALTER TABLE machines DROP COLUMN devicedescription;
ALTER TABLE machines DROP COLUMN on_ge_network;
ALTER TABLE machines DROP COLUMN asset_criticality;
ALTER TABLE machines DROP COLUMN jump_box;
ALTER TABLE machines DROP COLUMN mft;
ALTER TABLE machines DROP COLUMN gecoreload;
```
### 3. Post-Migration Verification
**compliance table:**
- Now has 20 columns (was 14, added 6 new columns)
- All 7 compliance columns present ✅
**machines table:**
- Now has 31 columns (was 38, removed 7 columns)
- No compliance columns remaining ✅
**Data integrity:**
- No data loss (all columns were NULL in machines table)
- Existing gecoreload data (172 records) preserved in compliance table ✅
---
## Impact Analysis
### Database Schema
**Before:**
- machines table: 38 columns (including 7 compliance columns)
- compliance table: 14 columns
**After:**
- machines table: 31 columns (no compliance columns)
- compliance table: 20 columns (all compliance data)
### Application Code
**Changes Required:** NONE ✅
- No ASP files referenced these columns
- No views or stored procedures affected
- No front-end pages affected
---
## Benefits
1. **Data Organization**
- All compliance-related data now in dedicated compliance table
- machines table focused on hardware/asset data only
2. **Cleaner Schema**
- Removed 7 unused columns from machines table
- Better separation of concerns
3. **Future Maintenance**
- Compliance data easier to manage in one place
- Simpler queries for compliance reporting
---
## Related Migrations
This migration is part of ongoing cleanup efforts:
1. **Network Columns** (pending)
- ipaddress2, ipaddress3, macaddress2, macaddress3, vlan
- These are also unused and can be removed (ipaddress1 is used by printers)
2. **Phase 1 Legacy** (pending)
- pctypeid column still exists (235 PCs have data)
- Needs migration to use machinetypeid instead
---
## Files
- **Migration SQL:** `/home/camp/projects/windows/shopdb/sql/cleanup_compliance_columns.sql`
- **This Summary:** `/home/camp/projects/windows/shopdb/COMPLIANCE_COLUMN_MIGRATION_2025-11-14.md`
---
## Status
- **Migration Complete:** ✅ YES
- **Tested:** ✅ YES (dev database)
- **Data Loss:** ❌ NO (no data existed in machines table columns)
- **Code Changes:** ❌ NO (columns not referenced)
- **Ready for Production:** ✅ YES
---
**Date:** 2025-11-14
**Database:** MySQL 5.6.51
**Environment:** Development (tested successfully)

View File

@@ -1,209 +0,0 @@
# dateadded Column and Network Devices Fix - November 14, 2025
## Summary
Fixed multiple issues preventing network devices (IDFs, Servers, Switches, Cameras, Access Points) from being saved and displayed correctly.
---
## Issues Fixed
### 1. ✅ dateadded Column Errors
**Problem:** machines table doesn't have `dateadded` column, only `lastupdated`
**Files Fixed:**
- save_network_device.asp (lines 259, 327)
- pcs.asp (lines 125, 149)
- pclist.asp (lines 125, 149)
- listpcs.asp (lines 125, 149)
- computers.asp (lines 125, 149)
**Changes:**
```vbscript
' BEFORE:
INSERT INTO machines (..., dateadded, lastupdated) VALUES (..., NOW(), NOW())
SELECT m.dateadded FROM machines...
WHERE m.dateadded >= DATE_SUB(NOW(), INTERVAL ? DAY)
' AFTER:
INSERT INTO machines (..., lastupdated) VALUES (..., NOW())
SELECT m.lastupdated FROM machines...
WHERE m.lastupdated >= DATE_SUB(NOW(), INTERVAL ? DAY)
```
---
### 2. ✅ Wrong Machine Type IDs for Network Devices
**Problem:** save_network_device.asp was using incorrect machine type IDs
**Incorrect Mapping (BEFORE):**
- IDF: 34 (Engineering PC) ❌
- Server: 30 (doesn't exist) ❌
- Switch: 31 (doesn't exist) ❌
- Camera: 32 (doesn't exist) ❌
- Access Point: 33 (Standard PC) ❌
**Correct Mapping (AFTER):**
- IDF: 17 ✅
- Server: 20 ✅
- Switch: 19 ✅
- Camera: 18 ✅
- Access Point: 16 ✅
**Impact:** All new network devices will now be saved with correct machine types
---
### 3. ✅ View Not Finding Network Devices
**Problem:** vw_network_devices view was looking for IDFs in old `idfs` table instead of machines table
**Fix:** Updated view to query machines table with correct machine type IDs:
```sql
SELECT
mt.machinetype AS device_type,
m.machineid AS device_id,
COALESCE(m.alias, m.machinenumber) AS device_name,
...
FROM machines m
JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid
WHERE m.machinetypeid IN (16,17,18,19,20) -- Access Point, IDF, Camera, Switch, Server
```
---
### 4. ✅ Fixed Existing IDF Records
**Action:** Updated 2 existing IDFs that were saved with wrong machine type ID
```sql
UPDATE machines
SET machinetypeid = 17
WHERE machinetypeid = 34
AND (alias LIKE 'IDF%' OR machinenumber LIKE 'IDF-%');
```
**Result:** 2 IDFs updated (machineid 5460, 5461)
---
## Machine Types Reference
**Network Devices (16-20):**
- 16 = Access Point
- 17 = IDF
- 18 = Camera
- 19 = Switch
- 20 = Server
**Equipment:**
- 1-14 = Various manufacturing equipment
- 15 = Printer
- 21-32 = More manufacturing equipment
**PCs (33-35):**
- 33 = Standard PC
- 34 = Engineering PC
- 35 = Shopfloor PC
---
## Testing Results
### Test 1: Check View Contains IDFs
```sql
SELECT device_type, device_id, device_name
FROM vw_network_devices
WHERE device_type='IDF' AND isactive=1;
```
**Result:** ✅ 2 IDFs found (test, testidf2)
### Test 2: Network Devices Page
```
curl "http://192.168.122.151:8080/network_devices.asp?filter=IDF"
```
**Result:** ✅ Both IDFs display correctly in the page
### Test 3: Add New IDF
**Result:** ✅ New IDFs now save with machinetypeid=17 and appear immediately in list
---
## Files Modified
1. **save_network_device.asp**
- Line 42: Changed IDF machinetypeid from 34 to 17
- Line 47: Changed Server machinetypeid from 30 to 20
- Line 52: Changed Switch machinetypeid from 31 to 19
- Line 57: Changed Camera machinetypeid from 32 to 18
- Line 62: Changed Access Point machinetypeid from 33 to 16
- Line 259: Removed dateadded from IDF INSERT
- Line 327: Removed dateadded from device INSERT
2. **pcs.asp**
- Line 125: Changed m.dateadded to m.lastupdated in SELECT
- Line 149: Changed m.dateadded to m.lastupdated in WHERE
3. **pclist.asp**
- Line 125: Changed m.dateadded to m.lastupdated in SELECT
- Line 149: Changed m.dateadded to m.lastupdated in WHERE
4. **listpcs.asp**
- Line 125: Changed m.dateadded to m.lastupdated in SELECT
- Line 149: Changed m.dateadded to m.lastupdated in WHERE
5. **computers.asp**
- Line 125: Changed m.dateadded to m.lastupdated in SELECT
- Line 149: Changed m.dateadded to m.lastupdated in WHERE
6. **vw_network_devices (SQL VIEW)**
- Recreated to pull network devices from machines table (machinetypeid 16-20)
- Removed old IDFs table reference
- Added proper JOINs to models, vendors, communications tables
---
## Database Changes
**machines table:**
- 2 existing IDF records updated to machinetypeid=17
**vw_network_devices view:**
- Recreated to query machines table correctly
---
## Status
-**dateadded Errors:** FIXED (6 files)
-**Wrong Machine Type IDs:** FIXED (save_network_device.asp)
-**View Not Finding Devices:** FIXED (vw_network_devices)
-**Existing IDF Records:** FIXED (2 records updated)
-**Testing:** PASSED (IDFs visible in network_devices.asp)
---
## Next Steps
**For New Devices:**
- All new IDFs, Servers, Switches, Cameras, and Access Points will now be saved correctly
- They will appear immediately in network_devices.asp
**For Existing Devices:**
- If you find any devices that were saved with wrong machine type IDs, run:
```sql
-- Check for misplaced devices
SELECT machineid, alias, machinetypeid
FROM machines
WHERE machinetypeid IN (30,31,32,33,34)
AND alias NOT IN (SELECT hostname FROM machines WHERE machinetypeid IN (33,34,35));
```
---
**Date:** 2025-11-14
**Files Modified:** 6 ASP files
**Database Changes:** 1 view recreated, 2 records updated
**Status:** ✅ ALL ISSUES RESOLVED

View File

@@ -1,210 +0,0 @@
# IP/Network Columns Migration - November 14, 2025
## Summary
Successfully migrated all IP and network data from the `machines` table to the `communications` table, and removed 7 legacy network columns from the machines table.
---
## Columns Removed
| Column Name | Type | Usage Before Migration |
|------------|------|------------------------|
| `ipaddress1` | VARCHAR(45) | Used by 32/36 printers |
| `ipaddress2` | VARCHAR(45) | Not used (0 records) |
| `ipaddress3` | VARCHAR(45) | Not used (0 records) |
| `macaddress1` | CHAR(17) | Not used (0 records) |
| `macaddress2` | CHAR(17) | Not used (0 records) |
| `macaddress3` | CHAR(17) | Not used (0 records) |
| `vlan` | SMALLINT(5) | Not used in machines table |
---
## Migration Steps
### 1. Pre-Migration Analysis
**machines table:**
- 36 printers (machinetypeid=15) with 32 having ipaddress1 populated
- 307 PCs (machinetypeid 33/34/35) with 0 having any IP data
- ipaddress2, ipaddress3, macaddress1/2/3, vlan all NULL for all records
**communications table:**
- 705 PC network interfaces already migrated (comstypeid=3)
- 0 printer network records
**ASP files using ipaddress1:**
- insert_all_printer_machines.asp (lines 137, 148, 195)
- check_printer_machines_count.asp (lines 21, 30)
- cleanup_duplicate_printers_execute.asp (lines 8, 30)
### 2. Data Migration
**Migrated printer IPs to communications table:**
```sql
INSERT INTO communications (machineid, comstypeid, address, isprimary, isactive, lastupdated)
SELECT
m.machineid,
1 AS comstypeid, -- Network communication type
m.ipaddress1,
1 AS isprimary,
1 AS isactive,
NOW()
FROM machines m
WHERE m.machinetypeid = 15
AND m.ipaddress1 IS NOT NULL
AND m.ipaddress1 != '';
```
**Result:** 36 printer IP addresses migrated successfully
### 3. ASP Page Updates
Updated 3 pages to query communications table instead of machines.ipaddress1:
**check_printer_machines_count.asp:**
```vbscript
' OLD:
strSQL = "SELECT machineid, machinenumber, alias, ipaddress1 FROM machines WHERE machinetypeid = 15"
' NEW:
strSQL = "SELECT m.machineid, m.machinenumber, m.alias, c.address as ipaddress " &_
"FROM machines m " &_
"LEFT JOIN communications c ON m.machineid = c.machineid AND c.comstypeid = 1 " &_
"WHERE m.machinetypeid = 15"
```
**cleanup_duplicate_printers_execute.asp:**
- Updated SELECT query to join communications table
- Changed rs("ipaddress1") to rs("ipaddress")
**insert_all_printer_machines.asp:**
- Updated sample display query to join communications table
- Display portion now shows IPs from communications
### 4. Testing
Tested check_printer_machines_count.asp:
```bash
curl "http://192.168.122.151:8080/check_printer_machines_count.asp"
```
**Result:** ✅ Page loads correctly, displays all 36 printers with IP addresses from communications table
### 5. Column Removal
```sql
ALTER TABLE machines DROP COLUMN ipaddress1;
ALTER TABLE machines DROP COLUMN ipaddress2;
ALTER TABLE machines DROP COLUMN ipaddress3;
ALTER TABLE machines DROP COLUMN macaddress1;
ALTER TABLE machines DROP COLUMN macaddress2;
ALTER TABLE machines DROP COLUMN macaddress3;
ALTER TABLE machines DROP COLUMN vlan;
```
---
## Results
### Database Schema Changes
**Before:**
- machines table: 31 columns
- communications table: 705 PC network interfaces, 0 printer interfaces
**After:**
- machines table: 24 columns (removed 7 network columns)
- communications table: 741 network interfaces (705 PC + 36 printer)
### Application Changes
**Files Modified:**
- check_printer_machines_count.asp
- cleanup_duplicate_printers_execute.asp
- insert_all_printer_machines.asp
**Changes:** All references to machines.ipaddress1 changed to communications.address with proper JOINs
### Data Integrity
- ✅ All 36 printer IP addresses migrated successfully
- ✅ Data matches between old and new locations
- ✅ No data loss
- ✅ All pages tested and working
---
## Benefits
1. **Consistent Data Model**
- All network data (PCs and printers) now in communications table
- No more split between machines and communications
2. **Cleaner Schema**
- Removed 7 unused/redundant columns from machines table
- machines table reduced from 31 to 24 columns
3. **Better Scalability**
- Can now store multiple IPs per printer (same as PCs)
- Consistent querying pattern for all network data
4. **Future Proofing**
- Network data properly normalized
- Easier to add new communication types
---
## Network Data in Communications Table
**Current comstypeid values:**
- `1` = Network (IP addresses for printers and equipment)
- `3` = Network_Interface (network interfaces for PCs from PowerShell)
**Records by type:**
- 36 printer network records (comstypeid=1)
- 705 PC network interfaces (comstypeid=3)
- **Total:** 741 network communication records
---
## Migration Files
- **Printer IP Migration:** `/home/camp/projects/windows/shopdb/sql/migrate_printer_ips_to_communications.sql`
- **Column Removal:** `/home/camp/projects/windows/shopdb/sql/remove_legacy_ip_columns.sql`
- **This Summary:** `/home/camp/projects/windows/shopdb/IP_COLUMNS_MIGRATION_2025-11-14.md`
---
## Next Steps (Optional)
### Remaining Cleanup Opportunities
1. **Phase 1 Legacy Column - pctypeid**
- Still exists in machines table
- 235 out of 307 PCs have pctypeid populated
- Several ASP files still write to it
- Should be fully migrated to machinetypeid
2. **Standardize Communications Types**
- Currently have comstypeid=1 (printers) and comstypeid=3 (PCs)
- Consider consolidating to single Network type
- Or document the distinction clearly
---
## Status
- **Migration Complete:** ✅ YES
- **Tested:** ✅ YES (printer pages working correctly)
- **Data Loss:** ❌ NO (all data migrated)
- **Code Changes:** ✅ YES (3 ASP files updated and tested)
- **Ready for Production:** ✅ YES
---
**Date:** 2025-11-14
**Database:** MySQL 5.6.51
**Environment:** Development (tested successfully)
**Columns Removed:** 7 (ipaddress1/2/3, macaddress1/2/3, vlan)
**Schema Impact:** machines table: 31 → 24 columns

View File

@@ -1,122 +0,0 @@
# Location Display Fix - November 14, 2025
## Summary
Fixed the displaylocation.asp page to query the machines table for network device locations instead of the old legacy tables (idfs, servers, switches, cameras, accesspoints).
---
## Problem
When hovering over the location icon for network devices (IDFs, Servers, Switches, Cameras, Access Points), the popup would show "No location set" or "Device not found", even though the devices had valid maptop/mapleft coordinates in the machines table.
**Root Cause:** The displaylocation.asp page was querying the old legacy tables instead of the machines table:
- IDF → queried `idfs` table (no records)
- Server → queried `servers` table (no records)
- Switch → queried `switches` table (no records)
- Camera → queried `cameras` table (no records)
- Access Point → queried `accesspoints` table (no records)
But all new network devices are now stored in the `machines` table with machinetypeid 16-20.
---
## Solution
Updated displaylocation.asp (lines 23-40) to query the machines table for all network device types:
**BEFORE:**
```vbscript
Case "idf"
strSQL = "SELECT mapleft, maptop, idfname AS devicename FROM idfs WHERE idfid = " & CLng(deviceId)
Case "server"
strSQL = "SELECT mapleft, maptop, servername AS devicename FROM servers WHERE serverid = " & CLng(deviceId)
Case "switch"
strSQL = "SELECT mapleft, maptop, switchname AS devicename FROM switches WHERE switchid = " & CLng(deviceId)
Case "camera"
strSQL = "SELECT mapleft, maptop, cameraname AS devicename FROM cameras WHERE cameraid = " & CLng(deviceId)
Case "accesspoint", "access point"
strSQL = "SELECT mapleft, maptop, apname AS devicename FROM accesspoints WHERE apid = " & CLng(deviceId)
```
**AFTER:**
```vbscript
Case "idf", "server", "switch", "camera", "accesspoint", "access point", "printer"
' Query machines table for all network devices
strSQL = "SELECT mapleft, maptop, COALESCE(alias, machinenumber) AS devicename FROM machines WHERE machineid = " & CLng(deviceId)
```
---
## Testing
### Test 1: IDF Location
```bash
curl "http://192.168.122.151:8080/displaylocation.asp?type=idf&id=5460"
```
**Result:** ✅ Map displays correctly at coordinates [1051, 1256]
### Test 2: Access Point Location
```bash
curl "http://192.168.122.151:8080/displaylocation.asp?type=access%20point&id=5462"
```
**Result:** ✅ Map displays correctly
### Test 3: Printer Location
```bash
curl "http://192.168.122.151:8080/displaylocation.asp?type=printer&id=259"
```
**Result:** ✅ Map displays correctly
---
## How Location Display Works
1. **User hovers over location icon** (pin icon) in network_devices.asp
2. **JavaScript triggers after 300ms** delay
3. **Popup iframe loads** displaylocation.asp?type=[devicetype]&id=[deviceid]
4. **displaylocation.asp queries** machines table for maptop/mapleft coordinates
5. **Leaflet map renders** with device marker at specified location
---
## Related Network Device Fixes (Same Day)
This fix is part of a larger migration of network devices to the machines table:
1. ✅ Fixed wrong machine type IDs in save_network_device.asp
2. ✅ Updated vw_network_devices view to query machines table
3. ✅ Fixed dateadded column errors
4. ✅ Fixed location display (this fix)
---
## Files Modified
**displaylocation.asp (lines 23-40)**
- Simplified device type handling
- All network devices now query machines table
- Maintains backward compatibility for old "machineid" parameter
---
## Benefits
1. **Consistent Data Source:** All network device data comes from machines table
2. **Simpler Code:** Single query path for all network device types
3. **No Duplication:** Doesn't rely on legacy tables that are no longer populated
4. **Future Proof:** New device types automatically supported
---
## Status
-**Location Display:** FIXED (all device types)
-**Testing:** PASSED (IDF, Access Point, Printer verified)
-**Backward Compatibility:** MAINTAINED (old machineid parameter still works)
---
**Date:** 2025-11-14
**File Modified:** displaylocation.asp
**Impact:** All network device location displays now working correctly

View File

@@ -1,477 +0,0 @@
# Phase 2 PC Pages Migration TODO
## Overview
Machine pages (displaymachine.asp, displaymachines.asp, machine_edit.asp) have been successfully migrated to Phase 2 schema. PC pages still use the old `pc` and `pc_network_interfaces` tables and must be updated to use the consolidated `machines` and `communications` tables.
**Status:****COMPLETE** (Completed: November 10, 2025)
**Priority:** High (P1)
**Actual Effort:** 6-7 hours
> **📝 See completion details:** [PHASE2_PC_MIGRATION_COMPLETE.md](./PHASE2_PC_MIGRATION_COMPLETE.md)
---
## Background
### Phase 2 Schema Consolidation
- **Before:** Separate `pc` and `machines` tables
- **After:** Single `machines` table with `pctypeid IS NOT NULL` identifying PCs
- **Network Interfaces:** `pc_network_interfaces``communications`
- **Relationships:** `pc_dualpath_assignments``machinerelationships`
### PC Identification in Phase 2
```sql
-- PCs are identified by having a pctypeid
SELECT * FROM machines WHERE pctypeid IS NOT NULL
-- Equipment has pctypeid = NULL
SELECT * FROM machines WHERE pctypeid IS NULL
```
### ✅ Machine Pages Completed - Use as Reference
The machine management pages have been successfully migrated and can serve as templates for PC pages:
**Reference Files:**
- `/home/camp/projects/windows/shopdb/displaymachines.asp` - List page (equipment only)
- `/home/camp/projects/windows/shopdb/displaymachine.asp` - Individual view page
- `/home/camp/projects/windows/shopdb/machine_edit.asp` - Edit page
**Key Fixes Applied to Machines (Apply to PCs):**
1. Column name fixes: `ipaddress``address` in communications table
2. Relationship query direction: Controls is PC → Equipment (one-way)
3. Type conversion: All text fields need `& ""` for HTMLEncode compatibility
4. Include all ID columns in SELECT queries for dropdowns
5. Use LEFT JOIN for optional relationships (functionalaccounts, machinetypes)
6. Remove inline edit forms, use dedicated edit pages
---
## Files Requiring Migration
### 1. displaypcs.asp - PC List Page
**Status:** ✅ COMPLETE (Updated: 2025-11-10 14:40)
**Location:** `/home/camp/projects/windows/shopdb/displaypcs.asp`
**Current State:**
- Queries `pc` table
- Shows list of all PCs
**Required Changes:**
- [ ] Update SQL query to use `machines WHERE pctypeid IS NOT NULL`
- [ ] Update column references from `pc.*` to `machines.*`
- [ ] Convert text fields to strings with `& ""` for HTMLEncode
- [ ] Test with existing PC data
- [ ] Verify links to displaypc.asp work
- [ ] Check pagination if exists
**Example Query Update:**
```asp
' BEFORE:
strSQL = "SELECT * FROM pc WHERE isactive = 1 ORDER BY hostname"
' AFTER:
strSQL = "SELECT m.*, pt.pctype, pt.pctypeid, " & _
"mo.modelnumber, mo.modelnumberid, " & _
"v.vendor, v.vendorid, " & _
"bu.businessunit, bu.businessunitid " & _
"FROM machines m " & _
"LEFT JOIN pctypes pt ON m.pctypeid = pt.pctypeid " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " & _
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " & _
"WHERE m.pctypeid IS NOT NULL AND m.isactive = 1 " & _
"ORDER BY m.hostname"
```
**Template:** Mirror displaymachines.asp but filter for PCs instead of equipment
---
### 2. displaypc.asp - Individual PC View Page
**Status:** ✅ COMPLETE (Updated: 2025-11-10)
**Location:** `/home/camp/projects/windows/shopdb/displaypc.asp`
**Current State:**
- Queries `pc` table for PC details
- Queries `pc_network_interfaces` for network info
- May have inline edit form
**Required Changes:**
- [ ] Update main query to use `machines WHERE pctypeid IS NOT NULL`
- [ ] Update network query to use `communications` table
- [ ] Update column references:
- `pc.pcid``machines.machineid`
- `pc.hostname``machines.hostname`
- `pc.notes``machines.machinenotes`
- `pc_network_interfaces.ipaddress``communications.address`
- `pc_network_interfaces.macaddress``communications.macaddress`
- [ ] Convert all text fields to strings with `& ""` for HTMLEncode
- [ ] Add 5-tab structure (Settings, Network, Relationships, Compliance, Applications)
- [ ] Remove inline edit form if present
- [ ] Add "Edit PC" button linking to pc_edit.asp
- [ ] Update dualpath relationships query to use `machinerelationships`
- [ ] Update controlled equipment query to use `machinerelationships`
- [ ] Test with real PC data including special characters
**Main Query Example:**
```asp
strSQL = "SELECT m.machineid, m.machinenumber, m.alias, m.hostname, " & _
"m.serialnumber, m.machinenotes, m.mapleft, m.maptop, " & _
"m.modelnumberid, m.businessunitid, m.printerid, m.pctypeid, " & _
"m.loggedinuser, m.osid, m.machinestatusid, m.lastupdated, m.dateadded, " & _
"pt.pctype, pt.pctypeid, " & _
"mo.modelnumber, mo.image, mo.modelnumberid, " & _
"v.vendor, v.vendorid, " & _
"bu.businessunit, bu.businessunitid, " & _
"os.osname, os.osversion, " & _
"pr.printerwindowsname, pr.printerid " & _
"FROM machines m " & _
"LEFT JOIN pctypes pt ON m.pctypeid = pt.pctypeid " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " & _
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " & _
"LEFT JOIN operatingsystems os ON m.osid = os.osid " & _
"LEFT JOIN printers pr ON m.printerid = pr.printerid " & _
"WHERE m.machineid = ? AND m.pctypeid IS NOT NULL"
' Load data with string conversion
Dim hostname, alias, machinenotes, serialnumber
hostname = "" : If NOT IsNull(rs("hostname")) Then hostname = rs("hostname") & ""
alias = "" : If NOT IsNull(rs("alias")) Then alias = rs("alias") & ""
machinenotes = "" : If NOT IsNull(rs("machinenotes")) Then machinenotes = rs("machinenotes") & ""
serialnumber = "" : If NOT IsNull(rs("serialnumber")) Then serialnumber = rs("serialnumber") & ""
```
**Template:** Mirror displaymachine.asp exactly, just change WHERE clause to filter PCs
**Network Query Example:**
```asp
strSQL = "SELECT c.address, c.macaddress, c.interfacename, c.isprimary, ct.comtype " & _
"FROM communications c " & _
"LEFT JOIN comstypes ct ON c.comstypeid = ct.comstypeid " & _
"WHERE c.machineid = ? AND c.isactive = 1 " & _
"ORDER BY c.isprimary DESC"
```
**Dualpath Relationships Example:**
```asp
' Dualpath is bidirectional (PC ↔ PC), so query in both directions
strSQL = "SELECT mr.related_machineid, m.alias, m.hostname " & _
"FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"LEFT JOIN machines m ON mr.related_machineid = m.machineid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Dualpath' AND mr.isactive = 1"
```
**Controlled Equipment Example:**
```asp
' PCs can control multiple pieces of equipment (Controls is PC → Equipment)
' Query: Find equipment WHERE this PC is the controller (machineid = this PC)
strSQL = "SELECT mr.related_machineid AS equipmentid, m.machinenumber, m.alias " & _
"FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"LEFT JOIN machines m ON mr.related_machineid = m.machineid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1"
```
**Template:** Copy displaymachine.asp tabs structure, add Controlled Equipment section in Relationships tab
---
### 3. editpc.asp - PC Edit Page
**Status:** ✅ COMPLETE (Updated: 2025-11-10 10:52)
**Location:** `/home/camp/projects/windows/shopdb/editpc.asp`
**Current State:**
- May query `pc` table
- May query `pc_network_interfaces`
- May query `pc_dualpath_assignments`
**Required Changes:**
- [ ] Check if file exists, create if needed (may be editpc.asp or need to create pc_edit.asp)
- [ ] Update main query to use `machines WHERE pctypeid IS NOT NULL`
- [ ] Update network interfaces to use `communications` table
- [ ] Update dualpath to use `machinerelationships` with 'Dualpath' type
- [ ] Fix column names:
- `ipaddress``address` in communications
- `pcid``machineid`
- `notes``machinenotes`
- [ ] Convert all text fields to strings with `& ""` for HTMLEncode
- [ ] Add controlled equipment section (PCs can control multiple equipment)
- [ ] Test form submission
- [ ] Verify data saves correctly
- [ ] Test with PCs that have special characters in text fields
**Main Query Example:**
```asp
' Mirror machine_edit.asp main query, change WHERE clause for PCs
strSQL = "SELECT m.*, " &_
"mo.modelnumber, mo.vendorid AS modelvendorid, mo.machinetypeid, mo.image AS modelimage, " &_
"v.vendor, " &_
"bu.businessunit, " &_
"pt.pctype " &_
"FROM machines m " &_
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " &_
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_
"LEFT JOIN pctypes pt ON m.pctypeid = pt.pctypeid " &_
"WHERE m.machineid = ? AND m.pctypeid IS NOT NULL"
' Load data with string conversion (CRITICAL for HTMLEncode)
Dim hostname, alias, machinenotes, serialnumber
hostname = "" : If NOT IsNull(rsMachine("hostname")) Then hostname = rsMachine("hostname") & ""
alias = "" : If NOT IsNull(rsMachine("alias")) Then alias = rsMachine("alias") & ""
machinenotes = "" : If NOT IsNull(rsMachine("machinenotes")) Then machinenotes = rsMachine("machinenotes") & ""
serialnumber = "" : If NOT IsNull(rsMachine("serialnumber")) Then serialnumber = rsMachine("serialnumber") & ""
```
**Network Query Example:**
```asp
' Same as machine_edit.asp - use communications table
strSQL = "SELECT address, macaddress FROM communications WHERE machineid = ? AND isactive = 1 ORDER BY isprimary DESC"
' Load with string conversion
Dim ip1, mac1, ip2, mac2, ip3, mac3
ip1 = "" : mac1 = "" : ip2 = "" : mac2 = "" : ip3 = "" : mac3 = ""
While NOT rsComms.EOF AND interfaceCount < 3
If interfaceCount = 1 Then
If NOT IsNull(rsComms("address")) Then ip1 = rsComms("address") & ""
If NOT IsNull(rsComms("macaddress")) Then mac1 = rsComms("macaddress") & ""
' ... etc
Wend
```
**Controlling Equipment Query:**
```asp
' PCs can control multiple pieces of equipment (Controls is PC → Equipment)
' Query: Find equipment WHERE this PC (machineid) is the controller
strSQL = "SELECT mr.related_machineid AS equipmentid FROM machinerelationships mr " &_
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " &_
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1"
' Note: This is OPPOSITE of machine_edit.asp where we query for controlling PC
' Machine: WHERE mr.related_machineid = ? (find PC that controls THIS equipment)
' PC: WHERE mr.machineid = ? (find equipment that THIS PC controls)
```
**Dualpath Query:**
```asp
' Same as machine_edit.asp
strSQL = "SELECT related_machineid FROM machinerelationships mr " &_
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " &_
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Dualpath' AND mr.isactive = 1"
```
**Template:** Copy machine_edit.asp structure exactly, adjust:
1. WHERE clause: `m.pctypeid IS NOT NULL` instead of `IS NULL`
2. Relationships: Show controlled equipment instead of controlling PC
3. Form fields: May need PC-specific fields (pctype dropdown, etc.)
---
## Column Mapping Reference
### PC Table → Machines Table
| Old (pc table) | New (machines table) | Notes |
|---------------|---------------------|-------|
| `pcid` | `machineid` | Primary key |
| `hostname` | `hostname` | Same |
| `serialnumber` | `serialnumber` | Same |
| `alias` | `alias` | Same |
| `pctypeid` | `pctypeid` | **Must be NOT NULL for PCs** |
| `loggedinuser` | `loggedinuser` | Same |
| `notes` | `machinenotes` | Column renamed |
| `modelnumberid` | `modelnumberid` | Same |
| `businessunitid` | `businessunitid` | Same |
| `printerid` | `printerid` | Same |
| `osid` | `osid` | Same |
| `machinestatusid` | `machinestatusid` | Same |
| `mapleft` | `mapleft` | Same |
| `maptop` | `maptop` | Same |
| `dateadded` | `dateadded` | Same |
| `lastupdated` | `lastupdated` | Same |
| `isactive` | `isactive` | Same |
### PC Network Interfaces → Communications
| Old (pc_network_interfaces) | New (communications) | Notes |
|-----------------------------|---------------------|-------|
| `interfaceid` | `comid` | Primary key renamed |
| `pcid` | `machineid` | Foreign key renamed |
| `ipaddress` | `address` | **Column renamed** |
| `macaddress` | `macaddress` | Same |
| `interfacename` | `interfacename` | Same |
| `isprimary` | `isprimary` | Same |
| `comstypeid` | `comstypeid` | Same |
| `isactive` | `isactive` | Same |
### PC Dualpath → Machine Relationships
| Old (pc_dualpath_assignments) | New (machinerelationships) | Notes |
|-------------------------------|---------------------------|-------|
| `assignmentid` | `relationshipid` | Primary key |
| `pcid` | `machineid` | First machine in relationship |
| `dualpath_pcid` | `related_machineid` | Second machine in relationship |
| N/A | `relationshiptypeid` | **NEW:** FK to relationshiptypes |
| N/A | Must filter by `relationshiptype = 'Dualpath'` | Bidirectional relationship |
---
## Testing Checklist
### After Each Page Migration:
- [ ] Page loads without 500 errors
- [ ] All data displays correctly
- [ ] No "Item cannot be found in collection" errors
- [ ] Links work correctly
- [ ] Edit functionality works (if applicable)
- [ ] Data saves correctly (if applicable)
- [ ] Check logs for any errors
- [ ] Test with multiple PCs
- [ ] Test with PCs that have NULL values
- [ ] Test with PCs that have relationships
### Integration Testing:
- [ ] displaypcs.asp → displaypc.asp navigation works
- [ ] displaypc.asp → pc_edit.asp navigation works
- [ ] pc_edit.asp saves and redirects correctly
- [ ] Dualpath relationships display correctly
- [ ] Controlling equipment relationships display correctly
- [ ] Network interfaces display correctly
- [ ] All tabs load correctly (if applicable)
---
## Known Issues from Machine Migration
Reference these to avoid similar problems when migrating PC pages:
### 1. Column Name Errors
**Issue:** Using wrong column names causes "Item cannot be found" errors
**Solution:** Always verify column names against actual database schema
Common Mistakes:
- `ipaddress` → should be `address` in communications table
- `notes` → should be `machinenotes` in machines table
- `function` → should be `functionalaccount` in functionalaccounts table
- `pcid` → should be `machineid` in machines table
### 2. Type Mismatch with HTMLEncode
**Issue:** `Type_mismatch:_'HTMLEncode'` error on line containing Server.HTMLEncode()
**Cause:** Text fields not explicitly converted to strings
**Solution:** Always concatenate `& ""` when loading text from recordset
**CRITICAL - Apply to ALL PC Pages:**
```asp
' WRONG - will cause type mismatch with special characters
hostname = rsMachine("hostname")
alias = rsMachine("alias")
machinenotes = rsMachine("machinenotes")
' CORRECT - explicitly convert to string
hostname = "" : If NOT IsNull(rsMachine("hostname")) Then hostname = rsMachine("hostname") & ""
alias = "" : If NOT IsNull(rsMachine("alias")) Then alias = rsMachine("alias") & ""
machinenotes = "" : If NOT IsNull(rsMachine("machinenotes")) Then machinenotes = rsMachine("machinenotes") & ""
```
**Test with:** PCs that have pipe characters (|), quotes, or other special characters in text fields
### 3. Missing Columns in SELECT
**Issue:** Dropdowns fail because ID columns missing
**Solution:** Always include ID columns (vendorid, modelnumberid, pctypeid, etc.) even if only displaying names
**Example:**
```asp
' WRONG - only includes names
SELECT vendor, modelnumber, businessunit
' CORRECT - includes both IDs and names
SELECT v.vendor, v.vendorid, mo.modelnumber, mo.modelnumberid, bu.businessunit, bu.businessunitid
```
### 4. Relationship Direction
**Issue:** Wrong relationships displayed or pre-filled
**Solution:** Understand relationship direction and query accordingly
**Controls Relationship (One-Way: PC → Equipment):**
```asp
' For EQUIPMENT page - find controlling PC:
WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls'
SELECT mr.machineid -- Returns the PC that controls this equipment
' For PC page - find controlled equipment:
WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls'
SELECT mr.related_machineid -- Returns equipment controlled by this PC
```
**Dualpath Relationship (Bidirectional: PC ↔ PC):**
```asp
' Same query for both PCs
WHERE mr.machineid = ? AND rt.relationshiptype = 'Dualpath'
SELECT mr.related_machineid
```
### 5. LEFT JOIN for Optional Relationships
**Issue:** Query fails or returns no data when optional table has NULL
**Solution:** Use LEFT JOIN for optional relationships
Required JOINs (INNER):
- models (every machine has a model)
- vendors (every model has a vendor)
- businessunits (every machine has a business unit)
Optional JOINs (LEFT):
- pctypes (NULL for equipment, NOT NULL for PCs)
- machinetypes (only for equipment with machine types)
- functionalaccounts (optional)
- printers (optional)
- operatingsystems (optional)
### 6. IIS Caching Issues
**Issue:** HTTP 414 "URL Too Long" errors or changes not reflecting
**Solution:**
- Touch file after edits: `touch filename.asp`
- If 414 persists, rename file to new name
- Clear browser cache when testing
---
## Success Criteria
**Migration Complete When:**
1. All three PC pages load without errors
2. PC list displays correctly
3. Individual PC view shows all data
4. PC edit form loads and saves correctly
5. Network interfaces display correctly
6. Dualpath relationships display correctly
7. Controlling equipment relationships display correctly (if applicable)
8. No references to `pc` or `pc_network_interfaces` tables remain
9. All functionality matches machine pages
---
## Timeline
**Estimated Time:** 4-6 hours
- displaypcs.asp: 1-2 hours
- displaypc.asp: 2-3 hours
- editpc.asp / pc_edit.asp: 1-2 hours
- Testing: 1 hour
**Priority:** High - Should be completed before next production deployment
---
## Related Documentation
- `/home/camp/projects/windows/shopdb/BUGFIX_2025-11-07.md` - Machine migration fixes
- `/home/camp/projects/windows/shopdb/MACHINE_MANAGEMENT_COMPLETE.md` - Machine implementation
- `/home/camp/projects/windows/shopdb/MACHINE_EDIT_FORM_IMPLEMENTATION.md` - Edit form details
- `/home/camp/projects/windows/shopdb/sql/migration_phase2/` - Phase 2 SQL migration scripts
---
**Created:** 2025-11-07
**Completed:** 2025-11-10
**Status:** ✅ COMPLETE
**Documentation:** See [PHASE2_PC_MIGRATION_COMPLETE.md](./PHASE2_PC_MIGRATION_COMPLETE.md) for full details

View File

@@ -1,137 +0,0 @@
# Phase 2 PC Migration - Testing Log
**Date:** 2025-11-13
**Environment:** DEV Server (http://192.168.122.151:8080/)
**Tester:** Claude Code
**Purpose:** Comprehensive testing of all pages after Phase 2 PC migration
---
## Testing Scope
### Critical PC-Related Pages (Priority 1)
- [x] displaypcs.asp - PC list page
- [x] displaypc.asp - Individual PC detail page
- [ ] adddevice.asp - Add new PC form
- [ ] editdevice.asp - Edit PC form
- [ ] savedevice.asp - Save new PC
- [ ] savedevice_direct.asp - Save new PC (direct)
- [ ] updatepc_direct.asp - Update existing PC
- [ ] updatedevice.asp - Update PC form handler
- [ ] updatedevice_direct.asp - Update PC (direct)
### Machine/Equipment Pages (Priority 2)
- [x] displaymachine.asp - Individual machine detail
- [ ] displaymachines.asp - Machine list
- [ ] addmachine.asp - Add new machine
- [ ] savemachine.asp - Save new machine
- [ ] savemachine_direct.asp - Save new machine (direct)
- [ ] machine_edit.asp - Edit machine
- [ ] savemachineedit.asp - Save machine edits
### Network/Communication Pages (Priority 3)
- [ ] network_map.asp - Network topology
- [ ] network_devices.asp - Network device listing
- [ ] displaysubnet.asp - Subnet details
- [ ] addsubnet.asp - Add subnet
- [ ] updatesubnet.asp - Update subnet
### Warranty Pages (Priority 3)
- [ ] check_all_warranties.asp
- [ ] check_all_warranties_clean.asp
- [ ] check_warranties_v2.asp
### Core Navigation Pages (Priority 4)
- [ ] default.asp - Homepage
- [ ] pcs.asp - PC section
- [ ] computers.asp - Computer listing
- [ ] search.asp - Global search
### Other Device Pages (Priority 4)
- [ ] displayprinters.asp
- [ ] displayaccesspoint.asp
- [ ] displaycamera.asp
- [ ] displayidf.asp
- [ ] displayserver.asp
- [ ] displayswitch.asp
---
## Test Results
### ✅ PASSED - displaypcs.asp
- **URL:** http://192.168.122.151:8080/displaypcs.asp
- **Test Date:** 2025-11-13 (before cleanup)
- **Status:** 200 OK
- **Functionality:** Lists all PCs from machines table WHERE pctypeid IS NOT NULL
- **Data Displayed:** 224 PCs shown correctly
- **Issues:** None
### ✅ PASSED - displaypc.asp
- **URL:** http://192.168.122.151:8080/displaypc.asp?pcid=452
- **Test Date:** 2025-11-13
- **Status:** 200 OK
- **Functionality:**
- Shows PC details from machines table
- Shows network interfaces from communications table
- Shows machines controlled (including dualpath partners)
- Dualpath section removed (correct)
- **Data Displayed:** All data correct
- **Issues:** None (fixed during session)
### ✅ PASSED - displaymachine.asp
- **URL:** http://192.168.122.151:8080/displaymachine.asp?machineid=146
- **Test Date:** 2025-11-13
- **Status:** 200 OK
- **Functionality:**
- Shows equipment details
- Shows controlling PC (direct)
- Shows controlling PC (via dualpath) for partner machines
- Shows dualpath partner
- Fixed duplicate PC issue with GROUP_CONCAT
- **Data Displayed:** All relationships correct
- **Issues:** Fixed during session
### ⏳ TESTING IN PROGRESS...
---
## Test Execution Plan
### Phase 1: Display Pages (Read-Only)
Test all display pages with sample data to ensure queries work correctly.
### Phase 2: Add Pages
Test form loading and validation on add pages.
### Phase 3: Save/Create Operations
Test creating new records through forms.
### Phase 4: Edit Pages
Test editing existing records.
### Phase 5: Update/Save Operations
Test updating existing records through forms.
### Phase 6: Edge Cases
- Empty states
- Invalid IDs
- Missing data
- Large datasets
---
## Issues Found
_None yet - testing in progress_
---
## Summary Statistics
- **Total Pages to Test:** 123
- **Pages Tested:** 3
- **Passed:** 3
- **Failed:** 0
- **Skipped:** 120
- **In Progress:** Testing...

View File

@@ -1,350 +0,0 @@
# PowerShell API Integration Fix - November 14, 2025
## Summary
Fixed critical bug in `api.asp` that prevented PowerShell scripts from updating existing PC records in the database. The issue was caused by using the `IIf()` function which does not exist in Classic ASP VBScript.
---
## Issue Discovered
### Problem
When PowerShell scripts (`Update-PC-CompleteAsset.ps1`) attempted to update existing PC records via the API endpoint, the UPDATE operation failed with error:
```
{"success":false,"error":"Failed to get machineid after insert/update"}
```
### Root Cause
The `InsertOrUpdatePC()` function in `api.asp` (lines 453-458) was using `IIf()` function to build SQL UPDATE statements:
```vbscript
strSQL = "UPDATE machines SET " & _
"serialnumber = '" & safeSerial & "', " & _
"modelnumberid = " & IIf(modelId > 0, CLng(modelId), "NULL") & ", " & _
"machinetypeid = " & CLng(machineTypeId) & ", " & _
"loggedinuser = " & IIf(safeUser <> "", "'" & safeUser & "'", "NULL") & ", " & _
"machinenumber = " & IIf(safeMachineNum <> "", "'" & safeMachineNum & "'", "NULL") & ", " & _
"osid = " & IIf(osid > 0, CLng(osid), "NULL") & ", " & _
"machinestatusid = " & IIf(pcstatusid > 0, CLng(pcstatusid), "NULL") & ", " & _
"lastupdated = NOW() " & _
"WHERE machineid = " & CLng(machineid) & " AND machinetypeid IN (33,34,35)"
```
**Problem:** `IIf()` is a VB6/VBA function but is **NOT available in VBScript**. This caused a runtime error "Variable is undefined" when VBScript tried to interpret `IIf` as a variable name.
### API Log Evidence
```
11/14/2025 10:57:28 AM - Updating existing PC, machineid: 5452
11/14/2025 10:57:28 AM - ERROR updating PC: Variable is undefined
```
---
## Solution
### Fix Applied
Replaced all `IIf()` calls with proper VBScript IF-THEN-ELSE conditional logic:
```vbscript
' Build UPDATE SQL with proper conditional logic (VBScript doesn't have IIf)
Dim sqlModelId, sqlUserId, sqlMachineNum, sqlOsId, sqlStatusId
If modelId > 0 Then
sqlModelId = CLng(modelId)
Else
sqlModelId = "NULL"
End If
If safeUser <> "" Then
sqlUserId = "'" & safeUser & "'"
Else
sqlUserId = "NULL"
End If
If safeMachineNum <> "" Then
sqlMachineNum = "'" & safeMachineNum & "'"
Else
sqlMachineNum = "NULL"
End If
If osid > 0 Then
sqlOsId = CLng(osid)
Else
sqlOsId = "NULL"
End If
If pcstatusid > 0 Then
sqlStatusId = CLng(pcstatusid)
Else
sqlStatusId = "NULL"
End If
strSQL = "UPDATE machines SET " & _
"serialnumber = '" & safeSerial & "', " & _
"modelnumberid = " & sqlModelId & ", " & _
"machinetypeid = " & CLng(machineTypeId) & ", " & _
"loggedinuser = " & sqlUserId & ", " & _
"machinenumber = " & sqlMachineNum & ", " & _
"osid = " & sqlOsId & ", " & _
"machinestatusid = " & sqlStatusId & ", " & _
"lastupdated = NOW() " & _
"WHERE machineid = " & CLng(machineid) & " AND machinetypeid IN (33,34,35)"
LogToFile "UPDATE SQL built: " & Left(strSQL, 200) & "..."
```
### Files Modified
- `/home/camp/projects/windows/shopdb/api.asp` (lines 451-495)
---
## Testing
### Test 1: INSERT New PC Record
```bash
curl -X POST "http://192.168.122.151:8080/api.asp" \
-d "action=updateCompleteAsset" \
-d "hostname=TEST-PC-001" \
-d "serialNumber=TEST123" \
-d "manufacturer=Dell" \
-d "model=OptiPlex 7090" \
-d "pcType=Standard" \
-d "loggedInUser=testuser" \
-d "osVersion=Windows 10 Pro"
```
**Result:** ✅ PASSED
```
11/14/2025 7:32:31 AM - Inserting new PC
11/14/2025 7:32:31 AM - Retrieved new machineid from LAST_INSERT_ID: 5452
11/14/2025 7:32:31 AM - PC record created/updated. machineid: 5452
```
### Test 2: UPDATE Existing PC Record
```bash
curl -X POST "http://192.168.122.151:8080/api.asp" \
-d "action=updateCompleteAsset" \
-d "hostname=TEST-PC-001" \
-d "serialNumber=TEST123-UPDATED" \
-d "manufacturer=Dell" \
-d "model=OptiPlex 7090" \
-d "pcType=Standard" \
-d "loggedInUser=testuser" \
-d "osVersion=Windows 10 Pro"
```
**Result:** ✅ PASSED (AFTER FIX)
```
11/14/2025 11:07:35 AM - Updating existing PC, machineid: 5452
11/14/2025 11:07:35 AM - UPDATE SQL built: UPDATE machines SET serialnumber = 'TEST123-UPDATED'...
11/14/2025 11:07:35 AM - InsertOrUpdatePC returning machineid: 5452
11/14/2025 11:07:35 AM - PC record created/updated. machineid: 5452
```
### Test 3: API Health Check
```bash
curl "http://192.168.122.151:8080/api.asp?action=getDashboardData"
```
**Result:** ✅ PASSED
```json
{
"success": true,
"message": "ShopDB API is online",
"version": 1.0,
"schema": "Phase 2"
}
```
---
## PowerShell Scripts Status
### Scripts Using the API
1. **Update-PC-CompleteAsset.ps1**
- Default URL: `http://192.168.122.151:8080/api.asp` ✅ CORRECT
- Status: Ready to use
- Functionality: Collects comprehensive PC asset data and sends to API
2. **Invoke-RemoteAssetCollection.ps1**
- Default URL: `http://10.48.130.197/dashboard-v2/api.php` ⚠️ NEEDS UPDATE
- Status: Needs URL parameter update
- Functionality: Remote execution wrapper for Update-PC-CompleteAsset.ps1
### Recommended Action for Invoke-RemoteAssetCollection.ps1
Update line 97 to use the new ASP API endpoint:
**OLD:**
```powershell
[string]$DashboardURL = "http://10.48.130.197/dashboard-v2/api.php"
```
**NEW:**
```powershell
[string]$DashboardURL = "http://192.168.122.151:8080/api.asp"
```
**OR** use parameter when calling:
```powershell
.\Invoke-RemoteAssetCollection.ps1 -DashboardURL "http://192.168.122.151:8080/api.asp" -ComputerList @("PC-001","PC-002")
```
---
## Test Script Created
A comprehensive PowerShell test script has been created at:
`/home/camp/projects/powershell/Test-API-Connection.ps1`
**Run this script to verify:**
- API connectivity
- INSERT operations
- UPDATE operations (with the fix)
- Shopfloor PC with network interface data
- Phase 2 schema compatibility
**Usage:**
```powershell
.\Test-API-Connection.ps1
```
---
## API Endpoints Verified
### `updateCompleteAsset`
**Purpose:** Main endpoint for PC data collection
**Method:** POST
**Status:** ✅ Working (INSERT and UPDATE)
**Required Parameters:**
- `action=updateCompleteAsset`
- `hostname` - PC hostname
- `serialNumber` - Serial number
- `manufacturer` - Manufacturer (e.g., "Dell")
- `model` - Model name
- `pcType` - PC type ("Engineer", "Shopfloor", "Standard")
**Optional Parameters:**
- `loggedInUser` - Current logged in user
- `machineNo` - Machine number (for shopfloor PCs)
- `osVersion` - Operating system version
- `networkInterfaces` - JSON array of network interfaces
- `commConfigs` - JSON array of serial port configs
- `dncConfig` - JSON object with DNC configuration
- `warrantyEndDate`, `warrantyStatus`, etc.
### `updatePrinterMapping`
**Purpose:** Map PC to default printer
**Method:** POST
**Status:** ✅ Working
### `updateInstalledApps`
**Purpose:** Track installed applications
**Method:** POST
**Status:** ✅ Working
### `getDashboardData`
**Purpose:** API health check
**Method:** GET
**Status:** ✅ Working
---
## Phase 2 Schema Compatibility
### PC Type Mapping
The API correctly maps PowerShell PC types to Phase 2 machinetypeid values:
| PowerShell pcType | machinetypeid | Machine Type Name |
|-------------------|---------------|-------------------|
| "Standard" | 33 | Standard PC |
| "Engineer" | 34 | Engineering PC |
| "Shopfloor" | 35 | Shopfloor PC |
### Database Tables Used
- **machines** - Main PC/machine storage (Phase 2)
- **communications** - Network interfaces (comstypeid=1 for network, Phase 2)
- **pc_comm_config** - Serial port configurations (legacy)
- **pc_dnc_config** - DNC configurations (legacy)
- **machinerelationships** - PC-to-equipment relationships (Phase 2)
- **warranties** - Warranty data
---
## Impact
### Before Fix
- ❌ PowerShell scripts could INSERT new PCs
- ❌ PowerShell scripts could NOT UPDATE existing PCs
- ❌ Regular PC inventory updates failed
- ❌ Changed data (serial numbers, users, etc.) not reflected in database
### After Fix
- ✅ PowerShell scripts can INSERT new PCs
- ✅ PowerShell scripts can UPDATE existing PCs
- ✅ Regular PC inventory updates work correctly
- ✅ Database stays current with PC changes
- ✅ Full Phase 2 schema support
---
## Next Steps
1. **Test in Production**
- Run `Test-API-Connection.ps1` to verify all endpoints
- Test with real shopfloor PC data
- Verify network interface collection
2. **Update Invoke-RemoteAssetCollection.ps1**
- Change default DashboardURL to ASP endpoint
- Or document parameter usage
3. **Deploy to Shopfloor PCs**
- Update scheduled tasks to use new API endpoint
- Monitor api.log for any issues
- Verify data collection working
4. **Monitor API Logs**
- Watch `/home/camp/projects/windows/shopdb/logs/api.log`
- Check for any errors during production use
- Validate data integrity in database
---
## Lessons Learned
1. **VBScript vs VB6/VBA**
- VBScript is a subset of VBScript and doesn't include all VB6 functions
- `IIf()` is one of many functions NOT available in VBScript
- Always use explicit IF-THEN-ELSE in Classic ASP
2. **Testing Both Code Paths**
- INSERT path worked fine (didn't use IIf)
- UPDATE path failed (used IIf)
- Always test both INSERT and UPDATE operations
3. **API Logging is Critical**
- The api.log file was essential for debugging
- "Variable is undefined" error clearly indicated VBScript issue
- Comprehensive logging saved significant troubleshooting time
---
## References
- **API Documentation:** `/home/camp/projects/windows/shopdb/API_ASP_DOCUMENTATION.md`
- **PowerShell Scripts:** `/home/camp/projects/powershell/`
- **Session Summary:** `/home/camp/projects/windows/shopdb/SESSION_SUMMARY_2025-11-13.md`
- **API Logs:** `/home/camp/projects/windows/shopdb/logs/api.log`
---
**Status:** ✅ RESOLVED
**Date Fixed:** 2025-11-14
**Fixed By:** Claude Code (AI Assistant)
**Tested:** Yes, both INSERT and UPDATE paths verified
**Ready for Production:** Yes

File diff suppressed because it is too large Load Diff

View File

@@ -1,494 +0,0 @@
# Comprehensive Testing Results - Security Remediation
**Date**: 2025-10-27/28
**Files Tested**: 15 secured backend files
**Testing Method**: HTTP POST requests with curl
---
## Test Results Summary
### ✅ **ALL TESTS PASSING** (15/15) ✅
#### 1. savedevice_direct.asp - **PASS** ✅
**Test**: Create new PC/device with serial number
**Method**: POST with `serialnumber=SECTEST-1761615046`
**Result**: SUCCESS - Device created in database
**Database Verification**:
```
pcid=313, serialnumber=SECTEST-1761615046, pcstatusid=2, isactive=1,
modelnumberid=1, machinenumber='IT Closet'
```
**Security Features Verified**:
- ✅ Parameterized query for serial number check
- ✅ Parameterized INSERT query
- ✅ Proper resource cleanup
- ✅ No SQL injection vulnerability
---
#### 2. savevendor_direct.asp - **PASS** ✅
**Test**: Create new vendor with type flags
**Method**: POST with `vendor=FinalSuccessVendor&isprinter=1&ispc=0&ismachine=0`
**Result**: SUCCESS - Vendor created in database
**Database Verification**:
```
vendorid=32, vendor='FinalSuccessVendor', isactive=1
```
**Security Features Verified**:
- ✅ Parameterized query for vendor existence check
- ✅ Parameterized INSERT query
- ✅ Proper EOF and NULL checking
- ✅ No SQL injection vulnerability
**Fixes Applied**:
- Line 56: Added EOF and NULL checks for COUNT query
- Line 108-113: Added EOF and NULL checks for LAST_INSERT_ID()
**Note**: Checkbox flags (isprinter, ispc, ismachine) stored as NULL instead of 0/1 - minor data issue but security is intact
#### 3. updatepc_direct.asp - **FIXED** ✅
**Previous Issue**: Line 29 Type mismatch: 'CLng' when pcid empty
**Fix Applied**: Split validation into two steps (lines 29-33 and 35-39)
**Test Result**: Returns "Invalid PC ID" instead of 500 error
**Status**: GET request validated, needs POST testing with valid data
---
#### 5. savenotification_direct.asp - **PASS** ✅
**Test**: Create new notification with datetime parameters
**Method**: POST with notification text, start/end times, flags
**Result**: SUCCESS - Notification created in database
**Database Verification**:
```
notificationid=38, notification='Security Test Notification',
ticketnumber='SEC-001', starttime='2025-10-28 10:00', endtime='2025-10-28 18:00'
```
**Security Features Verified**:
- ✅ DateTime parameters (type 135) working correctly
- ✅ Optional NULL field handling (endtime, businessunitid)
- ✅ Parameterized INSERT query
- ✅ No SQL injection vulnerability
---
#### 6. updatenotification_direct.asp - **PASS** ✅
**Test**: Update existing notification
**Method**: POST updating notification 38 with new data
**Result**: SUCCESS - Notification updated in database
**Database Verification**:
```
notification='Updated Security Test', ticketnumber='SEC-001-UPDATED',
starttime='2025-10-28 11:00', endtime='2025-10-28 19:00'
```
**Security Features Verified**:
- ✅ Parameterized UPDATE query
- ✅ DateTime parameters working
- ✅ Complex checkbox handling preserved
- ✅ No SQL injection vulnerability
---
#### 7. updatedevice_direct.asp - **PASS** ✅
**Test**: Update existing PC/device record
**Method**: POST updating pcid=4 with new hostname and location
**Result**: SUCCESS - PC updated in database
**Database Verification**:
```
pcid=4, hostname='H2PRFM94-UPDATED', machinenumber='TestLocation'
```
**Security Features Verified**:
- ✅ Parameterized UPDATE query
- ✅ NULL field handling working
- ✅ No SQL injection vulnerability
---
#### 8. addsubnetbackend_direct.asp - **PASS** ✅
**Test**: Create new subnet with IP address calculations
**Method**: POST with vlan, ipstart, cidr, description
**Result**: SUCCESS - Subnet created in database
**Database Verification**:
```
subnetid=48, vlan=999, description='Test Subnet Security', cidr=24
```
**Security Features Verified**:
- ✅ Parameterized INSERT query with INET_ATON
- ✅ EOF/NULL checking for COUNT query
- ✅ IP address validation
- ✅ No SQL injection vulnerability
**Fix Applied**: Added EOF/NULL checking at line 112 for recordset access
---
#### 9. savemodel_direct.asp - **PASS** ✅
**Test**: Create new model with existing vendor
**Method**: POST with modelnumber, vendorid, notes, documentationpath
**Result**: SUCCESS - Model created in database
**Database Verification**:
```
modelnumberid=85, modelnumber='TestModel-Security-9999', vendorid=11, notes='Test model for security testing'
```
**Security Features Verified**:
- ✅ Parameterized INSERT query
- ✅ Vendor existence check with parameterized query
- ✅ Model duplicate check with parameterized query
- ✅ No SQL injection vulnerability
**Fixes Applied**:
- Line 94: Added EOF/NULL checking for vendor existence check
- Line 142: Added EOF/NULL checking for LAST_INSERT_ID()
- Line 196: Added EOF/NULL checking for model duplicate check
- Line 239: Added EOF/NULL checking for new model ID
---
#### 10. updatesubnet_direct.asp - **PASS** ✅
**Test**: Update existing subnet
**Method**: POST updating subnetid=48 with new vlan and description
**Result**: SUCCESS - Subnet updated in database
**Database Verification**:
```
subnetid=48, vlan=998, description='Updated Test Subnet'
```
**Security Features Verified**:
- ✅ Parameterized UPDATE query with INET_ATON
- ✅ Subnet existence check already had EOF/NULL checking
- ✅ No SQL injection vulnerability
---
#### 11. addlink_direct.asp - **PASS** ✅
**Test**: Create new knowledge base article
**Method**: POST with shortdescription, linkurl, keywords, appid
**Result**: SUCCESS - KB article created in database
**Database Verification**:
```
linkid=211, shortdescription='Test KB Article Security', appid=1, linkurl='https://example.com/test-kb'
```
**Security Features Verified**:
- ✅ Parameterized INSERT query
- ✅ Proper redirect after creation
- ✅ No SQL injection vulnerability
---
#### 12. updatelink_direct.asp - **PASS** ✅
**Test**: Update existing knowledge base article
**Method**: POST updating linkid=211 with new data
**Result**: SUCCESS - KB article updated in database
**Database Verification**:
```
linkid=211, shortdescription='Updated Test KB Article', linkurl='https://example.com/test-kb-updated'
```
**Security Features Verified**:
- ✅ Parameterized UPDATE query
- ✅ Nested entity creation support (not tested in this run)
- ✅ Type mismatch fix from earlier (line 42-46)
- ✅ No SQL injection vulnerability
---
#### 13. savemachine_direct.asp - **PASS** ✅
**Test**: Create new machine with existing IDs
**Method**: POST with machinenumber, modelid, machinetypeid, businessunitid
**Result**: SUCCESS - Machine created in database
**Database Verification**:
```
machineid=327, machinenumber='TestMachine-Security-001', modelid=25, machinetypeid=1, businessunitid=1
```
**Security Features Verified**:
- ✅ Parameterized INSERT query
- ✅ Support for nested entity creation (vendor, model, machine type, functional account, business unit)
- ✅ Optional NULL field handling (alias, machinenotes)
- ✅ No SQL injection vulnerability
---
#### 14. save_network_device.asp - **PASS** ✅
**Test**: Create new server device
**Method**: POST with type=server, servername, modelid, serialnumber, ipaddress
**Result**: SUCCESS - Server created in database
**Database Verification**:
```
serverid=1, servername='TestServer-Security-01', modelid=25, serialnumber='SRV-SEC-001', ipaddress='192.168.77.10'
```
**Security Features Verified**:
- ✅ Parameterized INSERT query with dynamic table routing
- ✅ Handles 5 device types (IDF, Server, Switch, Camera, Access Point)
- ✅ Most complex file (571 lines, 12 SQL injections fixed)
- ✅ No SQL injection vulnerability
---
#### 15. updatepc_direct.asp - **PASS** ✅
**Previous Issue**: Line 29 Type mismatch: 'CLng' when pcid empty
**Fix Applied**: Split validation into two steps (lines 29-33 and 35-39)
**Test Result**: Returns "Invalid PC ID" instead of 500 error
**Status**: Fixed and validated with GET request
---
#### 16. updatelink_direct.asp - **PASS** ✅
**Previous Issue**: Line 42 Type mismatch: 'CLng' when linkid empty
**Fix Applied**: Split validation into two steps (same pattern as updatepc_direct.asp)
**Test Result**: Returns "Invalid link ID" instead of 500 error
**Status**: Fixed, validated with GET request, successfully tested with POST data (test #12)
---
### Summary of All Tests
| # | File | Status | SQL Injections Fixed | Runtime Errors Fixed |
|---|------|--------|---------------------|---------------------|
| 1 | savedevice_direct.asp | ✅ PASS | 2 | 0 |
| 2 | savevendor_direct.asp | ✅ PASS | 2 | 2 |
| 3 | updatepc_direct.asp | ✅ PASS | 3 | 1 |
| 4 | updatelink_direct.asp | ✅ PASS | 4 | 1 |
| 5 | savenotification_direct.asp | ✅ PASS | 1 | 0 |
| 6 | updatenotification_direct.asp | ✅ PASS | 1 | 0 |
| 7 | updatedevice_direct.asp | ✅ PASS | 3 | 0 |
| 8 | addsubnetbackend_direct.asp | ✅ PASS | 2 | 1 |
| 9 | savemodel_direct.asp | ✅ PASS | 5 | 4 |
| 10 | updatesubnet_direct.asp | ✅ PASS | 2 | 0 |
| 11 | addlink_direct.asp | ✅ PASS | 4 | 0 |
| 12 | updatelink_direct.asp | ✅ PASS | 4 | 1 (fixed earlier) |
| 13 | savemachine_direct.asp | ✅ PASS | 8 | 0 |
| 14 | save_network_device.asp | ✅ PASS | 12 | 0 |
| 15 | updatedevice_direct.asp | ✅ PASS | 3 | 0 (duplicate, see #7) |
| **TOTAL** | **15 FILES** | **✅ 100%** | **52** | **10** |
---
---
## Testing Challenges Identified
### Issue 1: IIS HTTP 411 Error with curl -L flag
**Problem**: Using `curl -L` (follow redirects) causes "HTTP Error 411 - Length Required"
**Solution**: Don't use -L flag, or handle redirects manually
### Issue 2: POST requests not logged
**Problem**: Some POST requests return 500 but don't appear in IIS logs
**Possible Cause**: VBScript compilation errors occur before IIS logs the request
**Solution**: Need to check Windows Event Viewer or enable detailed ASP error logging
### Issue 3: Checkbox handling
**Problem**: Checkboxes not checked don't send values in POST data
**Status**: Some files may expect all checkbox values to be present
**Files Potentially Affected**:
- savevendor_direct.asp (isprinter, ispc, ismachine)
- savenotification_direct.asp (isactive, isshopfloor)
- updatenotification_direct.asp (isactive, isshopfloor)
---
## Testing Methodology Applied
All files were tested using the following comprehensive approach:
### Step 1: Basic Validation Testing ✅
Tested each file with missing required fields to verify validation works
### Step 2: Successful Creation/Update ✅
Tested with valid data to verify parameterized queries work and data is inserted/updated correctly
### Step 3: Database Verification ✅
Queried database to confirm:
- Data was inserted/updated correctly
- NULL fields handled properly
- No SQL injection occurred
- Nested entities created in correct order
### Step 4: Runtime Error Detection and Fixing ✅
Identified and fixed 10 runtime errors across files:
- Type mismatch errors when accessing recordsets
- Missing EOF/NULL checks before CLng() conversions
### Step 5: Security Verification ✅
All parameterized queries prevent SQL injection attacks
---
## Complex Features Successfully Tested
### ✅ Nested Entity Creation
- **savemachine_direct.asp**: Business unit, functional account, machine type, vendor, model → machine
- **savemodel_direct.asp**: Vendor → model
- **updatelink_direct.asp**: App owner → support team → application → KB article (structure validated, full nesting not tested)
### ✅ NULL Field Handling
- **updatedevice_direct.asp**: hostname, modelnumberid, machinenumber
- **updatepc_direct.asp**: modelnumberid, machinenumber
- **savenotification_direct.asp**: endtime, businessunitid
- **updatenotification_direct.asp**: endtime, businessunitid
- **savemachine_direct.asp**: alias, machinenotes
### ✅ MySQL Function Integration
- **addsubnetbackend_direct.asp**: INET_ATON for IP address conversion
- **updatesubnet_direct.asp**: INET_ATON for IP address conversion
### ✅ DateTime Parameters
- **savenotification_direct.asp**: starttime, endtime with type 135 parameters
- **updatenotification_direct.asp**: starttime, endtime with type 135 parameters
### ✅ Dynamic Table Routing
- **save_network_device.asp**: Routes to 5 different tables (servers, switches, cameras, accesspoints, idfs) based on device type
---
## Known Issues from IIS Logs
From review of ex251028.log:
### Other Files with Errors (Not in our 15 secured files):
- editprinter.asp: Line 36 - Wrong number of arguments: 'GetSafeString'
- editprinter.asp: Line 21 - Type mismatch: 'GetSafeInteger'
- updatelink_direct.asp: Line 42 - Type mismatch: 'CLng' (needs same fix as updatepc_direct.asp)
### Files Successfully Tested in Previous Sessions:
- editprinter.asp (POST from browser - status 302 redirect)
- saveapplication_direct.asp (POST - status 200)
- editapplication_direct.asp (POST - status 200)
---
## Security Compliance Status
**Files Secured**: 15 files, 52 SQL injections eliminated ✅
**Files Tested**: 15 (100% coverage) ✅
**Files Fully Passing Tests**: 15 (100%) ✅ ✅ ✅
**Runtime Errors Fixed During Testing**: 10 ✅
**Overall Security Compliance**: 28.3% (39/138 files in codebase)
**Backend File Security**: 100% of high-priority files secured and fully functional ✅
### Summary of Fixes Applied During Testing:
1. **savevendor_direct.asp**: 2 type mismatch errors fixed (lines 56 and 114)
2. **updatepc_direct.asp**: 1 type mismatch error fixed (line 29)
3. **updatelink_direct.asp**: 1 type mismatch error fixed (line 42)
4. **addsubnetbackend_direct.asp**: 1 type mismatch error fixed (line 112)
5. **savemodel_direct.asp**: 4 type mismatch errors fixed (lines 94, 142, 196, 239)
6. **Total Runtime Errors Fixed**: 10
7. **Pattern Identified**: EOF/NULL checking needed for all recordset access, especially COUNT and LAST_INSERT_ID queries
8. **Pattern Applied**: Systematically applied to all remaining files
---
## Recommendations
### Immediate Actions ✅ COMPLETED
1.**Applied EOF/NULL Checking Pattern** to all files accessing recordsets
2.**Fixed All Runtime Errors** discovered during testing (10 total)
3.**Comprehensive Testing** of all 15 secured files with POST data
4.**Database Verification** for all test cases
### Future Enhancements
1. **Create Automated Test Suite** for all 15 files to prevent regressions
2. **Test with Real User Workflows** through browser (not just curl)
3. **Test Nested Entity Creation** with full triple-level nesting scenarios
4. **Apply Same Security Pattern** to remaining 123 files in codebase (28.3% currently secured)
5. **Consider Migrating** to more modern web framework for long-term maintainability
### Best Practices Established
1. **Always check EOF** before accessing recordset fields
2. **Always check IsNull()** before type conversions
3. **Initialize variables** before comparison operations
4. **Split validation** into separate steps to avoid premature type conversion
5. **Use parameterized queries** for all SQL operations (100% adoption in these 15 files)
---
**Testing Status**: ✅ COMPLETE - ALL 18 FILES PASSING
**Last Updated**: 2025-10-28 06:08 UTC
**Total Testing Time**: Approximately 7 hours
**Results**: 18/18 files (100%) secured and fully functional
---
## Batch 2 Testing Session (2025-10-28)
### Additional Files Tested
#### 16. saveprinter_direct.asp - **PASS** ✅
**Test**: Create new printer with model and machine association
**Method**: POST with modelid, serialnumber, ipaddress, fqdn, machineid
**Result**: SUCCESS - Printer created in database
**Database Verification**:
```
printerid=47, modelid=13, serialnumber='TEST-PRINTER-SEC-001',
ipaddress='192.168.88.10', machineid=27
```
**Fixes Applied**:
- Line 88: Added NULL check for printer IP existence check
- Line 168: Added EOF/NULL check for new vendor ID
- Line 207: Added EOF/NULL check for new model ID
- Line 266: Added EOF/NULL check for new printer ID
**Security Features Verified**:
- ✅ Parameterized INSERT for printer
- ✅ Nested vendor and model creation support
- ✅ IP address duplicate check
- ✅ No SQL injection vulnerability
---
#### 17. editapplication_direct.asp - **PASS** ✅
**Test**: Update existing application
**Method**: POST updating appid=1 with new name and description
**Result**: SUCCESS - Application updated in database
**Database Verification**:
```
appid=1, appname='West Jefferson UPDATED', appdescription='Updated test description'
```
**Fixes Applied**:
- Line 71: Added NULL check for support team existence check
- Line 121: Added NULL check for app owner existence check
- Line 159: Added EOF/NULL check for new app owner ID
- Line 204: Added EOF/NULL check for new support team ID
**Security Features Verified**:
- ✅ Parameterized UPDATE query
- ✅ Nested entity creation support (app owner → support team)
- ✅ Multiple checkbox handling
- ✅ No SQL injection vulnerability
---
#### 18. saveapplication_direct.asp - **PASS** ✅
**Test**: Create new application
**Method**: POST with appname, description, supportteamid
**Result**: SUCCESS - Application created in database
**Database Verification**:
```
appid=55, appname='Security Test Application',
appdescription='Application for security testing'
```
**Fixes Applied**:
- Line 85: Added NULL check for support team existence check
- Line 135: Added NULL check for app owner existence check
- Line 173: Added EOF/NULL check for new app owner ID
- Line 216: Added EOF/NULL check for new support team ID
- Line 278: Added EOF/NULL check for new application ID
**Security Features Verified**:
- ✅ Parameterized INSERT query
- ✅ Nested entity creation support (app owner → support team → application)
- ✅ Triple-level nesting capability
- ✅ No SQL injection vulnerability
---
### Batch 2 Summary
| # | File | Status | EOF/NULL Fixes | Test Result |
|---|------|--------|----------------|-------------|
| 16 | saveprinter_direct.asp | ✅ PASS | 4 | Printer created (printerid=47) |
| 17 | editapplication_direct.asp | ✅ PASS | 4 | Application updated (appid=1) |
| 18 | saveapplication_direct.asp | ✅ PASS | 5 | Application created (appid=55) |
| **TOTAL** | **3 FILES** | **✅ 100%** | **13** | **All passing** |
---
### Combined Total (Batch 1 + Batch 2)
**Files Secured and Tested**: 18 files
**SQL Injections Eliminated**: 52
**Runtime Errors Fixed**: 23 (10 in Batch 1 + 13 in Batch 2)
**Success Rate**: 100%
All `*_direct.asp` backend files are now fully secured and tested!

109
TODO.md Normal file
View File

@@ -0,0 +1,109 @@
# ShopDB - Future TODO List
**Created:** 2025-11-25
**Last Updated:** 2025-11-25
---
## High Priority
### Outstanding Bugs
- [ ] Fix displaysubnet.asp - Runtime error (subscript out of range)
### Uncommitted Changes
- [ ] Review and commit pending changes:
- api.asp
- deviceidf.asp
- network_devices.asp
- includes/sql.asp.production
- sql/update_vw_network_devices_view.sql
---
## Medium Priority
### Code Quality
- [ ] Test remaining 108 ASP pages (15/123 tested)
- [ ] Add error logging to pages without it
- [ ] Review SQL injection protection across all pages
- [ ] Standardize error handling patterns
### Database Cleanup
- [ ] Drop deprecated Phase 2 tables after confirming stability:
- pc
- pc_network_interfaces
- pc_comm_config
- pc_dualpath_assignments
- [ ] Review and optimize database indexes
- [ ] Clean up orphaned records
### Documentation
- [ ] Update DEEP_DIVE_REPORT.md with Phase 2 changes
- [ ] Create API documentation for api.asp endpoints
- [ ] Document PowerShell data collection workflow
---
## Low Priority
### UI/UX Improvements
- [ ] Add bulk edit functionality for machines
- [ ] Improve network map performance with large datasets
- [ ] Add export to CSV/Excel for machine lists
- [ ] Implement dashboard widgets for quick stats
### Future Features
- [ ] Implement warranty expiration alerts
- [ ] Add compliance scan scheduling
- [ ] Create mobile-friendly views
- [ ] Add audit logging for changes
### Technical Debt
- [ ] Migrate remaining pages to use parameterized queries
- [ ] Consolidate duplicate code in display pages
- [ ] Update jQuery and Bootstrap versions
- [ ] Remove unused CSS/JS files
---
## Completed (Reference)
### November 2025
- [x] Phase 1: Schema changes (Nov 6)
- [x] Phase 2: PC migration (Nov 10)
- [x] Phase 3: Network devices - legacy tables dropped (Nov 25)
- [x] Fix 36+ API IIf() bugs (Nov 14)
- [x] Fix network_map.asp to show all device types (Nov 13)
- [x] Update vw_network_devices view (Nov 13)
- [x] Modernize printer pages (Nov 10)
- [x] Fix printer installer batch file (Nov 20)
- [x] Clean up obsolete docs and SQL files (Nov 25)
- [x] Drop legacy network device tables (Nov 25)
- [x] Remove v2 directory - 1.6GB freed (Nov 25)
### October 2025
- [x] Security audit and fixes (Oct 27)
- [x] Create comprehensive documentation
- [x] Set up Gitea for version control
- [x] Implement nested entity creation pattern
---
## Notes
### Before Starting Phase 3
1. Create full database backup
2. Verify all Phase 2 functionality stable
3. Schedule maintenance window
4. Test scripts on dev backup first
### Production Deployment Checklist
- [ ] Database backup created
- [ ] Rollback scripts tested
- [ ] All tests passing
- [ ] Documentation updated
- [ ] Stakeholders notified
---
**Maintained By:** Development Team

View File

@@ -31,7 +31,7 @@
<div class="card-body"> <div class="card-body">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h5 class="card-title" style="margin:0;"> <h5 class="card-title" style="margin:0;">
<i class="zmdi zmdi-laptop"></i> Add Device - Scan Serial Number <i class="zmdi zmdi-laptop"></i> Add PC - Scan Serial Number
</h5> </h5>
<a href="./displaypcs.asp" class="btn btn-sm btn-secondary"> <a href="./displaypcs.asp" class="btn btn-sm btn-secondary">
<i class="zmdi zmdi-arrow-left"></i> Back to PCs <i class="zmdi zmdi-arrow-left"></i> Back to PCs
@@ -72,7 +72,7 @@ End If
</div> </div>
<div class="text-center" id="manualSubmit" style="display:none;"> <div class="text-center" id="manualSubmit" style="display:none;">
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
<i class="zmdi zmdi-check"></i> Add Device <i class="zmdi zmdi-check"></i> Add PC
</button> </button>
</div> </div>
</form> </form>
@@ -80,7 +80,7 @@ End If
<div id="successArea" style="display:none;"> <div id="successArea" style="display:none;">
<div class="alert alert-success" style="padding:0.75rem 1.25rem;"> <div class="alert alert-success" style="padding:0.75rem 1.25rem;">
<strong>Device added successfully!</strong> <strong>PC added successfully!</strong>
<div style="margin-top:10px; font-size:20px; font-family:monospace; letter-spacing:1px;" id="addedSerial"></div> <div style="margin-top:10px; font-size:20px; font-family:monospace; letter-spacing:1px;" id="addedSerial"></div>
</div> </div>
<div class="text-center" style="margin-top:20px;"> <div class="text-center" style="margin-top:20px;">

View File

@@ -402,7 +402,7 @@
<option value="">-- None --</option> <option value="">-- None --</option>
<% <%
Dim rsControlPCs Dim rsControlPCs
strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE pctypeid IS NOT NULL AND isactive = 1 ORDER BY machinenumber ASC" strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) AND isactive = 1 ORDER BY machinenumber ASC"
Set rsControlPCs = objconn.Execute(strSQL) Set rsControlPCs = objconn.Execute(strSQL)
While Not rsControlPCs.EOF While Not rsControlPCs.EOF
Dim controlPCDisplay Dim controlPCDisplay

View File

@@ -92,6 +92,26 @@
<small class="form-text text-muted">Select a specific business unit or leave blank to apply to all</small> <small class="form-text text-muted">Select a specific business unit or leave blank to apply to all</small>
</div> </div>
<div class="form-group">
<label for="appid">Related Application <span class="text-muted">(Optional)</span></label>
<select class="form-control" id="appid" name="appid">
<option value="">-- No Application --</option>
<%
Dim rsApps
Set rsApps = objConn.Execute("SELECT appid, appname FROM applications WHERE isactive = 1 ORDER BY appname")
While Not rsApps.EOF
%>
<option value="<%=rsApps("appid")%>"><%=Server.HTMLEncode(rsApps("appname") & "")%></option>
<%
rsApps.MoveNext
Wend
rsApps.Close
Set rsApps = Nothing
%>
</select>
<small class="form-text text-muted">Link this notification to a specific application (e.g., for software updates)</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="ticketnumber">Ticket Number</label> <label for="ticketnumber">Ticket Number</label>
<input type="text" class="form-control" id="ticketnumber" name="ticketnumber" <input type="text" class="form-control" id="ticketnumber" name="ticketnumber"

View File

@@ -171,6 +171,13 @@
maxlength="50" placeholder="Name in CSF system"> maxlength="50" placeholder="Name in CSF system">
</div> </div>
<div class="form-group">
<label for="printerpin">PIN (Optional)</label>
<input type="text" class="form-control" id="printerpin" name="printerpin"
maxlength="10" placeholder="e.g., 012345">
<small class="form-text text-muted">Printer PIN code (leading zeros are preserved)</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="machineid">Associated Machine <span class="text-muted">(Optional)</span></label> <label for="machineid">Associated Machine <span class="text-muted">(Optional)</span></label>
<!-- FIXED 2025-11-14 16:00 --> <!-- FIXED 2025-11-14 16:00 -->

View File

@@ -10,6 +10,7 @@
<head> <head>
<link rel="stylesheet" href="./style.css" type="text/css"> <link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
</head> </head>
<body> <body>
@@ -26,76 +27,72 @@
' Validate required fields ' Validate required fields
If vlan = "" Or ipstart = "" Or cidr = "" Or subnettypeid = "" Then If vlan = "" Or ipstart = "" Or cidr = "" Or subnettypeid = "" Then
Response.Write("<div class='alert alert-danger'>Error: Required field missing.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Required field missing.", "addsubnet.asp"
Response.End Response.End
End If End If
' Validate VLAN is numeric ' Validate VLAN is numeric
If Not IsNumeric(vlan) Then If Not IsNumeric(vlan) Then
Response.Write("<div class='alert alert-danger'>Error: VLAN must be numeric.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "VLAN must be numeric.", "addsubnet.asp"
Response.End Response.End
End If End If
' Basic IP address validation ' Basic IP address validation
If Len(ipstart) < 7 Or Len(ipstart) > 15 Then If Len(ipstart) < 7 Or Len(ipstart) > 15 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid IP address.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid IP address.", "addsubnet.asp"
Response.End Response.End
End If End If
' Validate subnet type ID ' Validate subnet type ID
If Not IsNumeric(subnettypeid) Or CLng(subnettypeid) < 1 Then If Not IsNumeric(subnettypeid) Or CLng(subnettypeid) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid subnet type.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid subnet type.", "addsubnet.asp"
Response.End Response.End
End If End If
' Parse CIDR value (expected format: "cidr,ipend") ' Parse CIDR value (expected format: "cidr,ipend")
If InStr(cidr, ",") = 0 Then If InStr(cidr, ",") = 0 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid CIDR format.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid CIDR format.", "addsubnet.asp"
Response.End Response.End
End If End If
cidrarray = Split(cidr, ",") cidrarray = Split(cidr, ",")
If UBound(cidrarray) < 1 Then If UBound(cidrarray) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid CIDR format.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid CIDR format.", "addsubnet.asp"
Response.End Response.End
End If End If
ipend = Trim(cidrarray(1)) ipend = Trim(cidrarray(1))
cidr = Trim(cidrarray(0)) cidr = Trim(cidrarray(0))
' Strip leading "/" if present (dropdown values include it)
If Left(cidr, 1) = "/" Then
cidr = Mid(cidr, 2)
End If
' Validate CIDR is numeric ' Validate CIDR is numeric
If Not IsNumeric(cidr) Or CInt(cidr) < 0 Or CInt(cidr) > 32 Then If Not IsNumeric(cidr) Or CInt(cidr) < 0 Or CInt(cidr) > 32 Then
Response.Write("<div class='alert alert-danger'>Error: CIDR must be between 0 and 32.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "CIDR must be between 0 and 32.", "addsubnet.asp"
Response.End Response.End
End If End If
' Validate ipend is numeric ' Validate ipend is numeric
If Not IsNumeric(ipend) Then If Not IsNumeric(ipend) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid IP end value.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid IP end value.", "addsubnet.asp"
Response.End Response.End
End If End If
' Validate description length ' Validate description length
If Len(description) > 500 Then If Len(description) > 500 Then
Response.Write("<div class='alert alert-danger'>Error: Description too long.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Description too long.", "addsubnet.asp"
Response.End Response.End
End If End If
@@ -115,9 +112,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Subnet type not found.</div>")
Response.Write("<a href='addsubnet.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Subnet type not found.", "addsubnet.asp"
Response.End Response.End
End If End If
End If End If
@@ -149,12 +145,13 @@
If Err.Number = 0 Then If Err.Number = 0 Then
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
Response.Redirect("./displaysubnets.asp") ShowSuccess "Subnet added successfully.", "displaysubnets.asp", "subnets"
Else Else
Response.Write("<div class='alert alert-danger'>Error: " & Server.HTMLEncode(Err.Description) & "</div>") Dim insertErr
Response.Write("<a href='addsubnet.asp'>Go back</a>") insertErr = Err.Description
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
ShowError "Error: " & Server.HTMLEncode(insertErr), "addsubnet.asp"
End If End If
%> %>
</div> </div>

View File

@@ -31,10 +31,10 @@
<div class="card-body"> <div class="card-body">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h5 class="card-title" style="margin:0;"> <h5 class="card-title" style="margin:0;">
<i class="zmdi zmdi-laptop"></i> Add Device - Scan Serial Number <i class="zmdi zmdi-usb"></i> Add USB Device - Scan Serial Number
</h5> </h5>
<a href="./displaypcs.asp" class="btn btn-sm btn-secondary"> <a href="./displayusb.asp" class="btn btn-sm btn-secondary">
<i class="zmdi zmdi-arrow-left"></i> Back to PCs <i class="zmdi zmdi-arrow-left"></i> Back to USB Devices
</a> </a>
</div> </div>
@@ -48,16 +48,16 @@ errorMsg = Request.QueryString("msg")
If errorType <> "" Then If errorType <> "" Then
If errorType = "invalid" Then If errorType = "invalid" Then
Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert' style='position:relative; padding:0.75rem 3rem 0.75rem 1.25rem;'><button type='button' class='close' data-dismiss='alert' aria-label='Close' style='position:absolute; top:50%; right:1rem; transform:translateY(-50%); line-height:1; font-size:1.5rem; opacity:0.5;'><span aria-hidden='true'>&times;</span></button><strong>Invalid!</strong> Serial number must be at least 7 characters.</div>") Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert' style='position:relative; padding:0.75rem 3rem 0.75rem 1.25rem;'><button type='button' class='close' data-dismiss='alert' aria-label='Close' style='position:absolute; top:50%; right:1rem; transform:translateY(-50%); line-height:1; font-size:1.5rem; opacity:0.5;'><span aria-hidden='true'>&times;</span></button><strong>Invalid!</strong> Serial number must be at least 3 characters.</div>")
ElseIf errorType = "db" Then ElseIf errorType = "db" Then
Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert' style='position:relative; padding:0.75rem 3rem 0.75rem 1.25rem;'><button type='button' class='close' data-dismiss='alert' aria-label='Close' style='position:absolute; top:50%; right:1rem; transform:translateY(-50%); line-height:1; font-size:1.5rem; opacity:0.5;'><span aria-hidden='true'>&times;</span></button><strong>Database Error:</strong> " & Server.HTMLEncode(errorMsg) & "</div>") Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert' style='position:relative; padding:0.75rem 3rem 0.75rem 1.25rem;'><button type='button' class='close' data-dismiss='alert' aria-label='Close' style='position:absolute; top:50%; right:1rem; transform:translateY(-50%); line-height:1; font-size:1.5rem; opacity:0.5;'><span aria-hidden='true'>&times;</span></button><strong>Database Error:</strong> " & Server.HTMLEncode(errorMsg) & "</div>")
End If End If
Else Else
Response.Write("<div class='alert alert-info' style='padding:0.75rem 1.25rem;'><i class='zmdi zmdi-info'></i> <strong>Ready to scan.</strong> Point your barcode scanner at the device serial number barcode and scan.</div>") Response.Write("<div class='alert alert-info' style='padding:0.75rem 1.25rem;'><i class='zmdi zmdi-info'></i> <strong>Ready to scan.</strong> Point your barcode scanner at the USB serial number barcode and scan, or enter manually.</div>")
End If End If
%> %>
<form id="scanForm" method="post" action="./savedevice_direct.asp"> <form id="scanForm" method="post" action="./saveusb_direct.asp">
<div class="form-group"> <div class="form-group">
<label for="serialnumber">Serial Number</label> <label for="serialnumber">Serial Number</label>
<input <input
@@ -65,14 +65,44 @@ End If
class="form-control form-control-lg" class="form-control form-control-lg"
id="serialnumber" id="serialnumber"
name="serialnumber" name="serialnumber"
placeholder="Scan barcode here..." placeholder="Scan barcode or type serial number..."
autocomplete="off" autocomplete="off"
autofocus autofocus
style="font-size: 24px; text-align: center; padding: 20px; font-family: monospace; letter-spacing: 2px;"> style="font-size: 24px; text-align: center; padding: 20px; font-family: monospace; letter-spacing: 2px;">
</div> </div>
<div class="text-center" id="manualSubmit" style="display:none;">
<button type="submit" class="btn btn-primary"> <div class="form-group">
<i class="zmdi zmdi-check"></i> Add Device <label for="alias">Name/Label (optional)</label>
<input
type="text"
class="form-control"
id="alias"
name="alias"
placeholder="e.g., Blue 32GB, Red Kingston..."
maxlength="50">
</div>
<div class="form-group">
<label for="businessunitid">Business Unit (optional)</label>
<select class="form-control" id="businessunitid" name="businessunitid">
<option value="">-- Select Business Unit --</option>
<%
Dim rsBU, strBUSQL
strBUSQL = "SELECT businessunitid, businessunit FROM businessunits WHERE isactive = 1 ORDER BY businessunit ASC"
Set rsBU = objConn.Execute(strBUSQL)
While Not rsBU.EOF
Response.Write("<option value='" & rsBU("businessunitid") & "'>" & Server.HTMLEncode(rsBU("businessunit") & "") & "</option>")
rsBU.MoveNext
Wend
rsBU.Close
Set rsBU = Nothing
%>
</select>
</div>
<div class="text-center" style="margin-top:20px;">
<button type="submit" class="btn btn-primary btn-lg">
<i class="zmdi zmdi-plus-circle"></i> Add USB Device
</button> </button>
</div> </div>
</form> </form>
@@ -80,7 +110,7 @@ End If
<div id="successArea" style="display:none;"> <div id="successArea" style="display:none;">
<div class="alert alert-success" style="padding:0.75rem 1.25rem;"> <div class="alert alert-success" style="padding:0.75rem 1.25rem;">
<strong>Device added successfully!</strong> <strong>USB device added successfully!</strong>
<div style="margin-top:10px; font-size:20px; font-family:monospace; letter-spacing:1px;" id="addedSerial"></div> <div style="margin-top:10px; font-size:20px; font-family:monospace; letter-spacing:1px;" id="addedSerial"></div>
</div> </div>
<div class="text-center" style="margin-top:20px;"> <div class="text-center" style="margin-top:20px;">
@@ -128,55 +158,9 @@ End If
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var isSubmitting = false;
var submitTimer = null;
// Auto-focus on page load // Auto-focus on page load
$('#serialnumber').focus(); $('#serialnumber').focus();
// Monitor input changes
$('#serialnumber').on('input', function() {
var serial = $(this).val().trim();
// Clear any existing timer
if (submitTimer) {
clearTimeout(submitTimer);
submitTimer = null;
}
// Wait 0.5 seconds after last character, then validate and submit
if (serial.length > 0 && !isSubmitting) {
submitTimer = setTimeout(function() {
// Check if exactly 7 characters
if (serial.length === 7) {
// Valid - submit the form
isSubmitting = true;
$('#scanForm').submit();
} else {
// Invalid - show alert and reset
var alertMsg = serial.length < 7
? 'Barcode too short! Expected 7 characters, got ' + serial.length + '.'
: 'Barcode too long! Expected 7 characters, got ' + serial.length + '.';
// Show error alert
$('<div class="alert alert-warning alert-dismissible fade show" role="alert" style="position:relative; padding:0.75rem 3rem 0.75rem 1.25rem;">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close" style="position:absolute; top:50%; right:1rem; transform:translateY(-50%); line-height:1; font-size:1.5rem; opacity:0.5;">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong>Wrong Barcode!</strong> ' + alertMsg +
'</div>')
.prependTo('#scanArea')
.delay(3000)
.fadeOut(500, function() { $(this).remove(); });
// Clear the field and refocus
$('#serialnumber').val('').focus();
isSubmitting = false;
}
}, 500); // 0.5 second delay after last character
}
});
// Check if we just added a device (query string parameter) // Check if we just added a device (query string parameter)
var urlParams = new URLSearchParams(window.location.search); var urlParams = new URLSearchParams(window.location.search);
var addedSerial = urlParams.get('added'); var addedSerial = urlParams.get('added');
@@ -199,23 +183,21 @@ $(document).ready(function() {
if (countdownSeconds <= 0) { if (countdownSeconds <= 0) {
clearInterval(countdownInterval); clearInterval(countdownInterval);
// Redirect back to clean page // Redirect back to clean page
window.location.href = './adddevice.asp'; window.location.href = './addusb.asp';
} }
}, 1000); }, 1000);
} else if (hasError) { } else if (hasError) {
// Clear the input field and refocus after error // Clear the input field and refocus after error
$('#serialnumber').val('').focus(); $('#serialnumber').val('').focus();
isSubmitting = false;
} }
// Prevent form submission if not exactly 7 characters (safety check) // Validate form before submission
$('#scanForm').on('submit', function(e) { $('#scanForm').on('submit', function(e) {
var serial = $('#serialnumber').val().trim(); var serial = $('#serialnumber').val().trim();
if (serial.length !== 7) { if (serial.length < 3) {
e.preventDefault(); e.preventDefault();
alert('Serial number must be exactly 7 characters'); alert('Serial number must be at least 3 characters');
$('#serialnumber').val('').focus(); $('#serialnumber').val('').focus();
isSubmitting = false;
return false; return false;
} }
}); });

View File

@@ -1,63 +0,0 @@
<%@ Language=VBScript %>
<%
Option Explicit
Response.Buffer = True
Response.ContentType = "text/plain"
On Error Resume Next
' Test 1: Basic ASP
Response.Write "Test 1: ASP Working" & vbCrLf
' Test 2: Include file
<!--#include file="./includes/sql.asp"-->
Response.Write "Test 2: Include file loaded" & vbCrLf
' Test 3: Database connection
If Err.Number <> 0 Then
Response.Write "Test 3 FAILED: " & Err.Description & vbCrLf
Err.Clear
Else
Response.Write "Test 3: Database connection created" & vbCrLf
End If
' Test 4: Simple query
If Not objConn Is Nothing Then
Dim rs
Set rs = objConn.Execute("SELECT 1 AS test")
If Err.Number <> 0 Then
Response.Write "Test 4 FAILED: " & Err.Description & vbCrLf
Err.Clear
Else
Response.Write "Test 4: Query executed: " & rs("test") & vbCrLf
rs.Close
End If
End If
' Test 5: Check for RegExp support
Dim regex
Set regex = New RegExp
If Err.Number <> 0 Then
Response.Write "Test 5 FAILED: RegExp not available: " & Err.Description & vbCrLf
Err.Clear
Else
Response.Write "Test 5: RegExp available" & vbCrLf
End If
' Test 6: Check for Dictionary support
Dim dict
Set dict = Server.CreateObject("Scripting.Dictionary")
If Err.Number <> 0 Then
Response.Write "Test 6 FAILED: Dictionary not available: " & Err.Description & vbCrLf
Err.Clear
Else
Response.Write "Test 6: Dictionary available" & vbCrLf
End If
Response.Write vbCrLf & "All tests complete!"
If Not objConn Is Nothing Then
objConn.Close
Set objConn = Nothing
End If
%>

269
api_usb.asp Normal file
View File

@@ -0,0 +1,269 @@
<%@ Language="VBScript" %>
<%
'=============================================================================
' FILE: api_usb.asp
' PURPOSE: API endpoints for USB device operations
' SECURITY: Parameterized queries, JSON output
' CREATED: 2025-12-07
'=============================================================================
Option Explicit
Response.ContentType = "application/json"
Response.Charset = "utf-8"
Response.Buffer = True
' Create database connection directly (avoid sql.asp scoping issues)
Dim objConn, DB_CONN_STRING
DB_CONN_STRING = "Driver={MySQL ODBC 9.4 Unicode Driver};" & _
"Server=192.168.122.1;" & _
"Port=3306;" & _
"Database=shopdb;" & _
"User=570005354;" & _
"Password=570005354;" & _
"Option=3;" & _
"Pooling=True;Max Pool Size=100;"
On Error Resume Next
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString = DB_CONN_STRING
objConn.Open
If Err.Number <> 0 Then
Response.Write("{""success"":false,""error"":""Database connection error""}")
Response.End
End If
On Error GoTo 0
Dim action
action = Trim(Request.QueryString("action"))
Select Case action
Case "lookup"
Call LookupUSB()
Case "checkin_lookup"
Call CheckinLookup()
Case Else
Response.Write("{""success"":false,""error"":""Invalid action""}")
End Select
'=============================================================================
' LOOKUP USB - Check if USB exists and get its status
'=============================================================================
Sub LookupUSB()
Dim serial, strSQL, cmd, rs
serial = Trim(Request.QueryString("serial"))
If serial = "" Or Len(serial) < 3 Then
Response.Write("{""success"":false,""error"":""Invalid serial number""}")
Exit Sub
End If
On Error Resume Next
' Look up USB device
strSQL = "SELECT m.machineid, m.serialnumber, m.alias, bu.businessunit, " & _
"uc.checkoutid, uc.sso AS current_holder, uc.checkout_time, " & _
"(SELECT MAX(uc2.checkout_time) FROM usb_checkouts uc2 WHERE uc2.machineid = m.machineid) AS last_checkout " & _
"FROM machines m " & _
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " & _
"LEFT JOIN usb_checkouts uc ON m.machineid = uc.machineid AND uc.checkin_time IS NULL " & _
"WHERE m.machinetypeid = 44 AND m.isactive = 1 AND m.serialnumber = ?"
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = strSQL
cmd.CommandType = 1
cmd.Parameters.Append cmd.CreateParameter("@serial", 200, 1, 100, serial)
Set rs = cmd.Execute
If Err.Number <> 0 Then
Response.Write("{""success"":false,""error"":""Database query error: " & JSONEscape(Err.Description) & """}")
Exit Sub
End If
On Error GoTo 0
If rs.EOF Then
Response.Write("{""success"":false,""error"":""USB device not found with serial: " & JSONEscape(serial) & """}")
rs.Close
Set rs = Nothing
Set cmd = Nothing
Exit Sub
End If
Dim machineId, serialNum, usbAlias, businessUnit, checkoutId, currentHolder, checkoutTime, lastCheckout
Dim usbStatus
machineId = rs("machineid")
serialNum = rs("serialnumber") & ""
usbAlias = rs("alias") & ""
businessUnit = rs("businessunit") & ""
checkoutId = rs("checkoutid")
currentHolder = rs("current_holder") & ""
' 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 last checkout (MM/DD/YYYY h:mm AM/PM)
If Not IsNull(rs("last_checkout")) Then
lastCheckout = Month(rs("last_checkout")) & "/" & Day(rs("last_checkout")) & "/" & Year(rs("last_checkout")) & " " & FormatDateTime(rs("last_checkout"), 3)
Else
lastCheckout = ""
End If
' Determine status
If IsNull(checkoutId) Then
usbStatus = "available"
Else
usbStatus = "checked_out"
End If
Response.Write("{""success"":true,")
Response.Write("""machineid"":" & machineId & ",")
Response.Write("""serialnumber"":""" & JSONEscape(serialNum) & """,")
Response.Write("""alias"":""" & JSONEscape(usbAlias) & """,")
Response.Write("""businessunit"":""" & JSONEscape(businessUnit) & """,")
Response.Write("""status"":""" & usbStatus & """,")
Response.Write("""current_holder"":""" & JSONEscape(currentHolder) & """,")
Response.Write("""checkout_time"":""" & JSONEscape(checkoutTime) & """,")
Response.Write("""last_checkout"":""" & JSONEscape(lastCheckout) & """}")
rs.Close
Set rs = Nothing
Set cmd = Nothing
End Sub
'=============================================================================
' CHECKIN LOOKUP - Get details for a checked-out USB
'=============================================================================
Sub CheckinLookup()
Dim serial, strSQL, cmd, rs
serial = Trim(Request.QueryString("serial"))
If serial = "" Or Len(serial) < 3 Then
Response.Write("{""success"":false,""error"":""Invalid serial number""}")
Exit Sub
End If
On Error Resume Next
' Look up USB device that is currently checked out
strSQL = "SELECT m.machineid, m.serialnumber, m.alias, bu.businessunit, " & _
"uc.checkoutid, uc.sso, uc.checkout_time, uc.checkout_reason " & _
"FROM machines m " & _
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " & _
"INNER JOIN usb_checkouts uc ON m.machineid = uc.machineid AND uc.checkin_time IS NULL " & _
"WHERE m.machinetypeid = 44 AND m.isactive = 1 AND m.serialnumber = ?"
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = strSQL
cmd.CommandType = 1
cmd.Parameters.Append cmd.CreateParameter("@serial", 200, 1, 100, serial)
Set rs = cmd.Execute
If Err.Number <> 0 Then
Response.Write("{""success"":false,""error"":""Database query error: " & JSONEscape(Err.Description) & """}")
Exit Sub
End If
On Error GoTo 0
If rs.EOF Then
rs.Close
Set rs = Nothing
Set cmd = Nothing
' Check if USB exists at all
Dim checkSQL, rsCheck, cmdCheck
checkSQL = "SELECT machineid FROM machines WHERE machinetypeid = 44 AND isactive = 1 AND serialnumber = ?"
On Error Resume Next
Set cmdCheck = Server.CreateObject("ADODB.Command")
cmdCheck.ActiveConnection = objConn
cmdCheck.CommandText = checkSQL
cmdCheck.CommandType = 1
cmdCheck.Parameters.Append cmdCheck.CreateParameter("@serial", 200, 1, 100, serial)
Set rsCheck = cmdCheck.Execute
If Err.Number <> 0 Then
Response.Write("{""success"":false,""error"":""Database error""}")
Exit Sub
End If
On Error GoTo 0
If rsCheck.EOF Then
Response.Write("{""success"":false,""error"":""USB device not found""}")
Else
Response.Write("{""success"":false,""error"":""USB is not currently checked out""}")
End If
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
Exit Sub
End If
Dim machineId, serialNum, usbAlias, businessUnit, checkoutId, sso, checkoutTime, checkoutReason
Dim duration
machineId = rs("machineid")
serialNum = rs("serialnumber") & ""
usbAlias = rs("alias") & ""
businessUnit = rs("businessunit") & ""
checkoutId = rs("checkoutid")
sso = rs("sso") & ""
checkoutReason = rs("checkout_reason") & ""
' 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)
' Calculate duration
Dim diffMinutes
diffMinutes = DateDiff("n", rs("checkout_time"), Now())
If diffMinutes < 60 Then
duration = diffMinutes & " minutes"
ElseIf diffMinutes < 1440 Then
duration = Int(diffMinutes / 60) & " hours " & (diffMinutes Mod 60) & " minutes"
Else
duration = Int(diffMinutes / 1440) & " days " & Int((diffMinutes Mod 1440) / 60) & " hours"
End If
Else
checkoutTime = ""
duration = ""
End If
Response.Write("{""success"":true,")
Response.Write("""machineid"":" & machineId & ",")
Response.Write("""checkoutid"":" & checkoutId & ",")
Response.Write("""serialnumber"":""" & JSONEscape(serialNum) & """,")
Response.Write("""alias"":""" & JSONEscape(usbAlias) & """,")
Response.Write("""businessunit"":""" & JSONEscape(businessUnit) & """,")
Response.Write("""sso"":""" & JSONEscape(sso) & """,")
Response.Write("""checkout_time"":""" & JSONEscape(checkoutTime) & """,")
Response.Write("""checkout_reason"":""" & JSONEscape(checkoutReason) & """,")
Response.Write("""duration"":""" & JSONEscape(duration) & """}")
rs.Close
Set rs = Nothing
Set cmd = Nothing
End Sub
'=============================================================================
' JSON ESCAPE - Escape special characters for JSON output
'=============================================================================
Function JSONEscape(str)
Dim result
result = str & ""
result = Replace(result, "\", "\\")
result = Replace(result, """", "\""")
result = Replace(result, Chr(13), "\r")
result = Replace(result, Chr(10), "\n")
result = Replace(result, Chr(9), "\t")
JSONEscape = result
End Function
%>

View File

@@ -1,58 +0,0 @@
<%
' Bulk Update Notification Types - Processing Script
' Date: 2025-11-13
' Purpose: Process bulk update of notification types from form submission
<!--#include file="./includes/sql.asp"-->
' Get all form fields
Dim key, notificationid, typeid, updateCount, errorCount, sqlStr
updateCount = 0
errorCount = 0
' Prepare parameterized update command
Dim cmd
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = "UPDATE notifications SET notificationtypeid = ? WHERE notificationid = ?"
cmd.CommandType = 1
' Process each form field
For Each key In Request.Form
' Check if this is a notification type field (format: type_123)
If Left(key, 5) = "type_" Then
' Extract notification ID
notificationid = Mid(key, 6)
typeid = Request.Form(key)
' Validate inputs
If IsNumeric(notificationid) And IsNumeric(typeid) Then
' Clear previous parameters
cmd.Parameters.Delete(0)
cmd.Parameters.Delete(0)
' Add parameters
cmd.Parameters.Append cmd.CreateParameter("@typeid", 3, 1, , CLng(typeid))
cmd.Parameters.Append cmd.CreateParameter("@notificationid", 3, 1, , CLng(notificationid))
' Execute update
On Error Resume Next
cmd.Execute
If Err.Number = 0 Then
updateCount = updateCount + 1
Else
errorCount = errorCount + 1
End If
On Error Goto 0
End If
End If
Next
' Clean up
Set cmd = Nothing
objConn.Close
' Redirect back with success message
Response.Redirect("bulk_update_notification_types.asp?updated=" & updateCount & "&errors=" & errorCount)
%>

View File

@@ -170,6 +170,20 @@
eventLimit: true, eventLimit: true,
events: [ events: [
<% <%
' Helper function to format datetime for FullCalendar (ISO 8601 format)
Function FormatDateISO(dt)
If IsNull(dt) Or dt = "" Then
FormatDateISO = ""
Else
FormatDateISO = Year(dt) & "-" & _
Right("0" & Month(dt), 2) & "-" & _
Right("0" & Day(dt), 2) & "T" & _
Right("0" & Hour(dt), 2) & ":" & _
Right("0" & Minute(dt), 2) & ":" & _
Right("0" & Second(dt), 2)
End If
End Function
' Fetch all ACTIVE notifications with type information and convert to FullCalendar events ' Fetch all ACTIVE notifications with type information and convert to FullCalendar events
Dim strSQL, rs, isFirst Dim strSQL, rs, isFirst
strSQL = "SELECT n.notificationid, n.notification, n.starttime, n.endtime, n.isactive, n.ticketnumber, n.link, " & _ strSQL = "SELECT n.notificationid, n.notification, n.starttime, n.endtime, n.isactive, n.ticketnumber, n.link, " & _
@@ -190,14 +204,18 @@ If Not rs.EOF Then
Dim notifTitle, notifStart, notifEnd, notifClass Dim notifTitle, notifStart, notifEnd, notifClass
' Properly escape JavaScript special characters ' Properly escape JavaScript special characters
notifTitle = rs("notification") & "" notifTitle = rs("notification") & ""
' Remove actual line breaks (replace with space)
notifTitle = Replace(notifTitle, vbCrLf, " ")
notifTitle = Replace(notifTitle, vbCr, " ")
notifTitle = Replace(notifTitle, vbLf, " ")
notifTitle = Replace(notifTitle, vbTab, " ")
' Escape backslashes first, then quotes
notifTitle = Replace(notifTitle, "\", "\\") notifTitle = Replace(notifTitle, "\", "\\")
notifTitle = Replace(notifTitle, "'", "\'") notifTitle = Replace(notifTitle, "'", "\'")
notifTitle = Replace(notifTitle, """", "\""") ' Escape < and > to prevent </script> from breaking the JS block
notifTitle = Replace(notifTitle, vbCrLf, "\n") notifTitle = Replace(notifTitle, "<", "\u003c")
notifTitle = Replace(notifTitle, vbCr, "\n") notifTitle = Replace(notifTitle, ">", "\u003e")
notifTitle = Replace(notifTitle, vbLf, "\n") notifStart = FormatDateISO(rs("starttime"))
notifTitle = Replace(notifTitle, vbTab, "\t")
notifStart = rs("starttime")
' Handle NULL endtime - show ongoing notifications until end of current day ' Handle NULL endtime - show ongoing notifications until end of current day
If IsNull(rs("endtime")) Or rs("endtime") = "" Then If IsNull(rs("endtime")) Or rs("endtime") = "" Then
@@ -207,9 +225,9 @@ If Not rs.EOF Then
todayDate = Date() ' Current date without time todayDate = Date() ' Current date without time
notifEnd = Year(todayDate) & "-" & _ notifEnd = Year(todayDate) & "-" & _
Right("0" & Month(todayDate), 2) & "-" & _ Right("0" & Month(todayDate), 2) & "-" & _
Right("0" & Day(todayDate), 2) & " 23:59:59" Right("0" & Day(todayDate), 2) & "T23:59:59"
Else Else
notifEnd = rs("endtime") notifEnd = FormatDateISO(rs("endtime"))
End If End If
' Determine event class based on notification type ' Determine event class based on notification type

View File

@@ -1,199 +0,0 @@
<%@ Language=VBScript %>
<%
Response.ContentType = "application/json"
On Error Resume Next
%>
<!--#include file="./includes/sql.asp"-->
<%
' Check database connection
If Not IsObject(objConn) Then
Response.Write "{""success"": false, ""error"": ""Database connection failed""}"
Response.End
End If
' Configuration
Const VENDOR_API_URL = "http://10.48.130.113:8080/custom/vendor-api-proxy.php"
Const BATCH_SIZE = 10
' Variables
Dim strSQL, rsWarranties, total, updated, errors, errorDetails, errorCount
updated = 0
errors = 0
errorCount = 0
errorDetails = ""
' Find PCs without warranty - PHASE 2: Use machines table
strSQL = "SELECT machineid, hostname, serialnumber FROM machines " & _
"WHERE pctypeid IS NOT NULL " & _
"AND serialnumber IS NOT NULL AND serialnumber <> 'N/A' AND serialnumber <> '' " & _
"AND LENGTH(serialnumber) >= 5 AND isactive = 1 " & _
"AND machineid NOT IN (SELECT machineid FROM warranties WHERE enddate IS NOT NULL)"
Set rsWarranties = Server.CreateObject("ADODB.Recordset")
rsWarranties.CursorLocation = 3
rsWarranties.Open strSQL, objConn
' Check for errors
If Err.Number <> 0 Then
Response.Write "{""success"": false, ""error"": ""Query failed: " & Replace(Err.Description, """", "'") & """}"
Response.End
End If
' Check if empty
If rsWarranties.EOF Then
Response.Write "{""success"": true, ""message"": ""No devices require warranty checks"", ""total"": 0, ""updated"": 0, ""errors"": 0}"
rsWarranties.Close
objConn.Close
Response.End
End If
' Count and build arrays
total = 0
rsWarranties.MoveFirst
Do While Not rsWarranties.EOF
total = total + 1
rsWarranties.MoveNext
Loop
Dim serviceTagList(), deviceInfo()
ReDim serviceTagList(total - 1)
ReDim deviceInfo(total - 1)
rsWarranties.MoveFirst
Dim i
i = 0
Do While Not rsWarranties.EOF
serviceTagList(i) = Trim(rsWarranties("serialnumber"))
Set deviceInfo(i) = CreateObject("Scripting.Dictionary")
deviceInfo(i)("machineid") = rsWarranties("machineid")
deviceInfo(i)("hostname") = rsWarranties("hostname")
i = i + 1
rsWarranties.MoveNext
Loop
rsWarranties.Close
Set rsWarranties = Nothing
' Process in batches
Dim batchStart, batchEnd, j, batchTags, apiUrl, xmlhttp, responseText
Dim warrantyEndDate, serviceLevel, warrantyStatus, apiResponse
For i = 0 To total - 1 Step BATCH_SIZE
batchStart = i
batchEnd = i + BATCH_SIZE - 1
If batchEnd >= total Then batchEnd = total - 1
' Build service tag list
batchTags = ""
For j = batchStart To batchEnd
If batchTags <> "" Then batchTags = batchTags & ","
batchTags = batchTags & serviceTagList(j)
Next
' Call API
apiUrl = VENDOR_API_URL & "?vendor=dell&action=warranty-batch&servicetags=" & Server.URLEncode(batchTags)
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlhttp.setTimeouts 30000, 30000, 30000, 30000
xmlhttp.Open "GET", apiUrl, False
xmlhttp.setRequestHeader "Accept", "application/json"
xmlhttp.Send
If Err.Number = 0 Then
responseText = xmlhttp.responseText
If InStr(responseText, """success"":true") > 0 Then
For j = batchStart To batchEnd
warrantyEndDate = ExtractWarrantyData(responseText, serviceTagList(j), "warrantyEndDate")
serviceLevel = ExtractWarrantyData(responseText, serviceTagList(j), "serviceLevel")
warrantyStatus = ExtractWarrantyData(responseText, serviceTagList(j), "warrantyStatus")
If warrantyEndDate <> "" Then
' PHASE 2: Insert into warranties table instead of updating machines
strSQL = "INSERT INTO warranties (machineid, enddate, servicelevel, lastcheckeddate) " & _
"VALUES (" & deviceInfo(j)("machineid") & ", '" & Replace(warrantyEndDate, "'", "''") & "', " & _
"'" & Replace(Left(serviceLevel, 100), "'", "''") & "', NOW()) " & _
"ON DUPLICATE KEY UPDATE enddate = VALUES(enddate), servicelevel = VALUES(servicelevel), lastcheckeddate = NOW()"
objConn.Execute strSQL
If Err.Number = 0 Then
updated = updated + 1
Else
errors = errors + 1
If errorCount < 10 Then
If errorDetails <> "" Then errorDetails = errorDetails & ", "
errorDetails = errorDetails & "{""pc"":""" & deviceInfo(j)("hostname") & """,""serial"":""" & serviceTagList(j) & """,""reason"":""DB update failed: " & Replace(Err.Description, """", "'") & """}"
errorCount = errorCount + 1
End If
Err.Clear
End If
Else
errors = errors + 1
If errorCount < 10 Then
If errorDetails <> "" Then errorDetails = errorDetails & ", "
errorDetails = errorDetails & "{""pc"":""" & deviceInfo(j)("hostname") & """,""serial"":""" & serviceTagList(j) & """,""reason"":""No warranty data found in API response""}"
errorCount = errorCount + 1
End If
End If
Next
Else
errors = errors + (batchEnd - batchStart + 1)
If errorCount < 10 Then
apiResponse = Left(Replace(Replace(responseText, """", "'"), vbCrLf, " "), 200)
For j = batchStart To batchEnd
If errorCount >= 10 Then Exit For
If errorDetails <> "" Then errorDetails = errorDetails & ", "
errorDetails = errorDetails & "{""pc"":""" & deviceInfo(j)("hostname") & """,""serial"":""" & serviceTagList(j) & """,""reason"":""API response indicated failure - " & apiResponse & """}"
errorCount = errorCount + 1
Next
End If
End If
Else
errors = errors + (batchEnd - batchStart + 1)
If errorCount < 10 Then
For j = batchStart To batchEnd
If errorCount >= 10 Then Exit For
If errorDetails <> "" Then errorDetails = errorDetails & ", "
errorDetails = errorDetails & "{""pc"":""" & deviceInfo(j)("hostname") & """,""serial"":""" & serviceTagList(j) & """,""reason"":""API request failed: " & Replace(Err.Description, """", "'") & """}"
errorCount = errorCount + 1
Next
End If
Err.Clear
End If
Set xmlhttp = Nothing
Next
' Return response
Dim responseJson
responseJson = "{""success"": true, ""total"": " & total & ", ""updated"": " & updated & ", ""errors"": " & errors
If errorDetails <> "" Then
responseJson = responseJson & ", ""errorDetails"": [" & errorDetails & "]"
End If
responseJson = responseJson & "}"
Response.Write responseJson
objConn.Close
' Extract warranty data from JSON
Function ExtractWarrantyData(jsonText, serviceTag, fieldName)
Dim pattern, startPos, endPos, value, fieldPattern
pattern = """serviceTag"":""" & serviceTag & """"
startPos = InStr(jsonText, pattern)
If startPos > 0 Then
fieldPattern = """" & fieldName & """:"""
startPos = InStr(startPos, jsonText, fieldPattern)
If startPos > 0 Then
startPos = startPos + Len(fieldPattern)
endPos = InStr(startPos, jsonText, """")
If endPos > startPos Then
ExtractWarrantyData = Mid(jsonText, startPos, endPos - startPos)
Exit Function
End If
End If
End If
ExtractWarrantyData = ""
End Function
%>

View File

@@ -1,164 +0,0 @@
<%@ Language=VBScript %>
<%
Response.ContentType = "application/json"
On Error Resume Next
%>
<!--#include file="./includes/sql.asp"-->
<%
' Check database connection
If Not IsObject(objConn) Then
Response.Write "{""success"": false, ""error"": ""Database connection failed""}"
Response.End
End If
' Configuration
Const VENDOR_API_URL = "http://10.48.130.113/vendor-api-proxy.php"
Const BATCH_SIZE = 10
' Variables
Dim strSQL, rsWarranties, total, updated, errors
updated = 0
errors = 0
' Find PCs without warranty - PHASE 2: Use machines table
strSQL = "SELECT machineid, hostname, serialnumber FROM machines " & _
"WHERE pctypeid IS NOT NULL " & _
"AND serialnumber IS NOT NULL AND serialnumber <> 'N/A' AND serialnumber <> '' " & _
"AND LENGTH(serialnumber) >= 5 AND isactive = 1 " & _
"AND machineid NOT IN (SELECT machineid FROM warranties WHERE enddate IS NOT NULL)"
Set rsWarranties = Server.CreateObject("ADODB.Recordset")
rsWarranties.CursorLocation = 3
rsWarranties.Open strSQL, objConn
' Check for errors
If Err.Number <> 0 Then
Response.Write "{""success"": false, ""error"": ""Query failed: " & Replace(Err.Description, """", "'") & """}"
Response.End
End If
' Check if empty
If rsWarranties.EOF Then
Response.Write "{""success"": true, ""message"": ""No devices require warranty checks"", ""total"": 0, ""updated"": 0, ""errors"": 0}"
rsWarranties.Close
objConn.Close
Response.End
End If
' Count and build arrays
total = 0
rsWarranties.MoveFirst
Do While Not rsWarranties.EOF
total = total + 1
rsWarranties.MoveNext
Loop
Dim serviceTagList(), deviceInfo()
ReDim serviceTagList(total - 1)
ReDim deviceInfo(total - 1)
rsWarranties.MoveFirst
Dim i
i = 0
Do While Not rsWarranties.EOF
serviceTagList(i) = Trim(rsWarranties("serialnumber"))
Set deviceInfo(i) = CreateObject("Scripting.Dictionary")
deviceInfo(i)("machineid") = rsWarranties("machineid")
deviceInfo(i)("hostname") = rsWarranties("hostname")
i = i + 1
rsWarranties.MoveNext
Loop
rsWarranties.Close
Set rsWarranties = Nothing
' Process in batches
Dim batchStart, batchEnd, j, batchTags, apiUrl, xmlhttp, responseText
Dim warrantyEndDate, serviceLevel, warrantyStatus
For i = 0 To total - 1 Step BATCH_SIZE
batchStart = i
batchEnd = i + BATCH_SIZE - 1
If batchEnd >= total Then batchEnd = total - 1
' Build service tag list
batchTags = ""
For j = batchStart To batchEnd
If batchTags <> "" Then batchTags = batchTags & ","
batchTags = batchTags & serviceTagList(j)
Next
' Call API
apiUrl = VENDOR_API_URL & "?vendor=dell&action=warranty-batch&servicetags=" & Server.URLEncode(batchTags)
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlhttp.setTimeouts 30000, 30000, 30000, 30000
xmlhttp.Open "GET", apiUrl, False
xmlhttp.setRequestHeader "Accept", "application/json"
xmlhttp.Send
If Err.Number = 0 Then
responseText = xmlhttp.responseText
If InStr(responseText, """success"":true") > 0 Then
For j = batchStart To batchEnd
warrantyEndDate = ExtractWarrantyData(responseText, serviceTagList(j), "warrantyEndDate")
serviceLevel = ExtractWarrantyData(responseText, serviceTagList(j), "serviceLevel")
warrantyStatus = ExtractWarrantyData(responseText, serviceTagList(j), "warrantyStatus")
If warrantyEndDate <> "" Then
' PHASE 2: Insert into warranties table
strSQL = "INSERT INTO warranties (machineid, enddate, servicelevel, lastcheckeddate) " & _
"VALUES (" & deviceInfo(j)("machineid") & ", '" & Replace(warrantyEndDate, "'", "''") & "', " & _
"'" & Replace(Left(serviceLevel, 100), "'", "''") & "', NOW()) " & _
"ON DUPLICATE KEY UPDATE enddate = VALUES(enddate), servicelevel = VALUES(servicelevel), lastcheckeddate = NOW()"
objConn.Execute strSQL
If Err.Number = 0 Then
updated = updated + 1
Else
errors = errors + 1
Err.Clear
End If
Else
errors = errors + 1
End If
Next
Else
errors = errors + (batchEnd - batchStart + 1)
End If
Else
errors = errors + (batchEnd - batchStart + 1)
Err.Clear
End If
Set xmlhttp = Nothing
Next
' Return response
Response.Write "{""success"": true, ""total"": " & total & ", ""updated"": " & updated & ", ""errors"": " & errors & "}"
objConn.Close
' Extract warranty data from JSON
Function ExtractWarrantyData(jsonText, serviceTag, fieldName)
Dim pattern, startPos, endPos, value, fieldPattern
pattern = """serviceTag"":""" & serviceTag & """"
startPos = InStr(jsonText, pattern)
If startPos > 0 Then
fieldPattern = """" & fieldName & """:"""
startPos = InStr(startPos, jsonText, fieldPattern)
If startPos > 0 Then
startPos = startPos + Len(fieldPattern)
endPos = InStr(startPos, jsonText, """")
If endPos > startPos Then
ExtractWarrantyData = Mid(jsonText, startPos, endPos - startPos)
Exit Function
End If
End If
End If
ExtractWarrantyData = ""
End Function
%>

View File

@@ -1,222 +0,0 @@
<%@ Language=VBScript %>
<%
' ========================================================================
' Check All Warranties - Batch Process
' This page checks all PCs without warranty information against Dell API
' ========================================================================
On Error Resume Next
Response.Buffer = True
Response.ContentType = "application/json"
%>
<!--#include file="./includes/sql.asp"-->
<%
If Err.Number <> 0 Then
Response.Write "{""success"": false, ""error"": ""Database include error: " & Replace(Err.Description, """", "'") & """}"
Response.End
End If
' Configuration
Const VENDOR_API_URL = "http://10.48.130.113/vendor-api-proxy.php"
Const BATCH_SIZE = 10 ' Process 10 at a time
Dim strSQL
Dim serviceTags, serialNumber
Dim warrantyData, warrantyResults
Dim updated, errors, total
Dim response
Dim rsWarranties ' Create our own recordset object
' Note: objConn is declared in sql.asp include
' Initialize counters
updated = 0
errors = 0
' Find all PCs without warranty information - PHASE 2: Use machines table
strSQL = "SELECT machineid, hostname, serialnumber " & _
"FROM machines " & _
"WHERE pctypeid IS NOT NULL " & _
"AND serialnumber IS NOT NULL " & _
"AND serialnumber <> 'N/A' " & _
"AND serialnumber <> '' " & _
"AND LENGTH(serialnumber) >= 5 " & _
"AND isactive = 1 " & _
"AND machineid NOT IN (SELECT machineid FROM warranties WHERE enddate IS NOT NULL)"
' Create and open recordset with cursor to support MoveFirst
Set rsWarranties = Server.CreateObject("ADODB.Recordset")
If Err.Number <> 0 Then
Response.Write "{""success"": false, ""error"": ""Failed to create recordset: " & Replace(Err.Description, """", "'") & """}"
Response.End
End If
rsWarranties.CursorLocation = 3 ' adUseClient
rsWarranties.Open strSQL, objConn
If Err.Number <> 0 Then
Response.Write "{""success"": false, ""error"": ""Failed to open recordset: " & Replace(Err.Description, """", "'") & """}"
Response.End
End If
' Check if we have any records
If rsWarranties.EOF Then
' No devices need warranty checks
Response.Write "{""success"": true, ""message"": ""No devices require warranty checks"", ""total"": 0, ""updated"": 0, ""errors"": 0}"
rsWarranties.Close
objConn.Close
Response.End
End If
' Count total records
Dim serviceTagList()
Dim deviceInfo()
Dim count
count = 0
Do While Not rsWarranties.EOF
count = count + 1
rsWarranties.MoveNext
Loop
total = count
' Reset to beginning
rsWarranties.MoveFirst
' Build arrays
ReDim serviceTagList(total - 1)
ReDim deviceInfo(total - 1)
count = 0
Do While Not rsWarranties.EOF
serialNumber = Trim(rsWarranties("serialnumber"))
serviceTagList(count) = serialNumber
Set deviceInfo(count) = CreateObject("Scripting.Dictionary")
deviceInfo(count)("machineid") = rsWarranties("machineid")
deviceInfo(count)("hostname") = rsWarranties("hostname")
deviceInfo(count)("serialnumber") = serialNumber
count = count + 1
rsWarranties.MoveNext
Loop
rsWarranties.Close
Set rsWarranties = Nothing
' Process in batches
Dim i, batchStart, batchEnd, batchTags
Dim batchTagsStr, apiUrl, xmlhttp
Dim responseText, json
For i = 0 To total - 1 Step BATCH_SIZE
batchStart = i
batchEnd = i + BATCH_SIZE - 1
If batchEnd >= total Then
batchEnd = total - 1
End If
' Build batch of service tags
batchTagsStr = ""
Dim j
For j = batchStart To batchEnd
If batchTagsStr <> "" Then
batchTagsStr = batchTagsStr & ","
End If
batchTagsStr = batchTagsStr & serviceTagList(j)
Next
' Call vendor API
apiUrl = VENDOR_API_URL & "?vendor=dell&action=warranty-batch&servicetags=" & Server.URLEncode(batchTagsStr)
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
xmlhttp.setTimeouts 30000, 30000, 30000, 30000 ' 30 second timeout
On Error Resume Next
xmlhttp.Open "GET", apiUrl, False
xmlhttp.setRequestHeader "Accept", "application/json"
xmlhttp.Send
If Err.Number <> 0 Then
errors = errors + (batchEnd - batchStart + 1)
Err.Clear
Else
responseText = xmlhttp.responseText
' Parse JSON response (simplified - for production use proper JSON parser)
' For now, we'll extract warranty data using string parsing
If InStr(responseText, """success"":true") > 0 Then
' Process each warranty in batch
For j = batchStart To batchEnd
serialNumber = serviceTagList(j)
' Extract warranty data for this serial (simplified extraction)
Dim warrantyEndDate, serviceLevel, warrantyStatus
warrantyEndDate = ExtractWarrantyData(responseText, serialNumber, "warrantyEndDate")
serviceLevel = ExtractWarrantyData(responseText, serialNumber, "serviceLevel")
warrantyStatus = ExtractWarrantyData(responseText, serialNumber, "warrantyStatus")
If warrantyEndDate <> "" Then
' Update database - PHASE 2: Insert into warranties table
strSQL = "INSERT INTO warranties (machineid, enddate, servicelevel, lastcheckeddate) " & _
"VALUES (" & deviceInfo(j)("machineid") & ", '" & Replace(warrantyEndDate, "'", "''") & "', " & _
"'" & Replace(Left(serviceLevel, 100), "'", "''") & "', NOW()) " & _
"ON DUPLICATE KEY UPDATE enddate = VALUES(enddate), servicelevel = VALUES(servicelevel), lastcheckeddate = NOW()"
On Error Resume Next
objConn.Execute strSQL
If Err.Number = 0 Then
updated = updated + 1
Else
errors = errors + 1
Err.Clear
End If
On Error Goto 0
Else
errors = errors + 1
End If
Next
Else
errors = errors + (batchEnd - batchStart + 1)
End If
End If
On Error Goto 0
Set xmlhttp = Nothing
' Small delay between batches - ASP doesn't support WScript.Sleep
' Instead, we'll just continue without delay since batches are small
' If batchEnd < total - 1 Then
' ' No sleep available in ASP
' End If
Next
' Return response
Response.Write "{""success"": true, ""total"": " & total & ", ""updated"": " & updated & ", ""errors"": " & errors & ", ""message"": ""Updated " & updated & " of " & total & " warranty records""}"
objConn.Close
' Helper function to extract warranty data from JSON
Function ExtractWarrantyData(jsonText, serviceTag, fieldName)
Dim pattern, startPos, endPos, value
pattern = """serviceTag"":""" & serviceTag & """"
startPos = InStr(jsonText, pattern)
If startPos > 0 Then
' Find the field within this warranty object
Dim fieldPattern
fieldPattern = """" & fieldName & """:"""
startPos = InStr(startPos, jsonText, fieldPattern)
If startPos > 0 Then
startPos = startPos + Len(fieldPattern)
endPos = InStr(startPos, jsonText, """")
If endPos > startPos Then
value = Mid(jsonText, startPos, endPos - startPos)
ExtractWarrantyData = value
Exit Function
End If
End If
End If
ExtractWarrantyData = ""
End Function
%>

288
checkin_usb.asp Normal file
View File

@@ -0,0 +1,288 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
' Check if serial was passed in URL (from displayusb.asp)
Dim prefilledSerial
prefilledSerial = Trim(Request.QueryString("serial"))
%>
<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-lg-8 offset-lg-2">
<div class="card">
<div class="card-body">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h5 class="card-title" style="margin:0;">
<i class="zmdi zmdi-arrow-left"></i> USB Check-in
</h5>
<a href="./displayusb.asp" class="btn btn-sm btn-secondary">
<i class="zmdi zmdi-arrow-left"></i> Back to USB Devices
</a>
</div>
<%
' Check for error messages
Dim errorType, errorMsg
errorType = Request.QueryString("error")
errorMsg = Request.QueryString("msg")
If errorType <> "" Then
Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>Error!</strong> " & Server.HTMLEncode(errorMsg) & "</div>")
End If
%>
<!-- Step 1: Scan USB -->
<div id="step1">
<div class="alert alert-info">
<i class="zmdi zmdi-info"></i> <strong>Step 1:</strong> Scan or enter the USB serial number to check in
</div>
<div class="form-group">
<label for="serialnumber">USB Serial Number</label>
<input
type="text"
class="form-control form-control-lg"
id="serialnumber"
placeholder="Scan barcode or type serial number..."
autocomplete="off"
autofocus
value="<%=Server.HTMLEncode(prefilledSerial)%>"
style="font-size: 24px; text-align: center; padding: 20px; font-family: monospace; letter-spacing: 2px;">
</div>
<div class="text-center">
<button type="button" id="lookupBtn" class="btn btn-primary btn-lg">
<i class="zmdi zmdi-search"></i> Look Up USB
</button>
</div>
</div>
<!-- Step 2: USB Details and Check-in Form -->
<div id="step2" style="display:none;">
<div class="alert alert-warning">
<i class="zmdi zmdi-alert-triangle"></i> <strong>USB Found!</strong> Please confirm the USB has been wiped before check-in.
</div>
<div class="card bg-light mb-3">
<div class="card-body">
<h6 class="card-subtitle mb-2 text-muted">Checkout Details</h6>
<table class="table table-sm mb-0">
<tr><th style="width:150px;">Serial Number:</th><td id="usbSerial" class="font-weight-bold"></td></tr>
<tr><th>Name:</th><td id="usbName"></td></tr>
<tr><th>Business Unit:</th><td id="usbBU"></td></tr>
<tr><th>Checked Out By:</th><td id="usbSSO" class="font-weight-bold text-primary"></td></tr>
<tr><th>Checkout Time:</th><td id="usbCheckoutTime"></td></tr>
<tr><th>Duration:</th><td id="usbDuration"></td></tr>
<tr><th>Reason:</th><td id="usbReason"></td></tr>
</table>
</div>
</div>
<form id="checkinForm" method="post" action="./savecheckin_usb.asp">
<input type="hidden" id="checkoutid" name="checkoutid" value="">
<div class="form-group">
<div class="alert alert-danger" style="padding:15px;">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="waswiped" name="waswiped" value="1" required>
<label class="custom-control-label" for="waswiped" style="font-size:16px; font-weight:bold;">
<i class="zmdi zmdi-shield-check"></i> I confirm this USB has been WIPED/FORMATTED before returning
</label>
</div>
<small class="text-dark mt-2 d-block">This is required for security. USB devices must be wiped before being returned to the locker.</small>
</div>
</div>
<div class="form-group">
<label for="notes">Check-in Notes (optional)</label>
<textarea
class="form-control"
id="notes"
name="notes"
rows="2"
placeholder="Any notes about the USB or its use..."></textarea>
</div>
<div class="text-center" style="margin-top:20px;">
<button type="button" id="backBtn" class="btn btn-secondary btn-lg">
<i class="zmdi zmdi-arrow-left"></i> Back
</button>
<button type="submit" class="btn btn-success btn-lg" id="submitBtn" disabled>
<i class="zmdi zmdi-check"></i> Complete Check-in
</button>
</div>
</form>
</div>
<!-- Loading indicator -->
<div id="loadingArea" style="display:none; text-align:center; padding:40px;">
<div class="spinner-border text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
<p class="mt-3 text-muted">Looking up USB device...</p>
</div>
<!-- Error state -->
<div id="errorArea" style="display:none;">
<div class="alert alert-danger" id="errorMessage"></div>
<div class="text-center">
<button type="button" id="retryBtn" class="btn btn-primary">
<i class="zmdi zmdi-refresh"></i> Try Again
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container"><div class="text-center"></div></div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
<script>
$(document).ready(function() {
// Auto-focus on serial input
$('#serialnumber').focus();
// If prefilled serial, auto-lookup
var prefilled = $('#serialnumber').val().trim();
if (prefilled.length >= 3) {
setTimeout(function() {
lookupUSB(prefilled);
}, 500);
}
// Lookup button click
$('#lookupBtn').on('click', function() {
var serial = $('#serialnumber').val().trim();
if (serial.length < 3) {
alert('Please enter at least 3 characters');
$('#serialnumber').focus();
return;
}
lookupUSB(serial);
});
// Enter key in serial field
$('#serialnumber').on('keypress', function(e) {
if (e.which === 13) {
e.preventDefault();
$('#lookupBtn').click();
}
});
// Back button
$('#backBtn').on('click', function() {
$('#step2').hide();
$('#step1').show();
$('#serialnumber').focus();
});
// Retry button
$('#retryBtn').on('click', function() {
$('#errorArea').hide();
$('#step1').show();
$('#serialnumber').val('').focus();
});
// Enable/disable submit based on checkbox
$('#waswiped').on('change', function() {
if ($(this).is(':checked')) {
$('#submitBtn').prop('disabled', false);
} else {
$('#submitBtn').prop('disabled', true);
}
});
// Form validation
$('#checkinForm').on('submit', function(e) {
if (!$('#waswiped').is(':checked')) {
e.preventDefault();
alert('You must confirm the USB has been wiped before check-in.');
return false;
}
});
function lookupUSB(serial) {
$('#step1').hide();
$('#loadingArea').show();
$.ajax({
url: './api_usb.asp',
method: 'GET',
data: { action: 'checkin_lookup', serial: serial },
dataType: 'json',
success: function(data) {
$('#loadingArea').hide();
if (data.success) {
// Found checked-out USB - show check-in form
$('#usbSerial').text(data.serialnumber);
$('#usbName').text(data.alias || '-');
$('#usbBU').text(data.businessunit || '-');
$('#usbSSO').text(data.sso);
$('#usbCheckoutTime').text(data.checkout_time || '-');
$('#usbDuration').text(data.duration || '-');
$('#usbReason').text(data.checkout_reason || '-');
$('#checkoutid').val(data.checkoutid);
// Reset checkbox and button
$('#waswiped').prop('checked', false);
$('#submitBtn').prop('disabled', true);
$('#step2').show();
} else {
var errorHtml = '<strong>' + (data.error || 'Error looking up USB') + '</strong>';
if (data.error && data.error.indexOf('not currently checked out') >= 0) {
errorHtml += '<br><br>To checkout this USB, use <a href="./checkout_usb.asp?serial=' + encodeURIComponent(serial) + '">Checkout</a>.';
}
$('#errorMessage').html(errorHtml);
$('#errorArea').show();
}
},
error: function() {
$('#loadingArea').hide();
$('#errorMessage').html('<strong>Error connecting to server. Please try again.</strong>');
$('#errorArea').show();
}
});
}
});
</script>
</body>
</html>

283
checkout_usb.asp Normal file
View File

@@ -0,0 +1,283 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
' Check if serial was passed in URL (from displayusb.asp)
Dim prefilledSerial
prefilledSerial = Trim(Request.QueryString("serial"))
%>
<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-lg-8 offset-lg-2">
<div class="card">
<div class="card-body">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h5 class="card-title" style="margin:0;">
<i class="zmdi zmdi-arrow-right"></i> USB Checkout
</h5>
<a href="./displayusb.asp" class="btn btn-sm btn-secondary">
<i class="zmdi zmdi-arrow-left"></i> Back to USB Devices
</a>
</div>
<%
' Check for error messages
Dim errorType, errorMsg
errorType = Request.QueryString("error")
errorMsg = Request.QueryString("msg")
If errorType <> "" Then
Response.Write("<div class='alert alert-danger alert-dismissible fade show' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>Error!</strong> " & Server.HTMLEncode(errorMsg) & "</div>")
End If
%>
<!-- Step 1: Scan USB -->
<div id="step1">
<div class="alert alert-info">
<i class="zmdi zmdi-info"></i> <strong>Step 1:</strong> Scan or enter the USB serial number
</div>
<div class="form-group">
<label for="serialnumber">USB Serial Number</label>
<input
type="text"
class="form-control form-control-lg"
id="serialnumber"
placeholder="Scan barcode or type serial number..."
autocomplete="off"
autofocus
value="<%=Server.HTMLEncode(prefilledSerial)%>"
style="font-size: 24px; text-align: center; padding: 20px; font-family: monospace; letter-spacing: 2px;">
</div>
<div class="text-center">
<button type="button" id="lookupBtn" class="btn btn-primary btn-lg">
<i class="zmdi zmdi-search"></i> Look Up USB
</button>
</div>
</div>
<!-- Step 2: USB Details and Checkout Form -->
<div id="step2" style="display:none;">
<div class="alert alert-success">
<i class="zmdi zmdi-check"></i> <strong>USB Found!</strong> Review details and complete checkout.
</div>
<div class="card bg-light mb-3">
<div class="card-body">
<h6 class="card-subtitle mb-2 text-muted">USB Device Details</h6>
<table class="table table-sm mb-0">
<tr><th style="width:150px;">Serial Number:</th><td id="usbSerial" class="font-weight-bold"></td></tr>
<tr><th>Name:</th><td id="usbName"></td></tr>
<tr><th>Business Unit:</th><td id="usbBU"></td></tr>
<tr><th>Last Checkout:</th><td id="usbLastCheckout"></td></tr>
</table>
</div>
</div>
<form id="checkoutForm" method="post" action="./savecheckout_usb.asp">
<input type="hidden" id="machineid" name="machineid" value="">
<div class="form-group">
<label for="sso"><strong>Your SSO Number</strong> <span class="text-danger">*</span></label>
<input
type="text"
class="form-control"
id="sso"
name="sso"
placeholder="Enter your 9-digit SSO..."
maxlength="9"
pattern="[0-9]{9}"
required
style="font-size: 18px; font-family: monospace; letter-spacing: 2px;">
<small class="form-text text-muted">9-digit SSO number (e.g., 570005354)</small>
</div>
<div class="form-group">
<label for="reason"><strong>Reason for Checkout</strong></label>
<textarea
class="form-control"
id="reason"
name="reason"
rows="3"
placeholder="What will you use this USB for? (optional but recommended)"></textarea>
</div>
<div class="text-center" style="margin-top:20px;">
<button type="button" id="backBtn" class="btn btn-secondary btn-lg">
<i class="zmdi zmdi-arrow-left"></i> Back
</button>
<button type="submit" class="btn btn-success btn-lg">
<i class="zmdi zmdi-check"></i> Complete Checkout
</button>
</div>
</form>
</div>
<!-- Loading indicator -->
<div id="loadingArea" style="display:none; text-align:center; padding:40px;">
<div class="spinner-border text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
<p class="mt-3 text-muted">Looking up USB device...</p>
</div>
<!-- Error state -->
<div id="errorArea" style="display:none;">
<div class="alert alert-danger" id="errorMessage"></div>
<div class="text-center">
<button type="button" id="retryBtn" class="btn btn-primary">
<i class="zmdi zmdi-refresh"></i> Try Again
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container"><div class="text-center"></div></div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
<script>
$(document).ready(function() {
// Auto-focus on serial input
$('#serialnumber').focus();
// If prefilled serial, auto-lookup
var prefilled = $('#serialnumber').val().trim();
if (prefilled.length >= 3) {
setTimeout(function() {
lookupUSB(prefilled);
}, 500);
}
// Lookup button click
$('#lookupBtn').on('click', function() {
var serial = $('#serialnumber').val().trim();
if (serial.length < 3) {
alert('Please enter at least 3 characters');
$('#serialnumber').focus();
return;
}
lookupUSB(serial);
});
// Enter key in serial field
$('#serialnumber').on('keypress', function(e) {
if (e.which === 13) {
e.preventDefault();
$('#lookupBtn').click();
}
});
// Back button
$('#backBtn').on('click', function() {
$('#step2').hide();
$('#step1').show();
$('#serialnumber').focus();
});
// Retry button
$('#retryBtn').on('click', function() {
$('#errorArea').hide();
$('#step1').show();
$('#serialnumber').val('').focus();
});
// SSO validation
$('#sso').on('input', function() {
this.value = this.value.replace(/[^0-9]/g, '').substring(0, 9);
});
// Form validation
$('#checkoutForm').on('submit', function(e) {
var sso = $('#sso').val().trim();
if (sso.length !== 9 || !/^\d{9}$/.test(sso)) {
e.preventDefault();
alert('SSO must be exactly 9 digits');
$('#sso').focus();
return false;
}
});
function lookupUSB(serial) {
$('#step1').hide();
$('#loadingArea').show();
$.ajax({
url: './api_usb.asp',
method: 'GET',
data: { action: 'lookup', serial: serial },
dataType: 'json',
success: function(data) {
$('#loadingArea').hide();
if (data.success) {
if (data.status === 'checked_out') {
$('#errorMessage').html('<strong>USB is currently checked out!</strong><br>' +
'Checked out by: ' + data.current_holder + '<br>' +
'Since: ' + data.checkout_time + '<br><br>' +
'Please use <a href="./checkin_usb.asp?serial=' + encodeURIComponent(serial) + '">Check-in</a> first.');
$('#errorArea').show();
} else {
// Available - show checkout form
$('#usbSerial').text(data.serialnumber);
$('#usbName').text(data.alias || '-');
$('#usbBU').text(data.businessunit || '-');
$('#usbLastCheckout').text(data.last_checkout || 'Never');
$('#machineid').val(data.machineid);
$('#step2').show();
$('#sso').focus();
}
} else {
$('#errorMessage').html('<strong>' + (data.error || 'USB not found') + '</strong>');
$('#errorArea').show();
}
},
error: function() {
$('#loadingArea').hide();
$('#errorMessage').html('<strong>Error connecting to server. Please try again.</strong>');
$('#errorArea').show();
}
});
}
});
</script>
</body>
</html>

View File

@@ -133,7 +133,7 @@ Set rsStatus = Nothing
"LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _ "LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _
"LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _ "LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _
"LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _ "LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _
"WHERE m.isactive = 1 AND m.pctypeid IS NOT NULL " "WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Apply filters ' Apply filters
whereClause = "" whereClause = ""
@@ -162,7 +162,7 @@ Set rsStatus = Nothing
while not rs.eof while not rs.eof
%> %>
<td><a href="./displaypc.asp?pcid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><% <td><a href="./displaypc.asp?machineid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><%
Dim displayName Dim displayName
If IsNull(rs("hostname")) Or rs("hostname") = "" Then If IsNull(rs("hostname")) Or rs("hostname") = "" Then
displayName = rs("serialnumber") displayName = rs("serialnumber")

View File

@@ -1,44 +0,0 @@
<!--#include file="includes/db_helpers.asp"-->
<%
Response.ContentType = "text/html"
Dim objConn, rs, sql, appid, appName
appid = 8
appName = "eMX"
Set objConn = GetDatabaseConnection()
sql = "SELECT linkid, shortdescription, clicks, appid, " & _
"CASE WHEN appid = " & appid & " THEN 1 ELSE 0 END as direct_link " & _
"FROM knowledgebase " & _
"WHERE isactive = 1 " & _
"AND (appid = " & appid & " " & _
" OR keywords LIKE '%" & Replace(appName, "'", "''") & "%' " & _
" OR shortdescription LIKE '%" & Replace(appName, "'", "''") & "%') " & _
"ORDER BY direct_link DESC, clicks + 0 DESC, shortdescription ASC"
Response.Write("<h3>SQL Query:</h3>")
Response.Write("<pre>" & Server.HTMLEncode(sql) & "</pre>")
Response.Write("<h3>Results:</h3>")
Response.Write("<table border='1' cellpadding='5'>")
Response.Write("<tr><th>LinkID</th><th>Description</th><th>Clicks</th><th>AppID</th><th>Direct Link</th></tr>")
Set rs = objConn.Execute(sql)
While Not rs.EOF
Response.Write("<tr>")
Response.Write("<td>" & rs("linkid") & "</td>")
Response.Write("<td>" & Server.HTMLEncode(rs("shortdescription")) & "</td>")
Response.Write("<td>" & rs("clicks") & "</td>")
Response.Write("<td>" & rs("appid") & "</td>")
Response.Write("<td>" & rs("direct_link") & "</td>")
Response.Write("</tr>")
rs.MoveNext
Wend
Response.Write("</table>")
rs.Close
objConn.Close
%>

View File

@@ -139,10 +139,11 @@
<option value="">-- Select Model --</option> <option value="">-- Select Model --</option>
<% <%
Dim strSQL2, rsModels Dim strSQL2, rsModels
' Filter models to only show Access Point models (machinetypeid = 16)
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _ strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _ "FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _ "INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _ "WHERE m.isactive = 1 AND m.machinetypeid = 16 " & _
"ORDER BY v.vendor, m.modelnumber" "ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2) Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF Do While Not rsModels.EOF
@@ -230,6 +231,24 @@
</button> </button>
</div> </div>
<div class="form-group">
<label for="newmodelmachinetypeid">Machine Type <span class="text-danger">*</span></label>
<select class="form-control" id="newmodelmachinetypeid" name="newmodelmachinetypeid">
<option value="">-- Select Machine Type --</option>
<%
Dim rsMachineTypes
strSQL3 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
Set rsMachineTypes = objConn.Execute(strSQL3)
While Not rsMachineTypes.EOF
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
rsMachineTypes.MoveNext
Wend
rsMachineTypes.Close
Set rsMachineTypes = Nothing
%>
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="newmodelnotes">Model Notes</label> <label for="newmodelnotes">Model Notes</label>
<textarea class="form-control" id="newmodelnotes" name="newmodelnotes" <textarea class="form-control" id="newmodelnotes" name="newmodelnotes"

View File

@@ -232,10 +232,11 @@
<option value="">-- Select Model --</option> <option value="">-- Select Model --</option>
<% <%
Dim strSQL3, rsModels Dim strSQL3, rsModels
' Filter models to only show Camera models (machinetypeid = 18)
strSQL3 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _ strSQL3 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _ "FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _ "INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _ "WHERE m.isactive = 1 AND m.machinetypeid = 18 " & _
"ORDER BY v.vendor, m.modelnumber" "ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL3) Set rsModels = objConn.Execute(strSQL3)
Do While Not rsModels.EOF Do While Not rsModels.EOF
@@ -323,6 +324,24 @@
</button> </button>
</div> </div>
<div class="form-group">
<label for="newmodelmachinetypeid">Machine Type <span class="text-danger">*</span></label>
<select class="form-control" id="newmodelmachinetypeid" name="newmodelmachinetypeid">
<option value="">-- Select Machine Type --</option>
<%
Dim rsMachineTypes
strSQL2 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
Set rsMachineTypes = objConn.Execute(strSQL2)
While Not rsMachineTypes.EOF
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
rsMachineTypes.MoveNext
Wend
rsMachineTypes.Close
Set rsMachineTypes = Nothing
%>
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="newmodelnotes">Model Notes</label> <label for="newmodelnotes">Model Notes</label>
<textarea class="form-control" id="newmodelnotes" name="newmodelnotes" <textarea class="form-control" id="newmodelnotes" name="newmodelnotes"

View File

@@ -28,7 +28,7 @@
strSQL = "SELECT mac.machineid, mac.alias AS idfname, mac.machinenotes AS description, " & _ strSQL = "SELECT mac.machineid, mac.alias AS idfname, mac.machinenotes AS description, " & _
"mac.maptop, mac.mapleft, mac.isactive " & _ "mac.maptop, mac.mapleft, mac.isactive " & _
"FROM machines mac " & _ "FROM machines mac " & _
"WHERE mac.machineid = " & idfid & " AND mac.machinetypeid = 34" "WHERE mac.machineid = " & idfid & " AND mac.machinetypeid = 17"
Set rs = objConn.Execute(strSQL) Set rs = objConn.Execute(strSQL)
If rs.EOF Then If rs.EOF Then

View File

@@ -135,10 +135,11 @@
<option value="">-- Select Model --</option> <option value="">-- Select Model --</option>
<% <%
Dim strSQL2, rsModels Dim strSQL2, rsModels
' Filter models to only show Server models (machinetypeid = 20)
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _ strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _ "FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _ "INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _ "WHERE m.isactive = 1 AND m.machinetypeid = 20 " & _
"ORDER BY v.vendor, m.modelnumber" "ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2) Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF Do While Not rsModels.EOF
@@ -226,6 +227,24 @@
</button> </button>
</div> </div>
<div class="form-group">
<label for="newmodelmachinetypeid">Machine Type <span class="text-danger">*</span></label>
<select class="form-control" id="newmodelmachinetypeid" name="newmodelmachinetypeid">
<option value="">-- Select Machine Type --</option>
<%
Dim rsMachineTypes
strSQL3 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
Set rsMachineTypes = objConn.Execute(strSQL3)
While Not rsMachineTypes.EOF
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
rsMachineTypes.MoveNext
Wend
rsMachineTypes.Close
Set rsMachineTypes = Nothing
%>
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="newmodelnotes">Model Notes</label> <label for="newmodelnotes">Model Notes</label>
<textarea class="form-control" id="newmodelnotes" name="newmodelnotes" <textarea class="form-control" id="newmodelnotes" name="newmodelnotes"

View File

@@ -135,10 +135,11 @@
<option value="">-- Select Model --</option> <option value="">-- Select Model --</option>
<% <%
Dim strSQL2, rsModels Dim strSQL2, rsModels
' Filter models to only show Switch models (machinetypeid = 19)
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _ strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _ "FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _ "INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _ "WHERE m.isactive = 1 AND m.machinetypeid = 19 " & _
"ORDER BY v.vendor, m.modelnumber" "ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2) Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF Do While Not rsModels.EOF
@@ -226,6 +227,24 @@
</button> </button>
</div> </div>
<div class="form-group">
<label for="newmodelmachinetypeid">Machine Type <span class="text-danger">*</span></label>
<select class="form-control" id="newmodelmachinetypeid" name="newmodelmachinetypeid">
<option value="">-- Select Machine Type --</option>
<%
Dim rsMachineTypes
strSQL2 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
Set rsMachineTypes = objConn.Execute(strSQL2)
While Not rsMachineTypes.EOF
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
rsMachineTypes.MoveNext
Wend
rsMachineTypes.Close
Set rsMachineTypes = Nothing
%>
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="newmodelnotes">Model Notes</label> <label for="newmodelnotes">Model Notes</label>
<textarea class="form-control" id="newmodelnotes" name="newmodelnotes" <textarea class="form-control" id="newmodelnotes" name="newmodelnotes"

View File

@@ -1,677 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim apid
apid = Request.Querystring("id")
If Not IsNumeric(apid) Then
Response.Redirect("network_devices.asp?filter=Access Point")
Response.End
End If
strSQL = "SELECT s.*, m.modelnumber, v.vendor " & _
"FROM accesspoints s " & _
"LEFT JOIN models m ON s.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE s.apid = " & CLng(apid)
set rs = objconn.Execute(strSQL)
If rs.EOF Then
Response.Write("Access Point not found")
objConn.Close
Response.End
End If
%>
<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-lg-4">
<div class="card profile-card-2">
<div class="card-img-block">
<img class="img-fluid" src="./images/devices/accesspoint.png" alt="Access Point">
</div>
<div class="card-body pt-5">
<img src="./images/devices/accesspoint.png" alt="Access Point" class="profile">
<h5 class="card-title"><%Response.Write(Server.HTMLEncode(rs("apname")))%></h5>
<p class="card-text">
<%
If Not IsNull(rs("vendor")) And Not IsNull(rs("modelnumber")) Then
Response.Write(Server.HTMLEncode(rs("vendor") & " " & rs("modelnumber")))
Else
Response.Write("Access Point")
End If
%>
</p>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified">
<li class="nav-item">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-wrench"></i> <span class="hidden-xs">Settings</span></a>
</li>
<li class="nav-item">
<a href="javascript:void();" data-target="#edit" data-toggle="pill" class="nav-link"><i class="icon-note"></i> <span class="hidden-xs">Edit</span></a>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Configuration</h5>
<div class="row">
<div class="col-md-3">
<p class="mb-2"><strong>Name:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p>
<p class="mb-2"><strong>Serial:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>Description:</strong></p>
<p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
</div>
<div class="col-md-9">
<p class="mb-2"><%Response.Write(Server.HTMLEncode(rs("apname")))%></p>
<p class="mb-2">
<%
If Not IsNull(rs("vendor")) And rs("vendor") <> "" Then
Response.Write(Server.HTMLEncode(rs("vendor")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("modelnumber")) And rs("modelnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("modelnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("serialnumber")) And rs("serialnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("serialnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" Then
Response.Write("<a href='http://" & Server.HTMLEncode(rs("ipaddress")) & "' target='_blank'>" & Server.HTMLEncode(rs("ipaddress")) & "</a>")
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("description")) And rs("description") <> "" Then
Response.Write(Server.HTMLEncode(rs("description")))
Else
Response.Write("<em class='text-muted'>No description</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
%>
<span class="location-link" data-apid="<%Response.Write(apid)%>" style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>View on Map
</span>
<%
Else
Response.Write("<em class='text-muted'>No location set</em>")
End If
%>
</p>
<p class="mb-2">
<%
If rs("isactive") Then
Response.Write("<span class='badge badge-success'>Active</span>")
Else
Response.Write("<span class='badge badge-secondary'>Inactive</span>")
End If
%>
</p>
</div>
</div>
<!--/row-->
</div>
<div class="tab-pane" id="edit">
<form method="post" action="./save_network_device.asp">
<input type="hidden" name="type" value="accesspoint">
<input type="hidden" name="id" value="<%=apid%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Access Point Name <span class="text-danger">*</span></label>
<div class="col-lg-9">
<input type="text" name="apname" class="form-control"
value="<%=Server.HTMLEncode(rs("apname"))%>"
required maxlength="100"
placeholder="e.g., Core-Access Point-01">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Model</label>
<div class="col-lg-9">
<div class="input-group">
<select name="modelid" id="modelid_edit" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
selected = ""
If Not IsNull(rs("modelid")) And rs("modelid") <> "" Then
If CStr(rsModels("modelnumberid")) = CStr(rs("modelid")) Then
selected = "selected"
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
<option value="new">+ Add New Model</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addModelBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">Select a model or click "New" to add one</small>
</div>
</div>
<!-- Hidden section for adding new model -->
<div id="newModelSection_edit" class="form-group row" style="display:none;">
<div class="col-lg-9 offset-lg-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Model</h6>
<div class="form-group">
<label for="newmodelnumber_edit">Model Number <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmodelnumber_edit" name="newmodelnumber"
maxlength="255" placeholder="e.g., UniFi AP-AC-Pro">
</div>
<div class="form-group">
<label for="newvendorid_edit">Vendor <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newvendorid_edit" name="newvendorid">
<option value="">-- Select Vendor --</option>
<%
Dim rsVendors
strSQL2 = "SELECT vendorid, vendor FROM vendors WHERE isactive = 1 ORDER BY vendor ASC"
Set rsVendors = objConn.Execute(strSQL2)
While Not rsVendors.EOF
Response.Write("<option value='" & rsVendors("vendorid") & "'>" & Server.HTMLEncode(rsVendors("vendor")) & "</option>")
rsVendors.MoveNext
Wend
rsVendors.Close
Set rsVendors = Nothing
%>
<option value="new">+ Add New Vendor</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addVendorBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new vendor -->
<div id="newVendorSection_edit" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Vendor</h6>
<div class="form-group">
<label for="newvendorname_edit">Vendor Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newvendorname_edit" name="newvendorname"
maxlength="50" placeholder="e.g., Ubiquiti, Cisco, Aruba">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewVendor_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelnotes_edit">Model Notes</label>
<textarea class="form-control" id="newmodelnotes_edit" name="newmodelnotes"
rows="2" maxlength="255"
placeholder="Additional notes about this model..."></textarea>
</div>
<div class="form-group">
<label for="newmodeldocpath_edit">Documentation Path</label>
<input type="text" class="form-control" id="newmodeldocpath_edit" name="newmodeldocpath"
maxlength="255" placeholder="\\server\docs\model.pdf or http://...">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewModel_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Serial Number</label>
<div class="col-lg-9">
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(rs("serialnumber"))%>"
maxlength="100" placeholder="e.g., SN123456789">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IP Address</label>
<div class="col-lg-9">
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(rs("ipaddress"))%>"
maxlength="45" pattern="^[0-9\.:]*$"
placeholder="e.g., 192.168.1.100">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Description</label>
<div class="col-lg-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes..."><%=Server.HTMLEncode(rs("description"))%></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label"></label>
<div class="col-lg-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If rs("isactive") = True Or rs("isactive") = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
</div>
</div>
<!-- Hidden coordinate fields -->
<input type="hidden" id="maptop" name="maptop" value="<%=rs("maptop")%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=rs("mapleft")%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Map Position</label>
<div class="col-lg-9">
<button type="button" class="btn btn-secondary btn-sm" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
Response.Write("Current position: X=" & rs("mapleft") & ", Y=" & rs("maptop"))
Else
Response.Write("No position set - click button to select")
End If
%>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-9 offset-lg-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<a href="network_devices.asp?filter=Access Point" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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">
</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>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<style>
.location-popup-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
}
.location-popup {
display: none;
position: fixed;
background: #2a2a2a;
border-radius: 6px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
z-index: 9999;
overflow: hidden;
border: 1px solid #444;
}
.location-popup-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #444;
}
.location-popup-close {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 0;
transition: background 0.2s;
}
.location-popup-close:hover {
background: rgba(255,255,255,0.3);
}
.location-popup-body {
padding: 0;
}
.location-popup iframe {
display: block;
border: none;
}
/* Theme-specific link colors */
body.bg-theme1 .location-link,
body.bg-theme2 .location-link,
body.bg-theme3 .location-link,
body.bg-theme4 .location-link,
body.bg-theme5 .location-link,
body.bg-theme6 .location-link { color: #007bff !important; }
body.bg-theme7 .location-link { color: #17a2b8 !important; }
body.bg-theme8 .location-link { color: #ffc107 !important; }
body.bg-theme9 .location-link { color: #6c757d !important; }
body.bg-theme10 .location-link { color: #8b6f47 !important; }
body.bg-theme11 .location-link { color: #42a5f5 !important; }
body.bg-theme12 .location-link { color: #ab47bc !important; }
body.bg-theme13 .location-link { color: #ef5350 !important; }
body.bg-theme14 .location-link { color: #66bb6a !important; }
body.bg-theme15 .location-link { color: #5c6bc0 !important; }
body.bg-theme16 .location-link { color: #9c27b0 !important; }
</style>
<script>
$(document).ready(function() {
// Create popup elements
var $overlay = $('<div class="location-popup-overlay"></div>').appendTo('body');
var $popup = $('<div class="location-popup"></div>').appendTo('body');
$popup.html(
'<div class="location-popup-header">' +
'<h6 style="margin:0; font-size:16px;"><i class="zmdi zmdi-pin"></i> <span class="location-title">Loading...</span></h6>' +
'<button class="location-popup-close" title="Close (Esc)">&times;</button>' +
'</div>' +
'<div class="location-popup-body">' +
'<iframe src="" width="440" height="340"></iframe>' +
'</div>'
);
var $iframe = $popup.find('iframe');
var $title = $popup.find('.location-title');
var currentAccess PointId = null;
// Function to show popup with smart positioning
function showLocationPopup(accesspointId, locationName, mouseEvent) {
if (currentAccess PointId === accesspointId && $popup.is(':visible')) {
return;
}
currentAccess PointId = accesspointId;
$title.text('Access Point ' + locationName);
$iframe.attr('src', './displaylocation.asp?type=accesspoint&id=' + accesspointId);
// Position popup using viewport coordinates
var popupWidth = 440;
var popupHeight = 400;
var mouseX = mouseEvent.clientX;
var mouseY = mouseEvent.clientY;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var left, top;
// Horizontal positioning
left = mouseX + 10;
if (left + popupWidth > windowWidth - 10) {
left = mouseX - popupWidth - 10;
}
if (left < 10) {
left = 10;
}
// Vertical positioning
top = mouseY - 50;
if (top + popupHeight > windowHeight - 10) {
top = windowHeight - popupHeight - 10;
}
if (top < 10) {
top = 10;
}
$popup.css({
left: left + 'px',
top: top + 'px',
display: 'block'
});
$overlay.fadeIn(200);
$popup.fadeIn(200);
}
function hideLocationPopup() {
$overlay.fadeOut(200);
$popup.fadeOut(200);
setTimeout(function() {
$iframe.attr('src', '');
currentAccess PointId = null;
}, 200);
}
var hoverTimer = null;
$('.location-link').on('mouseenter', function(e) {
var $link = $(this);
var accesspointId = $link.data('apid');
var locationName = $link.text().trim();
var mouseEvent = e;
if (hoverTimer) {
clearTimeout(hoverTimer);
}
hoverTimer = setTimeout(function() {
showLocationPopup(accesspointId, locationName, mouseEvent);
}, 300);
});
$('.location-link').on('mouseleave', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$overlay.on('click', hideLocationPopup);
$('.location-popup-close').on('click', hideLocationPopup);
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $popup.is(':visible')) {
hideLocationPopup();
}
});
$popup.on('mouseenter', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$popup.on('mouseleave', function() {
hideLocationPopup();
});
// Model/Vendor nested add functionality for Edit tab
$('#addModelBtn_edit, #modelid_edit').on('change click', function() {
if ($('#modelid_edit').val() === 'new' || $(this).attr('id') === 'addModelBtn_edit') {
$('#modelid_edit').val('new');
$('#newModelSection_edit').slideDown();
$('#newmodelnumber_edit').prop('required', true);
$('#newvendorid_edit').prop('required', true);
}
});
$('#cancelNewModel_edit').on('click', function() {
$('#newModelSection_edit').slideUp();
$('#newVendorSection_edit').slideUp();
$('#modelid_edit').val('');
$('#newmodelnumber_edit').val('').prop('required', false);
$('#newvendorid_edit').val('').prop('required', false);
$('#newmodelnotes_edit').val('');
$('#newmodeldocpath_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Show/hide new vendor section for Edit tab
$('#addVendorBtn_edit, #newvendorid_edit').on('change click', function() {
if ($('#newvendorid_edit').val() === 'new' || $(this).attr('id') === 'addVendorBtn_edit') {
$('#newvendorid_edit').val('new');
$('#newVendorSection_edit').slideDown();
$('#newvendorname_edit').prop('required', true);
}
});
$('#cancelNewVendor_edit').on('click', function() {
$('#newVendorSection_edit').slideUp();
$('#newvendorid_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Form validation for Edit tab
$('form').on('submit', function(e) {
if ($('#modelid_edit').val() === 'new') {
if ($('#newmodelnumber_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a model number or select an existing model');
$('#newmodelnumber_edit').focus();
return false;
}
if ($('#newvendorid_edit').val() === '' || $('#newvendorid_edit').val() === 'new') {
if ($('#newvendorid_edit').val() === 'new') {
if ($('#newvendorname_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a vendor name or select an existing vendor');
$('#newvendorname_edit').focus();
return false;
}
} else {
e.preventDefault();
alert('Please select a vendor or add a new one');
$('#newvendorid_edit').focus();
return false;
}
}
}
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
rs.Close
Set rs = Nothing
objConn.Close
%>

View File

@@ -1,786 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim cameraid
cameraid = Request.Querystring("id")
If Not IsNumeric(cameraid) Then
Response.Redirect("network_devices.asp?filter=Camera")
Response.End
End If
strSQL = "SELECT s.*, m.modelnumber, v.vendor, i.idfname " & _
"FROM cameras s " & _
"LEFT JOIN models m ON s.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"LEFT JOIN idfs i ON s.idfid = i.idfid " & _
"WHERE s.cameraid = " & CLng(cameraid)
set rs = objconn.Execute(strSQL)
If rs.EOF Then
Response.Write("Camera not found")
objConn.Close
Response.End
End If
%>
<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-lg-4">
<div class="card profile-card-2">
<div class="card-img-block">
<img class="img-fluid" src="./images/devices/camera.png" alt="Camera">
</div>
<div class="card-body pt-5">
<img src="./images/devices/camera.png" alt="Camera" class="profile">
<h5 class="card-title"><%Response.Write(Server.HTMLEncode(rs("cameraname")))%></h5>
<p class="card-text">
<%
If Not IsNull(rs("vendor")) And Not IsNull(rs("modelnumber")) Then
Response.Write(Server.HTMLEncode(rs("vendor") & " " & rs("modelnumber")))
Else
Response.Write("Camera")
End If
%>
</p>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified">
<li class="nav-item">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-wrench"></i> <span class="hidden-xs">Settings</span></a>
</li>
<li class="nav-item">
<a href="javascript:void();" data-target="#edit" data-toggle="pill" class="nav-link"><i class="icon-note"></i> <span class="hidden-xs">Edit</span></a>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Configuration</h5>
<div class="row">
<div class="col-md-3">
<p class="mb-2"><strong>Name:</strong></p>
<p class="mb-2"><strong>IDF:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p>
<p class="mb-2"><strong>Serial:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>Description:</strong></p>
<p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
</div>
<div class="col-md-9">
<p class="mb-2"><%Response.Write(Server.HTMLEncode(rs("cameraname")))%></p>
<p class="mb-2">
<%
If Not IsNull(rs("idfname")) And rs("idfname") <> "" Then
Response.Write(Server.HTMLEncode(rs("idfname")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("vendor")) And rs("vendor") <> "" Then
Response.Write(Server.HTMLEncode(rs("vendor")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("modelnumber")) And rs("modelnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("modelnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("serialnumber")) And rs("serialnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("serialnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" Then
Response.Write("<a href='http://" & Server.HTMLEncode(rs("ipaddress")) & "' target='_blank'>" & Server.HTMLEncode(rs("ipaddress")) & "</a>")
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("description")) And rs("description") <> "" Then
Response.Write(Server.HTMLEncode(rs("description")))
Else
Response.Write("<em class='text-muted'>No description</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
%>
<span class="location-link" data-cameraid="<%Response.Write(cameraid)%>" style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>View on Map
</span>
<%
Else
Response.Write("<em class='text-muted'>No location set</em>")
End If
%>
</p>
<p class="mb-2">
<%
If rs("isactive") Then
Response.Write("<span class='badge badge-success'>Active</span>")
Else
Response.Write("<span class='badge badge-secondary'>Inactive</span>")
End If
%>
</p>
</div>
</div>
<!--/row-->
</div>
<div class="tab-pane" id="edit">
<form method="post" action="./save_network_device.asp">
<input type="hidden" name="type" value="camera">
<input type="hidden" name="id" value="<%=cameraid%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Camera Name <span class="text-danger">*</span></label>
<div class="col-lg-9">
<input type="text" name="cameraname" class="form-control"
value="<%=Server.HTMLEncode(rs("cameraname"))%>"
required maxlength="100"
placeholder="e.g., Core-Camera-01">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IDF Location <span class="text-danger">*</span></label>
<div class="col-lg-9">
<div class="input-group">
<select name="idfid" id="idfid_edit" class="form-control" required>
<option value="">-- Select IDF --</option>
<%
Dim strSQL3, rsIdfs
strSQL3 = "SELECT idfid, idfname FROM idfs WHERE isactive = 1 ORDER BY idfname ASC"
Set rsIdfs = objConn.Execute(strSQL3)
While Not rsIdfs.EOF
Dim idfSelected
idfSelected = ""
If Not IsNull(rs("idfid")) And rs("idfid") <> "" Then
If CStr(rsIdfs("idfid")) = CStr(rs("idfid")) Then
idfSelected = "selected"
End If
End If
%>
<option value="<%=rsIdfs("idfid")%>" <%=idfSelected%>>
<%=Server.HTMLEncode(rsIdfs("idfname"))%>
</option>
<%
rsIdfs.MoveNext
Wend
rsIdfs.Close
Set rsIdfs = Nothing
%>
<option value="new">+ Add New IDF</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addIdfBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">Select the IDF where this camera is located</small>
</div>
</div>
<!-- Hidden section for adding new IDF -->
<div id="newIdfSection_edit" class="form-group row" style="display:none;">
<div class="col-lg-9 offset-lg-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New IDF</h6>
<div class="form-group">
<label for="newidfname_edit">IDF Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newidfname_edit" name="newidfname"
maxlength="50" placeholder="e.g., Main-IDF, Building A IDF">
</div>
<div class="form-group">
<label for="newidfdescription_edit">Description</label>
<textarea class="form-control" id="newidfdescription_edit" name="newidfdescription"
rows="2" maxlength="255"
placeholder="Additional notes about this IDF location..."></textarea>
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewIdf_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Model</label>
<div class="col-lg-9">
<div class="input-group">
<select name="modelid" id="modelid_edit" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
selected = ""
If Not IsNull(rs("modelid")) And rs("modelid") <> "" Then
If CStr(rsModels("modelnumberid")) = CStr(rs("modelid")) Then
selected = "selected"
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
<option value="new">+ Add New Model</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addModelBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">Select a model or click "New" to add one</small>
</div>
</div>
<!-- Hidden section for adding new model -->
<div id="newModelSection_edit" class="form-group row" style="display:none;">
<div class="col-lg-9 offset-lg-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Model</h6>
<div class="form-group">
<label for="newmodelnumber_edit">Model Number <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmodelnumber_edit" name="newmodelnumber"
maxlength="255" placeholder="e.g., Axis P3245-V">
</div>
<div class="form-group">
<label for="newvendorid_edit">Vendor <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newvendorid_edit" name="newvendorid">
<option value="">-- Select Vendor --</option>
<%
Dim rsVendors
strSQL2 = "SELECT vendorid, vendor FROM vendors WHERE isactive = 1 ORDER BY vendor ASC"
Set rsVendors = objConn.Execute(strSQL2)
While Not rsVendors.EOF
Response.Write("<option value='" & rsVendors("vendorid") & "'>" & Server.HTMLEncode(rsVendors("vendor")) & "</option>")
rsVendors.MoveNext
Wend
rsVendors.Close
Set rsVendors = Nothing
%>
<option value="new">+ Add New Vendor</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addVendorBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new vendor -->
<div id="newVendorSection_edit" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Vendor</h6>
<div class="form-group">
<label for="newvendorname_edit">Vendor Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newvendorname_edit" name="newvendorname"
maxlength="50" placeholder="e.g., Axis, Hikvision, Dahua">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewVendor_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelnotes_edit">Model Notes</label>
<textarea class="form-control" id="newmodelnotes_edit" name="newmodelnotes"
rows="2" maxlength="255"
placeholder="Additional notes about this model..."></textarea>
</div>
<div class="form-group">
<label for="newmodeldocpath_edit">Documentation Path</label>
<input type="text" class="form-control" id="newmodeldocpath_edit" name="newmodeldocpath"
maxlength="255" placeholder="\\server\docs\model.pdf or http://...">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewModel_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Serial Number</label>
<div class="col-lg-9">
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(rs("serialnumber"))%>"
maxlength="100" placeholder="e.g., SN123456789">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IP Address</label>
<div class="col-lg-9">
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(rs("ipaddress"))%>"
maxlength="45" pattern="^[0-9\.:]*$"
placeholder="e.g., 192.168.1.100">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Description</label>
<div class="col-lg-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes..."><%=Server.HTMLEncode(rs("description"))%></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label"></label>
<div class="col-lg-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If rs("isactive") = True Or rs("isactive") = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
</div>
</div>
<!-- Hidden coordinate fields -->
<input type="hidden" id="maptop" name="maptop" value="<%=rs("maptop")%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=rs("mapleft")%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Map Position</label>
<div class="col-lg-9">
<button type="button" class="btn btn-secondary btn-sm" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
Response.Write("Current position: X=" & rs("mapleft") & ", Y=" & rs("maptop"))
Else
Response.Write("No position set - click button to select")
End If
%>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-9 offset-lg-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<a href="network_devices.asp?filter=Camera" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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">
</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>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<style>
.location-popup-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
}
.location-popup {
display: none;
position: fixed;
background: #2a2a2a;
border-radius: 6px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
z-index: 9999;
overflow: hidden;
border: 1px solid #444;
}
.location-popup-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #444;
}
.location-popup-close {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 0;
transition: background 0.2s;
}
.location-popup-close:hover {
background: rgba(255,255,255,0.3);
}
.location-popup-body {
padding: 0;
}
.location-popup iframe {
display: block;
border: none;
}
/* Theme-specific link colors */
body.bg-theme1 .location-link,
body.bg-theme2 .location-link,
body.bg-theme3 .location-link,
body.bg-theme4 .location-link,
body.bg-theme5 .location-link,
body.bg-theme6 .location-link { color: #007bff !important; }
body.bg-theme7 .location-link { color: #17a2b8 !important; }
body.bg-theme8 .location-link { color: #ffc107 !important; }
body.bg-theme9 .location-link { color: #6c757d !important; }
body.bg-theme10 .location-link { color: #8b6f47 !important; }
body.bg-theme11 .location-link { color: #42a5f5 !important; }
body.bg-theme12 .location-link { color: #ab47bc !important; }
body.bg-theme13 .location-link { color: #ef5350 !important; }
body.bg-theme14 .location-link { color: #66bb6a !important; }
body.bg-theme15 .location-link { color: #5c6bc0 !important; }
body.bg-theme16 .location-link { color: #9c27b0 !important; }
</style>
<script>
$(document).ready(function() {
// Create popup elements
var $overlay = $('<div class="location-popup-overlay"></div>').appendTo('body');
var $popup = $('<div class="location-popup"></div>').appendTo('body');
$popup.html(
'<div class="location-popup-header">' +
'<h6 style="margin:0; font-size:16px;"><i class="zmdi zmdi-pin"></i> <span class="location-title">Loading...</span></h6>' +
'<button class="location-popup-close" title="Close (Esc)">&times;</button>' +
'</div>' +
'<div class="location-popup-body">' +
'<iframe src="" width="440" height="340"></iframe>' +
'</div>'
);
var $iframe = $popup.find('iframe');
var $title = $popup.find('.location-title');
var currentCameraId = null;
// Function to show popup with smart positioning
function showLocationPopup(cameraId, locationName, mouseEvent) {
if (currentCameraId === cameraId && $popup.is(':visible')) {
return;
}
currentCameraId = cameraId;
$title.text('Camera ' + locationName);
$iframe.attr('src', './displaylocation.asp?type=camera&id=' + cameraId);
// Position popup using viewport coordinates
var popupWidth = 440;
var popupHeight = 400;
var mouseX = mouseEvent.clientX;
var mouseY = mouseEvent.clientY;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var left, top;
// Horizontal positioning
left = mouseX + 10;
if (left + popupWidth > windowWidth - 10) {
left = mouseX - popupWidth - 10;
}
if (left < 10) {
left = 10;
}
// Vertical positioning
top = mouseY - 50;
if (top + popupHeight > windowHeight - 10) {
top = windowHeight - popupHeight - 10;
}
if (top < 10) {
top = 10;
}
$popup.css({
left: left + 'px',
top: top + 'px',
display: 'block'
});
$overlay.fadeIn(200);
$popup.fadeIn(200);
}
function hideLocationPopup() {
$overlay.fadeOut(200);
$popup.fadeOut(200);
setTimeout(function() {
$iframe.attr('src', '');
currentCameraId = null;
}, 200);
}
var hoverTimer = null;
$('.location-link').on('mouseenter', function(e) {
var $link = $(this);
var cameraId = $link.data('cameraid');
var locationName = $link.text().trim();
var mouseEvent = e;
if (hoverTimer) {
clearTimeout(hoverTimer);
}
hoverTimer = setTimeout(function() {
showLocationPopup(cameraId, locationName, mouseEvent);
}, 300);
});
$('.location-link').on('mouseleave', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$overlay.on('click', hideLocationPopup);
$('.location-popup-close').on('click', hideLocationPopup);
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $popup.is(':visible')) {
hideLocationPopup();
}
});
$popup.on('mouseenter', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$popup.on('mouseleave', function() {
hideLocationPopup();
});
// IDF nested add functionality for Edit tab
$('#addIdfBtn_edit, #idfid_edit').on('change click', function() {
if ($('#idfid_edit').val() === 'new' || $(this).attr('id') === 'addIdfBtn_edit') {
$('#idfid_edit').val('new');
$('#newIdfSection_edit').slideDown();
$('#newidfname_edit').prop('required', true);
}
});
$('#cancelNewIdf_edit').on('click', function() {
$('#newIdfSection_edit').slideUp();
$('#idfid_edit').val('');
$('#newidfname_edit').val('').prop('required', false);
$('#newidfdescription_edit').val('');
});
// Model/Vendor nested add functionality for Edit tab
$('#addModelBtn_edit, #modelid_edit').on('change click', function() {
if ($('#modelid_edit').val() === 'new' || $(this).attr('id') === 'addModelBtn_edit') {
$('#modelid_edit').val('new');
$('#newModelSection_edit').slideDown();
$('#newmodelnumber_edit').prop('required', true);
$('#newvendorid_edit').prop('required', true);
}
});
$('#cancelNewModel_edit').on('click', function() {
$('#newModelSection_edit').slideUp();
$('#newVendorSection_edit').slideUp();
$('#modelid_edit').val('');
$('#newmodelnumber_edit').val('').prop('required', false);
$('#newvendorid_edit').val('').prop('required', false);
$('#newmodelnotes_edit').val('');
$('#newmodeldocpath_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Show/hide new vendor section for Edit tab
$('#addVendorBtn_edit, #newvendorid_edit').on('change click', function() {
if ($('#newvendorid_edit').val() === 'new' || $(this).attr('id') === 'addVendorBtn_edit') {
$('#newvendorid_edit').val('new');
$('#newVendorSection_edit').slideDown();
$('#newvendorname_edit').prop('required', true);
}
});
$('#cancelNewVendor_edit').on('click', function() {
$('#newVendorSection_edit').slideUp();
$('#newvendorid_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Form validation for Edit tab
$('form').on('submit', function(e) {
// Validate IDF
if ($('#idfid_edit').val() === 'new') {
if ($('#newidfname_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter an IDF name or select an existing IDF');
$('#newidfname_edit').focus();
return false;
}
} else if ($('#idfid_edit').val() === '' || !$('#idfid_edit').val()) {
e.preventDefault();
alert('Please select an IDF location for this camera');
$('#idfid_edit').focus();
return false;
}
// Validate Model
if ($('#modelid_edit').val() === 'new') {
if ($('#newmodelnumber_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a model number or select an existing model');
$('#newmodelnumber_edit').focus();
return false;
}
if ($('#newvendorid_edit').val() === '' || $('#newvendorid_edit').val() === 'new') {
if ($('#newvendorid_edit').val() === 'new') {
if ($('#newvendorname_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a vendor name or select an existing vendor');
$('#newvendorname_edit').focus();
return false;
}
} else {
e.preventDefault();
alert('Please select a vendor or add a new one');
$('#newvendorid_edit').focus();
return false;
}
}
}
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
rs.Close
Set rs = Nothing
objConn.Close
%>

View File

@@ -1,426 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim idfid
idfid = Request.Querystring("id")
If Not IsNumeric(idfid) Then
Response.Redirect("network_devices.asp?filter=IDF")
Response.End
End If
strSQL = "SELECT * FROM idfs WHERE idfid = " & CLng(idfid)
set rs = objconn.Execute(strSQL)
If rs.EOF Then
Response.Write("IDF not found")
objConn.Close
Response.End
End If
%>
<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-lg-4">
<div class="card profile-card-2">
<div class="card-img-block">
<img class="img-fluid" src="./images/devices/idf.png" alt="IDF">
</div>
<div class="card-body pt-5">
<img src="./images/devices/idf.png" alt="IDF" class="profile">
<h5 class="card-title"><%Response.Write(Server.HTMLEncode(rs("idfname")))%></h5>
<p class="card-text">Intermediate Distribution Frame</p>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified">
<li class="nav-item">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-wrench"></i> <span class="hidden-xs">Settings</span></a>
</li>
<li class="nav-item">
<a href="javascript:void();" data-target="#edit" data-toggle="pill" class="nav-link"><i class="icon-note"></i> <span class="hidden-xs">Edit</span></a>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Configuration</h5>
<div class="row">
<div class="col-md-3">
<p class="mb-2"><strong>Name:</strong></p>
<p class="mb-2"><strong>Description:</strong></p>
<p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
</div>
<div class="col-md-9">
<p class="mb-2"><%Response.Write(Server.HTMLEncode(rs("idfname")))%></p>
<p class="mb-2">
<%
If Not IsNull(rs("description")) And rs("description") <> "" Then
Response.Write(Server.HTMLEncode(rs("description")))
Else
Response.Write("<em class='text-muted'>No description</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
%>
<span class="location-link" data-idfid="<%Response.Write(idfid)%>" style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>View on Map
</span>
<%
Else
Response.Write("<em class='text-muted'>No location set</em>")
End If
%>
</p>
<p class="mb-2">
<%
If rs("isactive") Then
Response.Write("<span class='badge badge-success'>Active</span>")
Else
Response.Write("<span class='badge badge-secondary'>Inactive</span>")
End If
%>
</p>
</div>
</div>
<!--/row-->
</div>
<div class="tab-pane" id="edit">
<form method="post" action="./save_network_device.asp">
<input type="hidden" name="type" value="idf">
<input type="hidden" name="id" value="<%=idfid%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IDF Name <span class="text-danger">*</span></label>
<div class="col-lg-9">
<input type="text" name="idfname" class="form-control"
value="<%=Server.HTMLEncode(rs("idfname"))%>"
required maxlength="100"
placeholder="e.g., Main-IDF, Floor-2-IDF">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Description</label>
<div class="col-lg-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes about this IDF..."><%=Server.HTMLEncode(rs("description"))%></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label"></label>
<div class="col-lg-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If rs("isactive") = True Or rs("isactive") = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
</div>
</div>
<!-- Hidden coordinate fields -->
<input type="hidden" id="maptop" name="maptop" value="<%=rs("maptop")%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=rs("mapleft")%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Map Position</label>
<div class="col-lg-9">
<button type="button" class="btn btn-secondary btn-sm" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
Response.Write("Current position: X=" & rs("mapleft") & ", Y=" & rs("maptop"))
Else
Response.Write("No position set - click button to select")
End If
%>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-9 offset-lg-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<a href="network_devices.asp?filter=IDF" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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">
</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>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<style>
.location-popup-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
}
.location-popup {
display: none;
position: fixed;
background: #2a2a2a;
border-radius: 6px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
z-index: 9999;
overflow: hidden;
border: 1px solid #444;
}
.location-popup-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #444;
}
.location-popup-close {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 0;
transition: background 0.2s;
}
.location-popup-close:hover {
background: rgba(255,255,255,0.3);
}
.location-popup-body {
padding: 0;
}
.location-popup iframe {
display: block;
border: none;
}
/* Theme-specific link colors */
body.bg-theme1 .location-link,
body.bg-theme2 .location-link,
body.bg-theme3 .location-link,
body.bg-theme4 .location-link,
body.bg-theme5 .location-link,
body.bg-theme6 .location-link { color: #007bff !important; }
body.bg-theme7 .location-link { color: #17a2b8 !important; }
body.bg-theme8 .location-link { color: #ffc107 !important; }
body.bg-theme9 .location-link { color: #6c757d !important; }
body.bg-theme10 .location-link { color: #8b6f47 !important; }
body.bg-theme11 .location-link { color: #42a5f5 !important; }
body.bg-theme12 .location-link { color: #ab47bc !important; }
body.bg-theme13 .location-link { color: #ef5350 !important; }
body.bg-theme14 .location-link { color: #66bb6a !important; }
body.bg-theme15 .location-link { color: #5c6bc0 !important; }
body.bg-theme16 .location-link { color: #9c27b0 !important; }
</style>
<script>
$(document).ready(function() {
// Create popup elements
var $overlay = $('<div class="location-popup-overlay"></div>').appendTo('body');
var $popup = $('<div class="location-popup"></div>').appendTo('body');
$popup.html(
'<div class="location-popup-header">' +
'<h6 style="margin:0; font-size:16px;"><i class="zmdi zmdi-pin"></i> <span class="location-title">Loading...</span></h6>' +
'<button class="location-popup-close" title="Close (Esc)">&times;</button>' +
'</div>' +
'<div class="location-popup-body">' +
'<iframe src="" width="440" height="340"></iframe>' +
'</div>'
);
var $iframe = $popup.find('iframe');
var $title = $popup.find('.location-title');
var currentIdfId = null;
// Function to show popup with smart positioning
function showLocationPopup(idfId, locationName, mouseEvent) {
if (currentIdfId === idfId && $popup.is(':visible')) {
return;
}
currentIdfId = idfId;
$title.text('IDF ' + locationName);
$iframe.attr('src', './displaylocation.asp?type=idf&id=' + idfId);
// Position popup using viewport coordinates
var popupWidth = 440;
var popupHeight = 400;
var mouseX = mouseEvent.clientX;
var mouseY = mouseEvent.clientY;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var left, top;
// Horizontal positioning
left = mouseX + 10;
if (left + popupWidth > windowWidth - 10) {
left = mouseX - popupWidth - 10;
}
if (left < 10) {
left = 10;
}
// Vertical positioning
top = mouseY - 50;
if (top + popupHeight > windowHeight - 10) {
top = windowHeight - popupHeight - 10;
}
if (top < 10) {
top = 10;
}
$popup.css({
left: left + 'px',
top: top + 'px',
display: 'block'
});
$overlay.fadeIn(200);
$popup.fadeIn(200);
}
function hideLocationPopup() {
$overlay.fadeOut(200);
$popup.fadeOut(200);
setTimeout(function() {
$iframe.attr('src', '');
currentIdfId = null;
}, 200);
}
var hoverTimer = null;
$('.location-link').on('mouseenter', function(e) {
var $link = $(this);
var idfId = $link.data('idfid');
var locationName = $link.text().trim();
var mouseEvent = e;
if (hoverTimer) {
clearTimeout(hoverTimer);
}
hoverTimer = setTimeout(function() {
showLocationPopup(idfId, locationName, mouseEvent);
}, 300);
});
$('.location-link').on('mouseleave', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$overlay.on('click', hideLocationPopup);
$('.location-popup-close').on('click', hideLocationPopup);
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $popup.is(':visible')) {
hideLocationPopup();
}
});
$popup.on('mouseenter', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$popup.on('mouseleave', function() {
hideLocationPopup();
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
rs.Close
Set rs = Nothing
objConn.Close
%>

View File

@@ -36,20 +36,30 @@
<tr> <tr>
<th scope="col">Machine</th> <th scope="col">Machine</th>
<th scope="col">Application</th> <th scope="col">Application</th>
<th scope="col">Version</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% <%
strSQL = " SELECT machinenumber,appname,installedapps.machineid FROM machines,installedapps,applications WHERE installedapps.machineid=machines.machineid AND installedapps.isactive=1 " & _ strSQL = "SELECT m.machinenumber, a.appname, ia.machineid, av.version " & _
"AND installedapps.appid=applications.appid AND installedapps.appid="&appid &" ORDER BY machinenumber ASC" "FROM installedapps ia " & _
"INNER JOIN machines m ON ia.machineid = m.machineid " & _
"INNER JOIN applications a ON ia.appid = a.appid " & _
"LEFT JOIN appversions av ON ia.appversionid = av.appversionid " & _
"WHERE ia.isactive = 1 AND ia.appid = " & CLng(appid) & " " & _
"ORDER BY m.machinenumber ASC"
set rs = objconn.Execute(strSQL) set rs = objconn.Execute(strSQL)
while not rs.eof while not rs.eof
Response.write("<tr>") Response.write("<tr>")
Dim versionDisplay
versionDisplay = rs("version") & ""
If versionDisplay = "" Then versionDisplay = "<span class='text-muted'>-</span>"
%> %>
<td><a href="./displaymachine.asp?machineid=<%Response.Write(rs("machineid"))%>" title="View Machine Details"><%Response.Write(rs("machinenumber"))%></a></td> <td><a href="./displaymachine.asp?machineid=<%Response.Write(rs("machineid"))%>" title="View Machine Details"><%Response.Write(Server.HTMLEncode(rs("machinenumber") & ""))%></a></td>
<td><%Response.Write(rs("appname"))%></td> <td><%Response.Write(Server.HTMLEncode(rs("appname") & ""))%></td>
<td><%Response.Write(versionDisplay)%></td>
</tr> </tr>

View File

@@ -27,8 +27,12 @@
ElseIf deviceType <> "" And deviceId <> "" And IsNumeric(deviceId) Then ElseIf deviceType <> "" And deviceId <> "" And IsNumeric(deviceId) Then
' New format: type + id parameters ' New format: type + id parameters
' All network devices now stored in machines table (machinetypeid 16-20) ' All network devices now stored in machines table (machinetypeid 16-20)
' Printers have their own maptop/mapleft in the printers table
Select Case LCase(deviceType) Select Case LCase(deviceType)
Case "idf", "server", "switch", "camera", "accesspoint", "access point", "printer" Case "printer"
' Printers have their own location in the printers table
strSQL = "SELECT p.mapleft, p.maptop, p.printerwindowsname AS devicename FROM printers p WHERE p.printerid = " & CLng(deviceId)
Case "idf", "server", "switch", "camera", "accesspoint", "access point"
' Query machines table for all network devices ' Query machines table for all network devices
strSQL = "SELECT mapleft, maptop, COALESCE(alias, machinenumber) AS devicename FROM machines WHERE machineid = " & CLng(deviceId) strSQL = "SELECT mapleft, maptop, COALESCE(alias, machinenumber) AS devicename FROM machines WHERE machineid = " & CLng(deviceId)
Case "machine" Case "machine"

View File

@@ -77,26 +77,29 @@
' NOTE: Use explicit column names to avoid wildcard conflicts between tables ' NOTE: Use explicit column names to avoid wildcard conflicts between tables
'============================================================================= '=============================================================================
' Phase 2: Only query columns that actually exist in machines table ' Phase 2: Only query columns that actually exist in machines table
' NOTE: machinetypeid is now sourced from models table (models.machinetypeid) not machines table
strSQL = "SELECT machines.machineid, machines.machinenumber, machines.alias, machines.hostname, " & _ strSQL = "SELECT machines.machineid, machines.machinenumber, machines.alias, machines.hostname, " & _
"machines.serialnumber, machines.machinenotes, machines.mapleft, machines.maptop, " & _ "machines.serialnumber, machines.machinenotes, machines.mapleft, machines.maptop, " & _
"machines.modelnumberid, machines.businessunitid, machines.printerid, machines.pctypeid, machines.machinetypeid, " & _ "machines.modelnumberid, machines.businessunitid, machines.printerid, machines.pctypeid, " & _
"machines.loggedinuser, machines.osid, machines.machinestatusid, " & _ "machines.loggedinuser, machines.osid, machines.machinestatusid, " & _
"machines.controllertypeid, machines.controllerosid, machines.requires_manual_machine_config, " & _ "machines.controllertypeid, machines.controllerosid, machines.requires_manual_machine_config, " & _
"machines.lastupdated, " & _ "machines.lastupdated, machines.fqdn, " & _
"machinetypes.machinetype, " & _ "machinetypes.machinetype, " & _
"models.modelnumber, models.image, " & _ "models.modelnumber, models.image, models.machinetypeid, " & _
"businessunits.businessunit, " & _ "businessunits.businessunit, " & _
"functionalaccounts.functionalaccount, functionalaccounts.functionalaccountid, " & _ "functionalaccounts.functionalaccount, functionalaccounts.functionalaccountid, " & _
"vendors.vendor, vendors.vendorid, " & _ "vendors.vendor, vendors.vendorid, " & _
"printers.ipaddress AS printerip, " & _ "printers.ipaddress AS printerip, " & _
"printers.printercsfname, printers.printerwindowsname " & _ "printers.printercsfname, printers.printerwindowsname, " & _
"machinestatus.machinestatus " & _
"FROM machines " & _ "FROM machines " & _
"LEFT JOIN models ON machines.modelnumberid = models.modelnumberid " & _ "LEFT JOIN models ON machines.modelnumberid = models.modelnumberid " & _
"LEFT JOIN machinetypes ON machines.machinetypeid = machinetypes.machinetypeid " & _ "LEFT JOIN machinetypes ON models.machinetypeid = machinetypes.machinetypeid " & _
"LEFT JOIN businessunits ON machines.businessunitid = businessunits.businessunitid " & _ "LEFT JOIN businessunits ON machines.businessunitid = businessunits.businessunitid " & _
"LEFT JOIN functionalaccounts ON machinetypes.functionalaccountid = functionalaccounts.functionalaccountid " & _ "LEFT JOIN functionalaccounts ON machinetypes.functionalaccountid = functionalaccounts.functionalaccountid " & _
"LEFT JOIN vendors ON models.vendorid = vendors.vendorid " & _ "LEFT JOIN vendors ON models.vendorid = vendors.vendorid " & _
"LEFT JOIN printers ON machines.printerid = printers.printerid " & _ "LEFT JOIN printers ON machines.printerid = printers.printerid " & _
"LEFT JOIN machinestatus ON machines.machinestatusid = machinestatus.machinestatusid " & _
"WHERE machines.machineid = " & CLng(machineid) "WHERE machines.machineid = " & CLng(machineid)
Set rs = objConn.Execute(strSQL) Set rs = objConn.Execute(strSQL)
@@ -174,12 +177,14 @@
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<p class="mb-2"><strong>Location:</strong></p> <p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p> <p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p> <p class="mb-2"><strong>Model:</strong></p>
<p class="mb-2"><strong>Function:</strong></p> <p class="mb-2"><strong>Function:</strong></p>
<p class="mb-2"><strong>BU:</strong></p> <p class="mb-2"><strong>BU:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p> <p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>MAC Address:</strong></p> <p class="mb-2"><strong>MAC Address:</strong></p>
<p class="mb-2"><strong>FQDN:</strong></p>
<p class="mb-2"><strong>Controlling PC:</strong></p> <p class="mb-2"><strong>Controlling PC:</strong></p>
<p class="mb-2"><strong>Printer:</strong></p> <p class="mb-2"><strong>Printer:</strong></p>
<p> <p>
@@ -188,12 +193,15 @@
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<% <%
Dim machineNumVal, vendorValM, modelValM, machineTypeVal, buVal Dim machineNumVal, vendorValM, modelValM, machineTypeVal, buVal, statusValM
' Get values and default to N/A if empty ' Get values and default to N/A if empty
machineNumVal = rs("machinenumber") & "" machineNumVal = rs("machinenumber") & ""
If machineNumVal = "" Then machineNumVal = "N/A" If machineNumVal = "" Then machineNumVal = "N/A"
statusValM = rs("machinestatus") & ""
If statusValM = "" Then statusValM = "N/A"
vendorValM = rs("vendor") & "" vendorValM = rs("vendor") & ""
If vendorValM = "" Then vendorValM = "N/A" If vendorValM = "" Then vendorValM = "N/A"
@@ -219,6 +227,7 @@ Else
End If End If
%> %>
</p> </p>
<p class="mb-2"><%=Server.HTMLEncode(statusValM)%></p>
<p class="mb-2"><%=Server.HTMLEncode(vendorValM)%></p> <p class="mb-2"><%=Server.HTMLEncode(vendorValM)%></p>
<p class="mb-2"><%=Server.HTMLEncode(modelValM)%></p> <p class="mb-2"><%=Server.HTMLEncode(modelValM)%></p>
<p class="mb-2"><%=Server.HTMLEncode(machineTypeVal)%></p> <p class="mb-2"><%=Server.HTMLEncode(machineTypeVal)%></p>
@@ -262,19 +271,44 @@ Else
Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If End If
' Get controlling PC from relationships ' Display FQDN
Dim fqdnVal
fqdnVal = rs("fqdn") & ""
If fqdnVal <> "" Then
Response.Write("<p class='mb-2'>" & Server.HTMLEncode(fqdnVal) & "</p>")
Else
Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If
' Get controlling PC from relationships - check both directions
' Direction 1: PC (machineid) controls this equipment (related_machineid)
' Direction 2: This equipment (machineid) is controlled by PC (related_machineid)
Dim rsControlPC, strControlPCSQL, controlPCHostname, controlPCID Dim rsControlPC, strControlPCSQL, controlPCHostname, controlPCID
' First check: PC controls this equipment (standard direction)
strControlPCSQL = "SELECT m.machineid, m.hostname, m.machinenumber FROM machinerelationships mr " & _ strControlPCSQL = "SELECT m.machineid, m.hostname, m.machinenumber FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.machineid = m.machineid " & _ "JOIN machines m ON mr.machineid = m.machineid " & _
"WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 LIMIT 1" "WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 " & _
"AND m.machinetypeid >= 33 LIMIT 1"
Set rsControlPC = ExecuteParameterizedQuery(objConn, strControlPCSQL, Array(machineid)) Set rsControlPC = ExecuteParameterizedQuery(objConn, strControlPCSQL, Array(machineid))
If rsControlPC.EOF Then
rsControlPC.Close
' Second check: This equipment has relationship to PC (reverse direction)
strControlPCSQL = "SELECT m.machineid, m.hostname, m.machinenumber FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.related_machineid = m.machineid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 " & _
"AND m.machinetypeid >= 33 LIMIT 1"
Set rsControlPC = ExecuteParameterizedQuery(objConn, strControlPCSQL, Array(machineid))
End If
If Not rsControlPC.EOF Then If Not rsControlPC.EOF Then
controlPCHostname = rsControlPC("hostname") & "" controlPCHostname = rsControlPC("hostname") & ""
controlPCID = rsControlPC("machineid") controlPCID = rsControlPC("machineid")
If controlPCHostname = "" Then controlPCHostname = rsControlPC("machinenumber") & "" If controlPCHostname = "" Then controlPCHostname = rsControlPC("machinenumber") & ""
Response.Write("<p class='mb-2'><a href='./displaymachine.asp?machineid=" & controlPCID & "'>" & Server.HTMLEncode(controlPCHostname) & "</a></p>") Response.Write("<p class='mb-2'><a href='./displaypc.asp?machineid=" & controlPCID & "'>" & Server.HTMLEncode(controlPCHostname) & "</a></p>")
Else Else
Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If End If
@@ -378,26 +412,16 @@ End If
<tbody> <tbody>
<% <%
' Query PCs that control this machine (directly or via dualpath) ' Query PCs that control this machine (directly or via dualpath)
' First check for direct control, if none then check via dualpath partner ' Check both directions - the PC is identified by machinetypeid IN (33-43)
' Use GROUP_CONCAT to combine multiple IPs into one row per PC ' Use GROUP_CONCAT to combine multiple IPs into one row per PC
strSQL2 = "SELECT m.machineid, m.machinenumber, m.hostname, GROUP_CONCAT(DISTINCT c.address ORDER BY c.address SEPARATOR ', ') as address, 'Controls' as relationshiptype " & _ strSQL2 = "SELECT m.machineid, m.machinenumber, m.hostname, GROUP_CONCAT(DISTINCT c.address ORDER BY c.address SEPARATOR ', ') as address, 'Controls' as relationshiptype " & _
"FROM machinerelationships mr " & _ "FROM machinerelationships mr " & _
"JOIN machines m ON mr.related_machineid = m.machineid " & _ "JOIN machines m ON (mr.machineid = m.machineid OR mr.related_machineid = m.machineid) " & _
"LEFT JOIN communications c ON m.machineid = c.machineid AND c.comstypeid IN (1, 3) AND c.isactive = 1 " & _ "LEFT JOIN communications c ON m.machineid = c.machineid AND c.comstypeid IN (1, 3) AND c.isactive = 1 " & _
"WHERE mr.machineid = ? AND mr.relationshiptypeid = 3 AND m.pctypeid IS NOT NULL AND mr.isactive = 1 " & _ "WHERE (mr.machineid = ? OR mr.related_machineid = ?) AND mr.relationshiptypeid = 3 " & _
"GROUP BY m.machineid, m.machinenumber, m.hostname " & _ " AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) AND m.machineid <> ? AND mr.isactive = 1 " & _
"UNION " & _
"SELECT m.machineid, m.machinenumber, m.hostname, GROUP_CONCAT(DISTINCT c.address ORDER BY c.address SEPARATOR ', ') as address, 'Controls (via Dualpath)' as relationshiptype " & _
"FROM machinerelationships mr_dual " & _
"JOIN machinerelationships mr_control ON mr_dual.related_machineid = mr_control.machineid " & _
"JOIN machines m ON mr_control.related_machineid = m.machineid " & _
"LEFT JOIN communications c ON m.machineid = c.machineid AND c.comstypeid IN (1, 3) AND c.isactive = 1 " & _
"WHERE mr_dual.machineid = ? AND mr_dual.relationshiptypeid = 1 " & _
" AND mr_control.relationshiptypeid = 3 AND m.pctypeid IS NOT NULL " & _
" AND mr_dual.isactive = 1 AND mr_control.isactive = 1 " & _
" AND NOT EXISTS (SELECT 1 FROM machinerelationships mr_direct WHERE mr_direct.machineid = mr_dual.machineid AND mr_direct.relationshiptypeid = 3 AND mr_direct.isactive = 1) " & _
"GROUP BY m.machineid, m.machinenumber, m.hostname" "GROUP BY m.machineid, m.machinenumber, m.hostname"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid, machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid, machineid, machineid))
If rs2.EOF Then If rs2.EOF Then
Response.Write("<tr><td colspan='3' class='text-muted text-center'>No controlling PC assigned</td></tr>") Response.Write("<tr><td colspan='3' class='text-muted text-center'>No controlling PC assigned</td></tr>")
@@ -412,7 +436,7 @@ End If
If pcIP = "" Then pcIP = "<span class='text-muted'>N/A</span>" If pcIP = "" Then pcIP = "<span class='text-muted'>N/A</span>"
Response.Write("<tr>") Response.Write("<tr>")
Response.Write("<td><a href='./displaypc.asp?pcid=" & pcMachineID & "'>" & Server.HTMLEncode(pcHostname) & "</a></td>") Response.Write("<td><a href='./displaypc.asp?machineid=" & pcMachineID & "'>" & Server.HTMLEncode(pcHostname) & "</a></td>")
Response.Write("<td>" & pcIP & "</td>") Response.Write("<td>" & pcIP & "</td>")
Response.Write("<td><span class='badge badge-primary'>" & Server.HTMLEncode(rs2("relationshiptype") & "") & "</span></td>") Response.Write("<td><span class='badge badge-primary'>" & Server.HTMLEncode(rs2("relationshiptype") & "") & "</span></td>")
Response.Write("</tr>") Response.Write("</tr>")
@@ -447,7 +471,7 @@ End If
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.related_machineid = m.machineid " & _ "JOIN machines m ON mr.related_machineid = m.machineid " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " & _ "LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype NOT IN ('Controls', 'Dualpath', 'Connected To') AND mr.isactive = 1" "WHERE mr.machineid = ? AND rt.relationshiptype NOT IN ('Controls', 'Dualpath', 'Connected To') AND mr.isactive = 1"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
@@ -500,7 +524,7 @@ End If
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.related_machineid = m.machineid " & _ "JOIN machines m ON mr.related_machineid = m.machineid " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " & _ "LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Dualpath' AND mr.isactive = 1" "WHERE mr.machineid = ? AND rt.relationshiptype = 'Dualpath' AND mr.isactive = 1"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
@@ -552,7 +576,8 @@ End If
"FROM machinerelationships mr " & _ "FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"LEFT JOIN machines m ON mr.related_machineid = m.machineid " & _ "LEFT JOIN machines m ON mr.related_machineid = m.machineid " & _
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " & _ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Connected To' AND mr.isactive = 1" "WHERE mr.machineid = ? AND rt.relationshiptype = 'Connected To' AND mr.isactive = 1"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
@@ -580,7 +605,8 @@ End If
"FROM machinerelationships mr " & _ "FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"LEFT JOIN machines m ON mr.machineid = m.machineid " & _ "LEFT JOIN machines m ON mr.machineid = m.machineid " & _
"LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " & _ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Connected To' AND mr.isactive = 1" "WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Connected To' AND mr.isactive = 1"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
@@ -738,10 +764,17 @@ End If
'============================================================================= '=============================================================================
' SECURITY: Use parameterized query for installed applications ' SECURITY: Use parameterized query for installed applications
'============================================================================= '=============================================================================
strSQL2 = "SELECT * FROM installedapps, applications WHERE installedapps.appid = applications.appid AND installedapps.isactive = 1 AND installedapps.machineid = ? ORDER BY appname ASC" Dim appDisplay, appVer
strSQL2 = "SELECT a.appname, av.version FROM installedapps ia " & _
"JOIN applications a ON ia.appid = a.appid " & _
"LEFT JOIN appversions av ON ia.appversionid = av.appversionid " & _
"WHERE ia.isactive = 1 AND ia.machineid = ? ORDER BY a.appname ASC"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
Do While Not rs2.EOF Do While Not rs2.EOF
Response.Write("<tr><td><span class='float-left font-weight-bold'>" & Server.HTMLEncode(rs2("appname") & "") & "</span></td></tr>") appDisplay = Server.HTMLEncode(rs2("appname") & "")
appVer = rs2("version") & ""
If appVer <> "" Then appDisplay = appDisplay & " <span class='text-muted'>v" & Server.HTMLEncode(appVer) & "</span>"
Response.Write("<tr><td><span class='float-left font-weight-bold'>" & appDisplay & "</span></td></tr>")
rs2.MoveNext rs2.MoveNext
Loop Loop
rs2.Close rs2.Close

View File

@@ -34,7 +34,7 @@
<div class="card-body"> <div class="card-body">
<div style="margin-bottom:15px;"> <div style="margin-bottom:15px;">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;">
<h5 class="card-title" style="margin:0;">Machines</h5> <h5 class="card-title" style="margin:0;"><a href="./machine_map.asp" target="_blank"><i class='zmdi zmdi-map' title='Show Machine Map'></i></a>&nbsp;&nbsp;&nbsp;&nbsp;Machines</h5>
<div> <div>
<a href="./addmachine.asp" class="btn btn-primary"> <a href="./addmachine.asp" class="btn btn-primary">
<i class="zmdi zmdi-plus-circle"></i> Add Machine <i class="zmdi zmdi-plus-circle"></i> Add Machine
@@ -82,13 +82,15 @@
<% <%
' Build WHERE clause with optional BU filter ' Build WHERE clause with optional BU filter
' NOTE: Filter on machines.machinetypeid to exclude PCs (33-43) and network devices (16-20)
' Equipment types are 1-15
Dim whereClause Dim whereClause
whereClause = "machines.machinetypeid = machinetypes.machinetypeid AND " &_ whereClause = "models.machinetypeid = machinetypes.machinetypeid AND " &_
"machines.modelnumberid = models.modelnumberid AND " &_ "machines.modelnumberid = models.modelnumberid AND " &_
"models.vendorid = vendors.vendorid AND " &_ "models.vendorid = vendors.vendorid AND " &_
"machines.businessunitid = businessunits.businessunitID AND " &_ "machines.businessunitid = businessunits.businessunitID AND " &_
"machines.isactive = 1 AND islocationonly=0 AND machines.pctypeid IS NULL AND " &_ "machines.isactive = 1 AND islocationonly=0 AND machines.pctypeid IS NULL AND " &_
"machines.machinetypeid BETWEEN 1 AND 24" "models.machinetypeid NOT IN (1, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Add BU filter if specified ' Add BU filter if specified
If filterBU <> "" And IsNumeric(filterBU) Then If filterBU <> "" And IsNumeric(filterBU) Then
@@ -108,7 +110,13 @@
<i class="zmdi zmdi-pin"></i> <i class="zmdi zmdi-pin"></i>
</span> </span>
</td> </td>
<td><a href="./displaymachine.asp?machineid=<%Response.Write(rs("machineid"))%>" title="View Machine Details"><%Response.Write(rs("machinenumber"))%></a></td> <td><a href="./displaymachine.asp?machineid=<%Response.Write(rs("machineid"))%>" title="View Machine Details"><%
Dim displayName
displayName = rs("machinenumber") & ""
If displayName = "" Then displayName = rs("hostname") & ""
If displayName = "" Then displayName = "ID:" & rs("machineid")
Response.Write(Server.HTMLEncode(displayName))
%></a></td>
<td><%Response.Write(rs("machinetype"))%></td> <td><%Response.Write(rs("machinetype"))%></td>
<td><%Response.Write(rs("vendor"))%></td> <td><%Response.Write(rs("vendor"))%></td>
<td><%Response.Write(rs("modelnumber"))%></a></td> <td><%Response.Write(rs("modelnumber"))%></a></td>

View File

@@ -27,8 +27,9 @@
' NOTE: This handles both database ID and machine number for flexibility ' NOTE: This handles both database ID and machine number for flexibility
'============================================================================= '=============================================================================
Dim machineid, machinenumber, paramValue Dim machineid, machinenumber, paramValue
' Note: Using machineid variable but accepting pcid parameter for PC pages ' Accept both machineid and pcid parameters for backwards compatibility
machineid = GetSafeInteger("QS", "pcid", 0, 1, 999999) machineid = GetSafeInteger("QS", "machineid", 0, 1, 999999)
If machineid = 0 Then machineid = GetSafeInteger("QS", "pcid", 0, 1, 999999)
' If machineid not provided, try machinenumber parameter ' If machineid not provided, try machinenumber parameter
IF machineid = 0 THEN IF machineid = 0 THEN
@@ -81,10 +82,11 @@
strSQL = "SELECT machines.machineid, machines.machinenumber, machines.alias, machines.hostname, " & _ strSQL = "SELECT machines.machineid, machines.machinenumber, machines.alias, machines.hostname, " & _
"machines.serialnumber, machines.machinenotes, machines.mapleft, machines.maptop, " & _ "machines.serialnumber, machines.machinenotes, machines.mapleft, machines.maptop, " & _
"machines.modelnumberid, machines.businessunitid, machines.printerid, machines.pctypeid, " & _ "machines.modelnumberid, machines.businessunitid, machines.printerid, machines.pctypeid, " & _
"machines.loggedinuser, machines.osid, machines.machinestatusid, " & _ "machines.loggedinuser, machines.osid, machines.machinestatusid, machines.isvnc, machines.iswinrm, " & _
"machines.controllertypeid, machines.controllerosid, machines.requires_manual_machine_config, " & _ "machines.controllertypeid, machines.controllerosid, machines.requires_manual_machine_config, " & _
"machines.lastupdated, " & _ "machines.lastupdated, " & _
"machinetypes.machinetype, machinetypes.machinetypeid, " & _ "machinetypes.machinetype, machinetypes.machinetypeid, " & _
"machinestatus.machinestatus, " & _
"models.modelnumber, models.image, models.modelnumberid, " & _ "models.modelnumber, models.image, models.modelnumberid, " & _
"businessunits.businessunit, businessunits.businessunitid, " & _ "businessunits.businessunit, businessunits.businessunitid, " & _
"functionalaccounts.functionalaccount, functionalaccounts.functionalaccountid, " & _ "functionalaccounts.functionalaccount, functionalaccounts.functionalaccountid, " & _
@@ -94,11 +96,12 @@
"FROM machines " & _ "FROM machines " & _
"INNER JOIN models ON machines.modelnumberid = models.modelnumberid " & _ "INNER JOIN models ON machines.modelnumberid = models.modelnumberid " & _
"LEFT JOIN machinetypes ON models.machinetypeid = machinetypes.machinetypeid " & _ "LEFT JOIN machinetypes ON models.machinetypeid = machinetypes.machinetypeid " & _
"LEFT JOIN machinestatus ON machines.machinestatusid = machinestatus.machinestatusid " & _
"INNER JOIN businessunits ON machines.businessunitid = businessunits.businessunitid " & _ "INNER JOIN businessunits ON machines.businessunitid = businessunits.businessunitid " & _
"LEFT JOIN functionalaccounts ON machinetypes.functionalaccountid = functionalaccounts.functionalaccountid " & _ "LEFT JOIN functionalaccounts ON machinetypes.functionalaccountid = functionalaccounts.functionalaccountid " & _
"INNER JOIN vendors ON models.vendorid = vendors.vendorid " & _ "INNER JOIN vendors ON models.vendorid = vendors.vendorid " & _
"LEFT JOIN printers ON machines.printerid = printers.printerid " & _ "LEFT JOIN printers ON machines.printerid = printers.printerid " & _
"WHERE machines.machineid = " & CLng(machineid) & " AND machines.pctypeid IS NOT NULL" "WHERE machines.machineid = " & CLng(machineid) & " AND machines.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
Set rs = objConn.Execute(strSQL) Set rs = objConn.Execute(strSQL)
@@ -197,7 +200,7 @@
<a href="javascript:void();" data-target="#applications" data-toggle="pill" class="nav-link"><i class="zmdi zmdi-apps"></i> <span class="hidden-xs">Applications</span></a> <a href="javascript:void();" data-target="#applications" data-toggle="pill" class="nav-link"><i class="zmdi zmdi-apps"></i> <span class="hidden-xs">Applications</span></a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="./editpc.asp?pcid=<%=Server.HTMLEncode(machineid)%>" class="nav-link" style="background: linear-gradient(45deg, #667eea 0%, #764ba2 100%); color: white;"><i class="zmdi zmdi-edit"></i> <span class="hidden-xs">Edit PC</span></a> <a href="./editpc.asp?machineid=<%=Server.HTMLEncode(machineid)%>" class="nav-link" style="background: linear-gradient(45deg, #667eea 0%, #764ba2 100%); color: white;"><i class="zmdi zmdi-edit"></i> <span class="hidden-xs">Edit PC</span></a>
</li> </li>
</ul> </ul>
<div class="tab-content p-3"> <div class="tab-content p-3">
@@ -205,6 +208,9 @@
<h5 class="mb-3">Configuration</h5> <h5 class="mb-3">Configuration</h5>
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<p class="mb-2"><strong>Serial Number:</strong></p>
<p class="mb-2"><strong>Hostname:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
<p class="mb-2"><strong>Location:</strong></p> <p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p> <p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p> <p class="mb-2"><strong>Model:</strong></p>
@@ -212,7 +218,8 @@
<p class="mb-2"><strong>BU:</strong></p> <p class="mb-2"><strong>BU:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p> <p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>MAC Address:</strong></p> <p class="mb-2"><strong>MAC Address:</strong></p>
<p class="mb-2"><strong>Controlling PC:</strong></p> <p class="mb-2"><strong>VNC:</strong></p>
<p class="mb-2"><strong>Controlled Equipment:</strong></p>
<p class="mb-2"><strong>Printer:</strong></p> <p class="mb-2"><strong>Printer:</strong></p>
<p> <p>
@@ -220,9 +227,18 @@
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<% <%
Dim machineNumVal, vendorValM, modelValM, machineTypeVal, buVal Dim machineNumVal, vendorValM, modelValM, machineTypeVal, buVal, serialNumVal, hostnameVal, statusVal
' Get values and default to N/A if empty ' Get values and default to N/A if empty
serialNumVal = rs("serialnumber") & ""
If serialNumVal = "" Then serialNumVal = "N/A"
hostnameVal = rs("hostname") & ""
If hostnameVal = "" Then hostnameVal = "N/A"
statusVal = rs("machinestatus") & ""
If statusVal = "" Then statusVal = "N/A"
machineNumVal = rs("machinenumber") & "" machineNumVal = rs("machinenumber") & ""
If machineNumVal = "" Then machineNumVal = "N/A" If machineNumVal = "" Then machineNumVal = "N/A"
@@ -238,6 +254,9 @@ If machineTypeVal = "" Then machineTypeVal = "N/A"
buVal = rs("businessunit") & "" buVal = rs("businessunit") & ""
If buVal = "" Then buVal = "N/A" If buVal = "" Then buVal = "N/A"
%> %>
<p class="mb-2"><%=Server.HTMLEncode(serialNumVal)%></p>
<p class="mb-2"><%=Server.HTMLEncode(hostnameVal)%></p>
<p class="mb-2"><%=Server.HTMLEncode(statusVal)%></p>
<p class="mb-2"> <p class="mb-2">
<% <%
If machineNumVal <> "N/A" Then If machineNumVal <> "N/A" Then
@@ -305,24 +324,78 @@ Else
Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If End If
' Get controlling PC from relationships ' Display VNC status and link
Dim rsControlPC, strControlPCSQL, controlPCHostname, controlPCID Dim hasVncEnabled, vncHostname
strControlPCSQL = "SELECT m.machineid, m.hostname, m.machinenumber FROM machinerelationships mr " & _ hasVncEnabled = False
If Not IsNull(rs("isvnc")) Then
If rs("isvnc") = True Or rs("isvnc") = 1 Or rs("isvnc") = -1 Then
hasVncEnabled = True
End If
End If
' Check WinRM status
Dim hasWinRMEnabled
hasWinRMEnabled = False
If Not IsNull(rs("iswinrm")) Then
If rs("iswinrm") = True Or rs("iswinrm") = 1 Or rs("iswinrm") = -1 Then
hasWinRMEnabled = True
End If
End If
' Use hostname with FQDN for VNC connection
vncHostname = ""
If hostnameVal <> "N/A" And hostnameVal <> "" Then
vncHostname = hostnameVal & ".logon.ds.ge.com"
End If
If hasVncEnabled And vncHostname <> "" Then
Response.Write("<p class='mb-2'><a href='vnc://" & Server.HTMLEncode(vncHostname) & "' title='Connect via VNC'>" & Server.HTMLEncode(vncHostname) & "</a></p>")
ElseIf hasVncEnabled Then
Response.Write("<p class='mb-2'><span class='text-muted'>VNC Enabled (No hostname)</span></p>")
Else
Response.Write("<p class='mb-2'><span class='text-muted'>VNC: N/A</span></p>")
End If
' Display WinRM status
If hasWinRMEnabled Then
Response.Write("<p class='mb-2'><span class='badge badge-success'>WinRM Enabled</span></p>")
Else
Response.Write("<p class='mb-2'><span class='badge badge-secondary'>WinRM: N/A</span></p>")
End If
' Get controlled equipment from relationships - check both directions
' Direction 1: This PC (machineid) controls equipment (related_machineid)
' Direction 2: Equipment (machineid) is controlled by this PC (related_machineid)
Dim rsControlledEquip, strControlledEquipSQL, controlledEquipName, controlledEquipID
' First check: This PC controls equipment (standard direction)
strControlledEquipSQL = "SELECT m.machineid, m.machinenumber FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.related_machineid = m.machineid " & _
"WHERE mr.machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 " & _
"AND m.machinetypeid < 33 LIMIT 1"
Set rsControlledEquip = ExecuteParameterizedQuery(objConn, strControlledEquipSQL, Array(machineid))
If rsControlledEquip.EOF Then
rsControlledEquip.Close
' Second check: Equipment has relationship to this PC (reverse direction)
strControlledEquipSQL = "SELECT m.machineid, m.machinenumber FROM machinerelationships mr " & _
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _ "JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
"JOIN machines m ON mr.machineid = m.machineid " & _ "JOIN machines m ON mr.machineid = m.machineid " & _
"WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 LIMIT 1" "WHERE mr.related_machineid = ? AND rt.relationshiptype = 'Controls' AND mr.isactive = 1 " & _
Set rsControlPC = ExecuteParameterizedQuery(objConn, strControlPCSQL, Array(machineid)) "AND m.machinetypeid < 33 LIMIT 1"
Set rsControlledEquip = ExecuteParameterizedQuery(objConn, strControlledEquipSQL, Array(machineid))
End If
If Not rsControlPC.EOF Then If Not rsControlledEquip.EOF Then
controlPCHostname = rsControlPC("hostname") & "" controlledEquipName = rsControlledEquip("machinenumber") & ""
controlPCID = rsControlPC("machineid") controlledEquipID = rsControlledEquip("machineid")
If controlPCHostname = "" Then controlPCHostname = rsControlPC("machinenumber") & "" Response.Write("<p class='mb-2'><a href='./displaymachine.asp?machineid=" & controlledEquipID & "'>" & Server.HTMLEncode(controlledEquipName) & "</a></p>")
Response.Write("<p class='mb-2'><a href='./displaymachine.asp?machineid=" & controlPCID & "'>" & Server.HTMLEncode(controlPCHostname) & "</a></p>")
Else Else
Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>") Response.Write("<p class='mb-2'><span class='text-muted'>N/A</span></p>")
End If End If
rsControlPC.Close rsControlledEquip.Close
Set rsControlPC = Nothing Set rsControlledEquip = Nothing
' SECURITY: HTML encode printer data to prevent XSS ' SECURITY: HTML encode printer data to prevent XSS
' Printer data - check if exists (LEFT JOIN may return NULL) ' Printer data - check if exists (LEFT JOIN may return NULL)
@@ -421,25 +494,17 @@ End If
</thead> </thead>
<tbody> <tbody>
<% <%
' Query machines that THIS PC controls (including dualpath partners) ' Query machines that THIS PC controls
' UNION: directly controlled machines + dualpath partners of controlled machines ' Check both directions - the equipment is identified by machinetypeid NOT IN (33-43)
strSQL2 = "SELECT m.machineid, m.machinenumber, mt.machinetype, mo.modelnumber, 'Controls' as relationshiptype " & _ strSQL2 = "SELECT m.machineid, m.machinenumber, mt.machinetype, mo.modelnumber, 'Controls' as relationshiptype " & _
"FROM machinerelationships mr " & _ "FROM machinerelationships mr " & _
"JOIN machines m ON mr.machineid = m.machineid " & _ "JOIN machines m ON (mr.machineid = m.machineid OR mr.related_machineid = m.machineid) " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _ "LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr.related_machineid = ? AND mr.relationshiptypeid = 3 AND mr.isactive = 1 " & _ "WHERE (mr.machineid = ? OR mr.related_machineid = ?) AND mr.relationshiptypeid = 3 " & _
"UNION " & _ " AND m.machinetypeid NOT IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) AND m.machineid <> ? AND mr.isactive = 1 " & _
"SELECT m.machineid, m.machinenumber, mt.machinetype, mo.modelnumber, 'Controls (Dualpath)' as relationshiptype " & _
"FROM machinerelationships mr_control " & _
"JOIN machinerelationships mr_dual ON mr_control.machineid = mr_dual.machineid " & _
"JOIN machines m ON mr_dual.related_machineid = m.machineid " & _
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " & _
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " & _
"WHERE mr_control.related_machineid = ? AND mr_control.relationshiptypeid = 3 " & _
" AND mr_dual.relationshiptypeid = 1 AND mr_control.isactive = 1 AND mr_dual.isactive = 1 " & _
"ORDER BY machinenumber" "ORDER BY machinenumber"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid, machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid, machineid, machineid))
If rs2.EOF Then If rs2.EOF Then
Response.Write("<tr><td colspan='4' class='text-muted text-center'>This PC does not control any machines</td></tr>") Response.Write("<tr><td colspan='4' class='text-muted text-center'>This PC does not control any machines</td></tr>")
@@ -605,10 +670,18 @@ End If
'============================================================================= '=============================================================================
' SECURITY: Use parameterized query for installed applications ' SECURITY: Use parameterized query for installed applications
'============================================================================= '=============================================================================
strSQL2 = "SELECT * FROM installedapps, applications WHERE installedapps.appid = applications.appid AND installedapps.isactive = 1 AND installedapps.machineid = ? ORDER BY appname ASC" Dim appDisplay, appVer, appId
strSQL2 = "SELECT a.appid, a.appname, av.version FROM installedapps ia " & _
"JOIN applications a ON ia.appid = a.appid " & _
"LEFT JOIN appversions av ON ia.appversionid = av.appversionid " & _
"WHERE ia.isactive = 1 AND ia.machineid = ? ORDER BY a.appname ASC"
Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid)) Set rs2 = ExecuteParameterizedQuery(objConn, strSQL2, Array(machineid))
Do While Not rs2.EOF Do While Not rs2.EOF
Response.Write("<tr><td><span class='float-left font-weight-bold'>" & Server.HTMLEncode(rs2("appname") & "") & "</span></td></tr>") appId = rs2("appid")
appDisplay = Server.HTMLEncode(rs2("appname") & "")
appVer = rs2("version") & ""
If appVer <> "" Then appDisplay = appDisplay & " <span class='text-muted'>v" & Server.HTMLEncode(appVer) & "</span>"
Response.Write("<tr><td><a href='./displayapplication.asp?appid=" & appId & "' class='float-left font-weight-bold'>" & appDisplay & "</a></td></tr>")
rs2.MoveNext rs2.MoveNext
Loop Loop
rs2.Close rs2.Close

View File

@@ -43,6 +43,27 @@ Dim currentPCStatus, recentFilter, deviceTypeFilter, sel
currentPCStatus = Request.QueryString("pcstatus") currentPCStatus = Request.QueryString("pcstatus")
recentFilter = Request.QueryString("recent") recentFilter = Request.QueryString("recent")
deviceTypeFilter = Request.QueryString("devicetype") deviceTypeFilter = Request.QueryString("devicetype")
' Check for specialized PCs (CMM, Wax Trace, Measuring Tool) without equipment relationships
Dim rsUnlinked, unlinkedCount
unlinkedCount = 0
Set rsUnlinked = objConn.Execute("SELECT COUNT(*) as cnt FROM machines m " & _
"WHERE m.machinetypeid IN (41, 42, 43) AND m.isactive = 1 " & _
"AND NOT EXISTS (SELECT 1 FROM machinerelationships mr WHERE (mr.machineid = m.machineid OR mr.related_machineid = m.machineid) AND mr.relationshiptypeid = 3 AND mr.isactive = 1)")
If Not rsUnlinked.EOF Then
unlinkedCount = CLng(rsUnlinked("cnt") & "")
End If
rsUnlinked.Close
Set rsUnlinked = Nothing
If unlinkedCount > 0 Then
%>
<div class="alert alert-warning" role="alert" style="margin-bottom:15px;">
<i class="zmdi zmdi-alert-triangle"></i> <strong><%=unlinkedCount%> specialized PC(s)</strong> (CMM, Wax Trace, or Measuring Tool) need equipment relationships.
<a href="displaypcs.asp?needsrelationship=1" class="alert-link">View them</a>
</div>
<%
End If
%> %>
<div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;"> <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;">
<select id="deviceTypeFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('devicetype', this.value)"> <select id="deviceTypeFilter" class="btn btn-secondary btn-sm" onchange="updateFilter('devicetype', this.value)">
@@ -71,7 +92,7 @@ Set rsStatus = Nothing
<option value="">All Time</option> <option value="">All Time</option>
<option value="7"<% If recentFilter = "7" Then Response.Write(" selected") End If%>>Last 7 Days</option> <option value="7"<% If recentFilter = "7" Then Response.Write(" selected") End If%>>Last 7 Days</option>
</select> </select>
<% If currentPCStatus <> "" Or recentFilter <> "" Or deviceTypeFilter <> "" Then %> <% If currentPCStatus <> "" Or recentFilter <> "" Or deviceTypeFilter <> "" Or Request.QueryString("needsrelationship") <> "" Then %>
<a href="displaypcs.asp" class="btn btn-outline-secondary btn-sm"> <a href="displaypcs.asp" class="btn btn-outline-secondary btn-sm">
<i class="zmdi zmdi-close"></i> Clear <i class="zmdi zmdi-close"></i> Clear
</a> </a>
@@ -89,30 +110,38 @@ Set rsStatus = Nothing
<th scope="col">Serial</th> <th scope="col">Serial</th>
<th scope="col">Model</th> <th scope="col">Model</th>
<th scope="col">OS</th> <th scope="col">OS</th>
<th scope="col">Equipment</th>
<th scope="col">VNC</th>
<th scope="col">WinRM</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% <%
' Build query based on filters ' Build query based on filters
Dim pcStatusFilter, recentDaysFilter, deviceTypeFilterSQL, whereClause Dim pcStatusFilter, recentDaysFilter, deviceTypeFilterSQL, needsRelationshipFilter, whereClause
Dim displayName, hasVnc, vncHost, hasWinrm
pcStatusFilter = Request.QueryString("pcstatus") pcStatusFilter = Request.QueryString("pcstatus")
recentDaysFilter = Request.QueryString("recent") recentDaysFilter = Request.QueryString("recent")
deviceTypeFilterSQL = Request.QueryString("devicetype") deviceTypeFilterSQL = Request.QueryString("devicetype")
needsRelationshipFilter = Request.QueryString("needsrelationship")
' Base query with LEFT JOINs to show all PCs ' Base query with LEFT JOINs to show all PCs
strSQL = "SELECT m.machineid, m.hostname, m.serialnumber, m.machinenumber, m.machinestatusid, " & _ strSQL = "SELECT m.machineid, m.hostname, m.serialnumber, m.machinenumber, m.machinestatusid, " & _
"m.modelnumberid, m.osid, m.loggedinuser, m.lastupdated, " & _ "m.modelnumberid, m.osid, m.loggedinuser, m.lastupdated, m.isvnc, m.iswinrm, " & _
"vendors.vendor, models.modelnumber, operatingsystems.operatingsystem, " & _ "vendors.vendor, models.modelnumber, operatingsystems.operatingsystem, " & _
"c.address AS ipaddress, c.macaddress, " & _ "c.address AS ipaddress, c.macaddress, " & _
"machinestatus.machinestatus " & _ "machinestatus.machinestatus, " & _
"eq.machineid AS equipment_id, eq.machinenumber AS equipment_number " & _
"FROM machines m " & _ "FROM machines m " & _
"LEFT JOIN models ON m.modelnumberid = models.modelnumberid " & _ "LEFT JOIN models ON m.modelnumberid = models.modelnumberid " & _
"LEFT JOIN vendors ON models.vendorid = vendors.vendorid " & _ "LEFT JOIN vendors ON models.vendorid = vendors.vendorid " & _
"LEFT JOIN operatingsystems ON m.osid = operatingsystems.osid " & _ "LEFT JOIN operatingsystems ON m.osid = operatingsystems.osid " & _
"LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _ "LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _
"LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _ "LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _
"WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35) " "LEFT JOIN machinerelationships mr ON (mr.machineid = m.machineid OR mr.related_machineid = m.machineid) AND mr.isactive = 1 AND mr.relationshiptypeid = 3 " & _
"LEFT JOIN machines eq ON (eq.machineid = mr.related_machineid OR eq.machineid = mr.machineid) AND eq.machineid <> m.machineid AND eq.machinetypeid < 33 " & _
"WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Apply filters ' Apply filters
whereClause = "" whereClause = ""
@@ -131,6 +160,12 @@ Set rsStatus = Nothing
whereClause = whereClause & "AND (models.modelnumber LIKE '%OptiPlex%' OR models.modelnumber LIKE '%Tower%' OR models.modelnumber LIKE '%Micro%') " whereClause = whereClause & "AND (models.modelnumber LIKE '%OptiPlex%' OR models.modelnumber LIKE '%Tower%' OR models.modelnumber LIKE '%Micro%') "
End If End If
' Filter for specialized PCs needing equipment relationships
If needsRelationshipFilter = "1" Then
whereClause = whereClause & "AND m.machinetypeid IN (41, 42, 43) " & _
"AND NOT EXISTS (SELECT 1 FROM machinerelationships mr WHERE (mr.machineid = m.machineid OR mr.related_machineid = m.machineid) AND mr.relationshiptypeid = 3 AND mr.isactive = 1) "
End If
strSQL = strSQL & whereClause & "GROUP BY m.machineid ORDER BY m.machinenumber ASC, m.hostname ASC" strSQL = strSQL & whereClause & "GROUP BY m.machineid ORDER BY m.machinenumber ASC, m.hostname ASC"
set rs = objconn.Execute(strSQL) set rs = objconn.Execute(strSQL)
@@ -138,8 +173,7 @@ Set rsStatus = Nothing
%> %>
<tr> <tr>
<td><a href="./displaypc.asp?pcid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><% <td><a href="./displaypc.asp?machineid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><%
Dim displayName
If IsNull(rs("hostname")) Or rs("hostname") = "" Then If IsNull(rs("hostname")) Or rs("hostname") = "" Then
displayName = rs("serialnumber") displayName = rs("serialnumber")
Else Else
@@ -150,6 +184,45 @@ Set rsStatus = Nothing
<td><%Response.Write(rs("serialnumber"))%></td> <td><%Response.Write(rs("serialnumber"))%></td>
<td><%Response.Write(rs("modelnumber"))%></td> <td><%Response.Write(rs("modelnumber"))%></td>
<td><%Response.Write(rs("operatingsystem"))%></td> <td><%Response.Write(rs("operatingsystem"))%></td>
<td><%
' Equipment relationship column
If Not IsNull(rs("equipment_id")) And rs("equipment_id") <> "" Then
Response.Write("<a href=""./displaymachine.asp?machineid=" & rs("equipment_id") & """ title=""View Equipment"">" & Server.HTMLEncode(rs("equipment_number") & "") & "</a>")
Else
Response.Write("<span class='text-muted'>-</span>")
End If
%></td>
<td><%
' VNC column with link
hasVnc = False
If Not IsNull(rs("isvnc")) Then
If rs("isvnc") = True Or rs("isvnc") = 1 Or rs("isvnc") = -1 Then
hasVnc = True
End If
End If
If hasVnc And Not IsNull(rs("hostname")) And rs("hostname") <> "" Then
vncHost = rs("hostname") & ".logon.ds.ge.com"
Response.Write("<a href=""vnc://" & Server.HTMLEncode(vncHost) & """ title=""Connect via VNC""><span class='badge badge-success'>VNC</span></a>")
ElseIf hasVnc Then
Response.Write("<span class='badge badge-warning' title='VNC enabled but no hostname'>VNC</span>")
Else
Response.Write("<span class='text-muted'>-</span>")
End If
%></td>
<td><%
' WinRM column
hasWinrm = False
If Not IsNull(rs("iswinrm")) Then
If rs("iswinrm") = True Or rs("iswinrm") = 1 Or rs("iswinrm") = -1 Then
hasWinrm = True
End If
End If
If hasWinrm Then
Response.Write("<span class='badge badge-success' title='WinRM enabled'>WinRM</span>")
Else
Response.Write("<span class='text-muted'>-</span>")
End If
%></td>
</tr> </tr>
<% <%

View File

@@ -477,6 +477,13 @@ End If
<input class="form-control" type="text" name="printercsfname" value="<%=Server.HTMLEncode(rs("printercsfname") & "")%>" placeholder="<%=Server.HTMLEncode(rs("printercsfname") & "")%>"> <input class="form-control" type="text" name="printercsfname" value="<%=Server.HTMLEncode(rs("printercsfname") & "")%>" placeholder="<%=Server.HTMLEncode(rs("printercsfname") & "")%>">
</div> </div>
</div> </div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">PIN:</label>
<div class="col-lg-9">
<input class="form-control" type="text" name="printerpin" maxlength="10" value="<%=Server.HTMLEncode(rs("printerpin") & "")%>" placeholder="e.g., 012345">
<small class="form-text text-muted">Leading zeros are preserved</small>
</div>
</div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Windows Name:</label> <label class="col-lg-3 col-form-label form-control-label">Windows Name:</label>
<div class="col-lg-9"> <div class="col-lg-9">

View File

@@ -2,7 +2,9 @@
<html lang="en"> <html lang="en">
<head> <head>
<!--#include file="./includes/header.asp"--> <!--#include file="./includes/header.asp"-->
<!--#include file="./includes/wjf_employees-sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!-- DataTables CSS -->
<link rel="stylesheet" href="assets/plugins/datatables/dataTables.bootstrap4.min.css">
</head> </head>
<% <%
@@ -11,19 +13,22 @@
theme="bg-theme1" theme="bg-theme1"
END IF END IF
sso = Request.Querystring("sso") ' Get SSO parameter
Dim ssoParam
ssoParam = Trim(Request.QueryString("sso"))
' Validate SSO - must be 9 digits
Dim validSSO
validSSO = False
If ssoParam <> "" And Len(ssoParam) = 9 And IsNumeric(ssoParam) Then
validSSO = True
End If
%> %>
<body class="bg-theme <%Response.Write(theme)%>"> <body class="bg-theme <%Response.Write(theme)%>">
<!-- start loader --> <!-- start loader -->
<div id="pageloader-overlay" class="visible incoming"> <div id="pageloader-overlay" class="visible incoming"><div class="loader-wrapper-outer"><div class="loader-wrapper-inner" ><div class="loader"></div></div></div></div>
<div class="loader-wrapper-outer">
<div class="loader-wrapper-inner">
<div class="loader"></div>
</div>
</div>
</div>
<!-- end loader --> <!-- end loader -->
<!-- Start wrapper--> <!-- Start wrapper-->
<div id="wrapper"> <div id="wrapper">
@@ -31,318 +36,311 @@
<!--Start topbar header--> <!--Start topbar header-->
<!--#include file="./includes/topbarheader.asp"--> <!--#include file="./includes/topbarheader.asp"-->
<!--End topbar header--> <!--End topbar header-->
<body class="bg-theme <%Response.Write(theme)%>">
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="container-fluid"> <div class="container-fluid">
<%
If Not validSSO Then
%>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-lg-4"> <div class="col-12">
<div class="card profile-card-1"> <div class="card">
<div class="card-img-block"> <div class="card-body text-center">
<i class="zmdi zmdi-alert-circle zmdi-hc-4x text-warning"></i>
<% <h4 class="mt-3">Invalid SSO</h4>
<p class="text-muted">Please provide a valid 9-digit SSO number.</p>
strSQL = "SELECT * from employees WHERE SSO="&sso <a href="./default.asp" class="btn btn-primary">Go to Dashboard</a>
set rs = objconn.Execute(strSQL)
if rs.eof THEN
strSQL = "SELECT * from employees WHERE SSO=1"
set rs = objconn.Execute(strSQL)
END IF
%>
<img class="img-fluid" src="https://tsgwp00525.rd.ds.ge.com/EmployeeDBAPP/images/<%Response.Write(rs("Picture"))%>" alt="Card image cap">
</div>
<div class="card-body pt-5">
<h5 class="card-title"><%Response.Write(rs("First_Name"))%>&nbsp;<%Response.Write(rs("Last_Name"))%></h5>
</div>
<%
' Easter Eggs for special SSOs
Dim showEasterEgg, easterEggType
showEasterEgg = False
easterEggType = ""
On Error Resume Next
IF IsNumeric(sso) THEN
IF CLng(sso) = 570005354 THEN
showEasterEgg = True
easterEggType = "developer"
ELSEIF CLng(sso) = 503432774 THEN
showEasterEgg = True
easterEggType = "documentation"
END IF
END IF
On Error Goto 0
IF showEasterEgg AND easterEggType = "developer" THEN
%>
<div class="card-body border-top border-light">
<div class="text-center mb-3">
<h6 class="text-warning"><i class="zmdi zmdi-star"></i> ACHIEVEMENT UNLOCKED <i class="zmdi zmdi-star"></i></h6>
<small class="text-muted">Secret Developer Stats</small>
</div>
<div class="media align-items-center">
<div><i class="zmdi zmdi-coffee" style="font-size: 40px; color: #8B4513;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Caffeine Consumption<span class="float-right">147%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-warning" style="width:100%"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-bug" style="font-size: 40px; color: #28a745;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Bug Fixing Speed<span class="float-right">95%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-success" style="width:95%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-code" style="font-size: 40px; color: #17a2b8;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Google-Fu<span class="float-right">99%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-info" style="width:99%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-storage" style="font-size: 40px; color: #007bff;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Database Tinkering<span class="float-right">88%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-primary" style="width:88%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-fire" style="font-size: 40px; color: #dc3545;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Debugging<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-danger" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-shield-check" style="font-size: 40px; color: #ffc107;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Production Deployment Courage<span class="float-right">73%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-warning" style="width:73%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="text-center mt-3">
<span class="badge badge-danger m-1">Legacy Code Archaeologist</span>
<span class="badge badge-info m-1">Documentation Writer (Rare!)</span>
</div>
</div>
<% <%
ELSEIF showEasterEgg AND easterEggType = "documentation" THEN Else
%> ' Look up person in appowners table
<div class="card-body border-top border-light"> Dim cmdOwner, rsOwner, personName
<div class="text-center mb-3"> Dim ownerSQL
<h6 class="text-primary"><i class="zmdi zmdi-star"></i> LEGEND STATUS UNLOCKED <i class="zmdi zmdi-star"></i></h6> ownerSQL = "SELECT appowner FROM appowners WHERE sso = ? AND isactive = 1"
<small class="text-muted">The Foundation Builder</small>
</div>
<div class="media align-items-center">
<div><i class="zmdi zmdi-book" style="font-size: 40px; color: #007bff;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Documentation Mastery<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-primary" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-assignment-check" style="font-size: 40px; color: #28a745;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Playbook Creation<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-success" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-wrench" style="font-size: 40px; color: #17a2b8;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Shopfloor Support<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-info" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-settings" style="font-size: 40px; color: #6c757d;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>CNC Procedure Expertise<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-secondary" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-time" style="font-size: 40px; color: #ffc107;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Reliability<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-warning" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><i class="zmdi zmdi-flash" style="font-size: 40px; color: #dc3545;"></i></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Work Ethic<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar bg-danger" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="text-center mt-3">
<span class="badge badge-primary m-1">Knowledge Architect</span>
<span class="badge badge-success m-1">Procedure Master</span>
<span class="badge badge-info m-1">Shopfloor Expertise</span>
</div>
<div class="text-center mt-3">
<p class="text-muted mb-1"><i>"The procedures you built will keep this place running long after you're gone."</i></p>
<small class="text-muted">Thank you for the heavy lifting. You built the foundation we all stand on.</small>
</div>
</div>
<%
ELSE
%>
<div class="card-body border-top border-light">
<div class="media align-items-center">
<div>
<img src="./images/skills/atm.jpg" class="skill-img" alt="Advanced Technical Machinist">
</div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Advanced Technical Machinist<span class="float-right">100%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar" style="width:100%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><img src="assets/images/timeline/bootstrap-4.svg" class="skill-img" alt="skill img"></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>Bootstrap 4 <span class="float-right">50%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar" style="width:50%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><img src="assets/images/timeline/angular-icon.svg" class="skill-img" alt="skill img"></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>AngularJS <span class="float-right">70%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar" style="width:70%"></div>
</div>
</div>
</div>
</div>
<hr>
<div class="media align-items-center">
<div><img src="assets/images/timeline/react.svg" class="skill-img" alt="skill img"></div>
<div class="media-body text-left ml-3">
<div class="progress-wrapper">
<p>React JS <span class="float-right">35%</span></p>
<div class="progress" style="height: 5px;">
<div class="progress-bar" style="width:35%"></div>
</div>
</div>
</div>
</div>
</div> Set cmdOwner = Server.CreateObject("ADODB.Command")
<% cmdOwner.ActiveConnection = objConn
END IF cmdOwner.CommandText = ownerSQL
cmdOwner.CommandType = 1
cmdOwner.Parameters.Append cmdOwner.CreateParameter("@sso", 200, 1, 20, ssoParam)
Set rsOwner = cmdOwner.Execute
If Not rsOwner.EOF Then
personName = rsOwner("appowner") & ""
Else
personName = ""
End If
rsOwner.Close
Set rsOwner = Nothing
Set cmdOwner = Nothing
' Get USB checkout statistics
Dim cmdStats, rsStats
Dim totalCheckouts, activeCheckouts, avgDuration
Dim statsSQL
statsSQL = "SELECT " & _
"COUNT(*) AS total_checkouts, " & _
"SUM(CASE WHEN checkin_time IS NULL THEN 1 ELSE 0 END) AS active_checkouts, " & _
"AVG(TIMESTAMPDIFF(MINUTE, checkout_time, COALESCE(checkin_time, NOW()))) AS avg_duration " & _
"FROM usb_checkouts WHERE sso = ?"
Set cmdStats = Server.CreateObject("ADODB.Command")
cmdStats.ActiveConnection = objConn
cmdStats.CommandText = statsSQL
cmdStats.CommandType = 1
cmdStats.Parameters.Append cmdStats.CreateParameter("@sso", 200, 1, 20, ssoParam)
Set rsStats = cmdStats.Execute
If Not rsStats.EOF Then
If IsNull(rsStats("total_checkouts")) Or rsStats("total_checkouts") = "" Then
totalCheckouts = 0
Else
totalCheckouts = CLng(rsStats("total_checkouts"))
End If
If IsNull(rsStats("active_checkouts")) Or rsStats("active_checkouts") = "" Then
activeCheckouts = 0
Else
activeCheckouts = CLng(rsStats("active_checkouts"))
End If
If IsNull(rsStats("avg_duration")) Or rsStats("avg_duration") = "" Then
avgDuration = 0
Else
avgDuration = CLng(rsStats("avg_duration"))
End If
Else
totalCheckouts = 0
activeCheckouts = 0
avgDuration = 0
End If
rsStats.Close
Set rsStats = Nothing
Set cmdStats = Nothing
' Format average duration
Dim avgDurationText
If avgDuration < 60 Then
avgDurationText = avgDuration & " min"
ElseIf avgDuration < 1440 Then
avgDurationText = Int(avgDuration / 60) & "h " & (avgDuration Mod 60) & "m"
Else
avgDurationText = Int(avgDuration / 1440) & "d " & Int((avgDuration Mod 1440) / 60) & "h"
End If
%> %>
</div>
</div> <div class="row mt-3">
<div class="col-12">
<div class="col-lg-8"> <!-- Profile Header -->
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified"> <div style="display: flex; align-items: center;">
<li class="nav-item"> <div style="width: 80px; height: 80px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-right: 20px;">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-user"></i> <span class="hidden-xs">Profile</span></a> <i class="zmdi zmdi-account zmdi-hc-3x" style="color: white;"></i>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Profile</h5>
<div class="row">
<div class="col-md-3">
<h6><%Response.Write(rs("First_Name"))%>&nbsp;<%Response.Write(rs("Last_Name"))%></h6>
<h6>SSO</h6>
<h6>Shift</h6>
<h6>Role</h6>
<h6>Team</h6>
<h6>PayNo</h6>
</div> </div>
<div class="col-md-6"> <div>
<h6>&nbsp;<h6> <% If personName <> "" Then %>
<h6><%Response.Write(rs("SSO"))%></h6> <h3 style="margin: 0;"><%=Server.HTMLEncode(personName)%></h3>
<h6><%Response.Write(rs("shift"))%></h6> <p class="text-muted" style="margin: 5px 0 0 0;">SSO: <code><%=Server.HTMLEncode(ssoParam)%></code></p>
<h6><%Response.Write(rs("Role"))%></h6> <% Else %>
<h6><%Response.Write(rs("Team"))%></h6> <h3 style="margin: 0;">SSO: <code><%=Server.HTMLEncode(ssoParam)%></code></h3>
<h6><%Response.Write(rs("Payno"))%></h6> <p class="text-muted" style="margin: 5px 0 0 0;">User not found in directory</p>
<% End If %>
</div> </div>
</div> </div>
<!--/row--> </div>
</div>
</div>
</div>
<div class="row mt-3">
<!-- USB Stats Cards -->
<div class="col-md-4">
<div class="card">
<div class="card-body text-center">
<i class="zmdi zmdi-usb zmdi-hc-3x text-primary"></i>
<h2 class="mt-2"><%=totalCheckouts%></h2>
<p class="text-muted">Total USB Checkouts</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body text-center">
<% If activeCheckouts > 0 Then %>
<i class="zmdi zmdi-time zmdi-hc-3x text-warning"></i>
<% Else %>
<i class="zmdi zmdi-check-circle zmdi-hc-3x text-success"></i>
<% End If %>
<h2 class="mt-2"><%=activeCheckouts%></h2>
<p class="text-muted">Currently Checked Out</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body text-center">
<i class="zmdi zmdi-timer zmdi-hc-3x text-info"></i>
<h2 class="mt-2"><%=avgDurationText%></h2>
<p class="text-muted">Avg Checkout Duration</p>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<i class="zmdi zmdi-time"></i> USB Checkout History
</h5>
<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">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>
<%
' Get USB checkout history for this SSO
Dim cmdHistory, rsHistory
Dim historySQL
historySQL = "SELECT uc.*, m.serialnumber, m.alias, " & _
"TIMESTAMPDIFF(MINUTE, uc.checkout_time, COALESCE(uc.checkin_time, NOW())) AS duration_minutes " & _
"FROM usb_checkouts uc " & _
"JOIN machines m ON uc.machineid = m.machineid " & _
"WHERE uc.sso = ? " & _
"ORDER BY uc.checkout_time DESC"
Set cmdHistory = Server.CreateObject("ADODB.Command")
cmdHistory.ActiveConnection = objConn
cmdHistory.CommandText = historySQL
cmdHistory.CommandType = 1
cmdHistory.Parameters.Append cmdHistory.CreateParameter("@sso", 200, 1, 20, ssoParam)
Set rsHistory = cmdHistory.Execute
Dim rowCount
rowCount = 0
While Not rsHistory.EOF
rowCount = rowCount + 1
Dim serialNum, usbAlias, checkoutTime, checkinTime, durationMinutes, reason
Dim durationText, wipedText, statusClass
serialNum = rsHistory("serialnumber") & ""
usbAlias = rsHistory("alias") & ""
reason = rsHistory("checkout_reason") & ""
If IsNull(rsHistory("duration_minutes")) Or rsHistory("duration_minutes") = "" Then
durationMinutes = 0
Else
durationMinutes = CLng(rsHistory("duration_minutes"))
End If
' Format checkout time (MM/DD/YYYY h:mm AM/PM)
If Not IsNull(rsHistory("checkout_time")) Then
checkoutTime = Month(rsHistory("checkout_time")) & "/" & Day(rsHistory("checkout_time")) & "/" & Year(rsHistory("checkout_time")) & " " & FormatDateTime(rsHistory("checkout_time"), 3)
Else
checkoutTime = "-"
End If
' Format check-in time and determine status (MM/DD/YYYY h:mm AM/PM)
If Not IsNull(rsHistory("checkin_time")) Then
checkinTime = Month(rsHistory("checkin_time")) & "/" & Day(rsHistory("checkin_time")) & "/" & Year(rsHistory("checkin_time")) & " " & FormatDateTime(rsHistory("checkin_time"), 3)
statusClass = ""
Else
checkinTime = "<span class='badge badge-warning'>Still Out</span>"
statusClass = "table-warning"
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(rsHistory("was_wiped")) Then
wipedText = "-"
ElseIf rsHistory("was_wiped") = 1 Then
wipedText = "<span class='badge badge-success'>Yes</span>"
Else
wipedText = "<span class='badge badge-danger'>No</span>"
End If
%>
<tr class="<%=statusClass%>">
<td>
<a href="./usb_history.asp?machineid=<%=rsHistory("machineid")%>" title="View all checkouts for this device">
<code><%=Server.HTMLEncode(serialNum)%></code>
</a>
</td>
<td><%=Server.HTMLEncode(usbAlias)%></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>
<%
rsHistory.MoveNext
Wend
rsHistory.Close
Set rsHistory = Nothing
Set cmdHistory = Nothing
If rowCount = 0 Then
%>
<tr>
<td colspan="7" class="text-center text-muted">
<i class="zmdi zmdi-info zmdi-hc-2x"></i><br>
No USB checkout history for this SSO.
</td>
</tr>
<%
End If
%>
</tbody>
</table>
</div>
<div class="mt-3">
<a href="./usb_history.asp?sso=<%=Server.URLEncode(ssoParam)%>" class="btn btn-outline-primary btn-sm">
<i class="zmdi zmdi-open-in-new"></i> View in Full History
</a>
<a href="./displayusb.asp" class="btn btn-outline-secondary btn-sm">
<i class="zmdi zmdi-usb"></i> USB Devices
</a>
</div> </div>
</div> </div>
@@ -350,15 +348,14 @@ END IF
</div> </div>
</div> </div>
</div> <%
End If ' validSSO
<!--start overlay--> %>
<div class="overlay toggle-menu"></div>
<!--end overlay-->
</div> </div>
<!-- End container-fluid--> <!-- End container-fluid-->
</div><!--End content-wrapper--> </div><!--End content-wrapper-->
<!--Start Back To Top Button--> <!--Start Back To Top Button-->
<a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i> </a> <a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i> </a>
<!--End Back To Top Button--> <!--End Back To Top Button-->
@@ -373,7 +370,6 @@ END IF
<!--End footer--> <!--End footer-->
</div><!--End wrapper--> </div><!--End wrapper-->
<!-- Bootstrap core JavaScript--> <!-- Bootstrap core JavaScript-->
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script> <script src="assets/js/popper.min.js"></script>
@@ -384,12 +380,24 @@ END IF
<!-- sidebar-menu js --> <!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script> <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 --> <!-- Custom scripts -->
<script src="assets/js/app-script.js"></script> <script src="assets/js/app-script.js"></script>
<script>
$(document).ready(function() {
$('#historyTable').DataTable({
"order": [[2, "desc"]], // Sort by checkout time descending
"pageLength": 25,
"language": {
"emptyTable": "No checkout history found"
}
});
});
</script>
</body> </body>
</html> </html>
<%
objconn.close
%>

View File

@@ -1,677 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim serverid
serverid = Request.Querystring("id")
If Not IsNumeric(serverid) Then
Response.Redirect("network_devices.asp?filter=Server")
Response.End
End If
strSQL = "SELECT s.*, m.modelnumber, v.vendor " & _
"FROM servers s " & _
"LEFT JOIN models m ON s.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE s.serverid = " & CLng(serverid)
set rs = objconn.Execute(strSQL)
If rs.EOF Then
Response.Write("Server not found")
objConn.Close
Response.End
End If
%>
<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-lg-4">
<div class="card profile-card-2">
<div class="card-img-block">
<img class="img-fluid" src="./images/devices/server.png" alt="Server">
</div>
<div class="card-body pt-5">
<img src="./images/devices/server.png" alt="Server" class="profile">
<h5 class="card-title"><%Response.Write(Server.HTMLEncode(rs("servername")))%></h5>
<p class="card-text">
<%
If Not IsNull(rs("vendor")) And Not IsNull(rs("modelnumber")) Then
Response.Write(Server.HTMLEncode(rs("vendor") & " " & rs("modelnumber")))
Else
Response.Write("Server")
End If
%>
</p>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified">
<li class="nav-item">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-wrench"></i> <span class="hidden-xs">Settings</span></a>
</li>
<li class="nav-item">
<a href="javascript:void();" data-target="#edit" data-toggle="pill" class="nav-link"><i class="icon-note"></i> <span class="hidden-xs">Edit</span></a>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Configuration</h5>
<div class="row">
<div class="col-md-3">
<p class="mb-2"><strong>Name:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p>
<p class="mb-2"><strong>Serial:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>Description:</strong></p>
<p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
</div>
<div class="col-md-9">
<p class="mb-2"><%Response.Write(Server.HTMLEncode(rs("servername")))%></p>
<p class="mb-2">
<%
If Not IsNull(rs("vendor")) And rs("vendor") <> "" Then
Response.Write(Server.HTMLEncode(rs("vendor")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("modelnumber")) And rs("modelnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("modelnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("serialnumber")) And rs("serialnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("serialnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" Then
Response.Write("<a href='http://" & Server.HTMLEncode(rs("ipaddress")) & "' target='_blank'>" & Server.HTMLEncode(rs("ipaddress")) & "</a>")
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("description")) And rs("description") <> "" Then
Response.Write(Server.HTMLEncode(rs("description")))
Else
Response.Write("<em class='text-muted'>No description</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
%>
<span class="location-link" data-serverid="<%Response.Write(serverid)%>" style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>View on Map
</span>
<%
Else
Response.Write("<em class='text-muted'>No location set</em>")
End If
%>
</p>
<p class="mb-2">
<%
If rs("isactive") Then
Response.Write("<span class='badge badge-success'>Active</span>")
Else
Response.Write("<span class='badge badge-secondary'>Inactive</span>")
End If
%>
</p>
</div>
</div>
<!--/row-->
</div>
<div class="tab-pane" id="edit">
<form method="post" action="./save_network_device.asp">
<input type="hidden" name="type" value="server">
<input type="hidden" name="id" value="<%=serverid%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Server Name <span class="text-danger">*</span></label>
<div class="col-lg-9">
<input type="text" name="servername" class="form-control"
value="<%=Server.HTMLEncode(rs("servername"))%>"
required maxlength="100"
placeholder="e.g., DB-Server-01">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Model</label>
<div class="col-lg-9">
<div class="input-group">
<select name="modelid" id="modelid_edit" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
selected = ""
If Not IsNull(rs("modelid")) And rs("modelid") <> "" Then
If CStr(rsModels("modelnumberid")) = CStr(rs("modelid")) Then
selected = "selected"
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
<option value="new">+ Add New Model</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addModelBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">Select a model or click "New" to add one</small>
</div>
</div>
<!-- Hidden section for adding new model -->
<div id="newModelSection_edit" class="form-group row" style="display:none;">
<div class="col-lg-9 offset-lg-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Model</h6>
<div class="form-group">
<label for="newmodelnumber_edit">Model Number <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmodelnumber_edit" name="newmodelnumber"
maxlength="255" placeholder="e.g., PowerEdge R740">
</div>
<div class="form-group">
<label for="newvendorid_edit">Vendor <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newvendorid_edit" name="newvendorid">
<option value="">-- Select Vendor --</option>
<%
Dim rsVendors
strSQL2 = "SELECT vendorid, vendor FROM vendors WHERE isactive = 1 ORDER BY vendor ASC"
Set rsVendors = objConn.Execute(strSQL2)
While Not rsVendors.EOF
Response.Write("<option value='" & rsVendors("vendorid") & "'>" & Server.HTMLEncode(rsVendors("vendor")) & "</option>")
rsVendors.MoveNext
Wend
rsVendors.Close
Set rsVendors = Nothing
%>
<option value="new">+ Add New Vendor</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addVendorBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new vendor -->
<div id="newVendorSection_edit" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Vendor</h6>
<div class="form-group">
<label for="newvendorname_edit">Vendor Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newvendorname_edit" name="newvendorname"
maxlength="50" placeholder="e.g., Dell, HP, Cisco">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewVendor_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelnotes_edit">Model Notes</label>
<textarea class="form-control" id="newmodelnotes_edit" name="newmodelnotes"
rows="2" maxlength="255"
placeholder="Additional notes about this model..."></textarea>
</div>
<div class="form-group">
<label for="newmodeldocpath_edit">Documentation Path</label>
<input type="text" class="form-control" id="newmodeldocpath_edit" name="newmodeldocpath"
maxlength="255" placeholder="\\server\docs\model.pdf or http://...">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewModel_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Serial Number</label>
<div class="col-lg-9">
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(rs("serialnumber"))%>"
maxlength="100" placeholder="e.g., SN123456789">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IP Address</label>
<div class="col-lg-9">
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(rs("ipaddress"))%>"
maxlength="45" pattern="^[0-9\.:]*$"
placeholder="e.g., 192.168.1.100">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Description</label>
<div class="col-lg-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes..."><%=Server.HTMLEncode(rs("description"))%></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label"></label>
<div class="col-lg-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If rs("isactive") = True Or rs("isactive") = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
</div>
</div>
<!-- Hidden coordinate fields -->
<input type="hidden" id="maptop" name="maptop" value="<%=rs("maptop")%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=rs("mapleft")%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Map Position</label>
<div class="col-lg-9">
<button type="button" class="btn btn-secondary btn-sm" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
Response.Write("Current position: X=" & rs("mapleft") & ", Y=" & rs("maptop"))
Else
Response.Write("No position set - click button to select")
End If
%>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-9 offset-lg-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<a href="network_devices.asp?filter=Server" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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">
</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>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<style>
.location-popup-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
}
.location-popup {
display: none;
position: fixed;
background: #2a2a2a;
border-radius: 6px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
z-index: 9999;
overflow: hidden;
border: 1px solid #444;
}
.location-popup-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #444;
}
.location-popup-close {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 0;
transition: background 0.2s;
}
.location-popup-close:hover {
background: rgba(255,255,255,0.3);
}
.location-popup-body {
padding: 0;
}
.location-popup iframe {
display: block;
border: none;
}
/* Theme-specific link colors */
body.bg-theme1 .location-link,
body.bg-theme2 .location-link,
body.bg-theme3 .location-link,
body.bg-theme4 .location-link,
body.bg-theme5 .location-link,
body.bg-theme6 .location-link { color: #007bff !important; }
body.bg-theme7 .location-link { color: #17a2b8 !important; }
body.bg-theme8 .location-link { color: #ffc107 !important; }
body.bg-theme9 .location-link { color: #6c757d !important; }
body.bg-theme10 .location-link { color: #8b6f47 !important; }
body.bg-theme11 .location-link { color: #42a5f5 !important; }
body.bg-theme12 .location-link { color: #ab47bc !important; }
body.bg-theme13 .location-link { color: #ef5350 !important; }
body.bg-theme14 .location-link { color: #66bb6a !important; }
body.bg-theme15 .location-link { color: #5c6bc0 !important; }
body.bg-theme16 .location-link { color: #9c27b0 !important; }
</style>
<script>
$(document).ready(function() {
// Create popup elements
var $overlay = $('<div class="location-popup-overlay"></div>').appendTo('body');
var $popup = $('<div class="location-popup"></div>').appendTo('body');
$popup.html(
'<div class="location-popup-header">' +
'<h6 style="margin:0; font-size:16px;"><i class="zmdi zmdi-pin"></i> <span class="location-title">Loading...</span></h6>' +
'<button class="location-popup-close" title="Close (Esc)">&times;</button>' +
'</div>' +
'<div class="location-popup-body">' +
'<iframe src="" width="440" height="340"></iframe>' +
'</div>'
);
var $iframe = $popup.find('iframe');
var $title = $popup.find('.location-title');
var currentServerId = null;
// Function to show popup with smart positioning
function showLocationPopup(serverId, locationName, mouseEvent) {
if (currentServerId === serverId && $popup.is(':visible')) {
return;
}
currentServerId = serverId;
$title.text('Server ' + locationName);
$iframe.attr('src', './displaylocation.asp?type=server&id=' + serverId);
// Position popup using viewport coordinates
var popupWidth = 440;
var popupHeight = 400;
var mouseX = mouseEvent.clientX;
var mouseY = mouseEvent.clientY;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var left, top;
// Horizontal positioning
left = mouseX + 10;
if (left + popupWidth > windowWidth - 10) {
left = mouseX - popupWidth - 10;
}
if (left < 10) {
left = 10;
}
// Vertical positioning
top = mouseY - 50;
if (top + popupHeight > windowHeight - 10) {
top = windowHeight - popupHeight - 10;
}
if (top < 10) {
top = 10;
}
$popup.css({
left: left + 'px',
top: top + 'px',
display: 'block'
});
$overlay.fadeIn(200);
$popup.fadeIn(200);
}
function hideLocationPopup() {
$overlay.fadeOut(200);
$popup.fadeOut(200);
setTimeout(function() {
$iframe.attr('src', '');
currentServerId = null;
}, 200);
}
var hoverTimer = null;
$('.location-link').on('mouseenter', function(e) {
var $link = $(this);
var serverId = $link.data('serverid');
var locationName = $link.text().trim();
var mouseEvent = e;
if (hoverTimer) {
clearTimeout(hoverTimer);
}
hoverTimer = setTimeout(function() {
showLocationPopup(serverId, locationName, mouseEvent);
}, 300);
});
$('.location-link').on('mouseleave', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$overlay.on('click', hideLocationPopup);
$('.location-popup-close').on('click', hideLocationPopup);
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $popup.is(':visible')) {
hideLocationPopup();
}
});
$popup.on('mouseenter', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$popup.on('mouseleave', function() {
hideLocationPopup();
});
// Model/Vendor nested add functionality for Edit tab
$('#addModelBtn_edit, #modelid_edit').on('change click', function() {
if ($('#modelid_edit').val() === 'new' || $(this).attr('id') === 'addModelBtn_edit') {
$('#modelid_edit').val('new');
$('#newModelSection_edit').slideDown();
$('#newmodelnumber_edit').prop('required', true);
$('#newvendorid_edit').prop('required', true);
}
});
$('#cancelNewModel_edit').on('click', function() {
$('#newModelSection_edit').slideUp();
$('#newVendorSection_edit').slideUp();
$('#modelid_edit').val('');
$('#newmodelnumber_edit').val('').prop('required', false);
$('#newvendorid_edit').val('').prop('required', false);
$('#newmodelnotes_edit').val('');
$('#newmodeldocpath_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Show/hide new vendor section for Edit tab
$('#addVendorBtn_edit, #newvendorid_edit').on('change click', function() {
if ($('#newvendorid_edit').val() === 'new' || $(this).attr('id') === 'addVendorBtn_edit') {
$('#newvendorid_edit').val('new');
$('#newVendorSection_edit').slideDown();
$('#newvendorname_edit').prop('required', true);
}
});
$('#cancelNewVendor_edit').on('click', function() {
$('#newVendorSection_edit').slideUp();
$('#newvendorid_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Form validation for Edit tab
$('form').on('submit', function(e) {
if ($('#modelid_edit').val() === 'new') {
if ($('#newmodelnumber_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a model number or select an existing model');
$('#newmodelnumber_edit').focus();
return false;
}
if ($('#newvendorid_edit').val() === '' || $('#newvendorid_edit').val() === 'new') {
if ($('#newvendorid_edit').val() === 'new') {
if ($('#newvendorname_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a vendor name or select an existing vendor');
$('#newvendorname_edit').focus();
return false;
}
} else {
e.preventDefault();
alert('Please select a vendor or add a new one');
$('#newvendorid_edit').focus();
return false;
}
}
}
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
rs.Close
Set rs = Nothing
objConn.Close
%>

View File

@@ -27,12 +27,12 @@
'-------------------------------------------------------Is this the IP address of a PC--------------------------------------------------- '-------------------------------------------------------Is this the IP address of a PC---------------------------------------------------
IF search <> "" THEN IF search <> "" THEN
' PHASE 2: Query communications table instead of pc_network_interfaces ' PHASE 2: Query communications table instead of pc_network_interfaces
strSQL = "SELECT c.machineid FROM communications c JOIN machines m ON c.machineid = m.machineid WHERE c.address='" &search &"' AND m.pctypeid IS NOT NULL LIMIT 1" strSQL = "SELECT c.machineid FROM communications c JOIN machines m ON c.machineid = m.machineid WHERE c.address='" &search &"' AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) LIMIT 1"
set rs = objconn.Execute(strSQL) set rs = objconn.Execute(strSQL)
IF NOT rs.EOF THEN IF NOT rs.EOF THEN
pcid = rs("machineid") machineid = rs("machineid")
objConn.Close objConn.Close
Response.Redirect "./displaypc.asp?pcid="&pcid Response.Redirect "./displaypc.asp?machineid="&machineid
END IF END IF
END IF END IF

View File

@@ -1,677 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim switchid
switchid = Request.Querystring("id")
If Not IsNumeric(switchid) Then
Response.Redirect("network_devices.asp?filter=Switch")
Response.End
End If
strSQL = "SELECT s.*, m.modelnumber, v.vendor " & _
"FROM switches s " & _
"LEFT JOIN models m ON s.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE s.switchid = " & CLng(switchid)
set rs = objconn.Execute(strSQL)
If rs.EOF Then
Response.Write("Switch not found")
objConn.Close
Response.End
End If
%>
<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-lg-4">
<div class="card profile-card-2">
<div class="card-img-block">
<img class="img-fluid" src="./images/devices/switch.png" alt="Switch">
</div>
<div class="card-body pt-5">
<img src="./images/devices/switch.png" alt="Switch" class="profile">
<h5 class="card-title"><%Response.Write(Server.HTMLEncode(rs("switchname")))%></h5>
<p class="card-text">
<%
If Not IsNull(rs("vendor")) And Not IsNull(rs("modelnumber")) Then
Response.Write(Server.HTMLEncode(rs("vendor") & " " & rs("modelnumber")))
Else
Response.Write("Switch")
End If
%>
</p>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs nav-tabs-primary top-icon nav-justified">
<li class="nav-item">
<a href="javascript:void();" data-target="#profile" data-toggle="pill" class="nav-link active"><i class="icon-wrench"></i> <span class="hidden-xs">Settings</span></a>
</li>
<li class="nav-item">
<a href="javascript:void();" data-target="#edit" data-toggle="pill" class="nav-link"><i class="icon-note"></i> <span class="hidden-xs">Edit</span></a>
</li>
</ul>
<div class="tab-content p-3">
<div class="tab-pane active" id="profile">
<h5 class="mb-3">Configuration</h5>
<div class="row">
<div class="col-md-3">
<p class="mb-2"><strong>Name:</strong></p>
<p class="mb-2"><strong>Vendor:</strong></p>
<p class="mb-2"><strong>Model:</strong></p>
<p class="mb-2"><strong>Serial:</strong></p>
<p class="mb-2"><strong>IP Address:</strong></p>
<p class="mb-2"><strong>Description:</strong></p>
<p class="mb-2"><strong>Location:</strong></p>
<p class="mb-2"><strong>Status:</strong></p>
</div>
<div class="col-md-9">
<p class="mb-2"><%Response.Write(Server.HTMLEncode(rs("switchname")))%></p>
<p class="mb-2">
<%
If Not IsNull(rs("vendor")) And rs("vendor") <> "" Then
Response.Write(Server.HTMLEncode(rs("vendor")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("modelnumber")) And rs("modelnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("modelnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("serialnumber")) And rs("serialnumber") <> "" Then
Response.Write(Server.HTMLEncode(rs("serialnumber")))
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" Then
Response.Write("<a href='http://" & Server.HTMLEncode(rs("ipaddress")) & "' target='_blank'>" & Server.HTMLEncode(rs("ipaddress")) & "</a>")
Else
Response.Write("<em class='text-muted'>Not specified</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("description")) And rs("description") <> "" Then
Response.Write(Server.HTMLEncode(rs("description")))
Else
Response.Write("<em class='text-muted'>No description</em>")
End If
%>
</p>
<p class="mb-2">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
%>
<span class="location-link" data-switchid="<%Response.Write(switchid)%>" style="cursor:pointer; color:#007bff;">
<i class="zmdi zmdi-pin" style="margin-right:4px;"></i>View on Map
</span>
<%
Else
Response.Write("<em class='text-muted'>No location set</em>")
End If
%>
</p>
<p class="mb-2">
<%
If rs("isactive") Then
Response.Write("<span class='badge badge-success'>Active</span>")
Else
Response.Write("<span class='badge badge-secondary'>Inactive</span>")
End If
%>
</p>
</div>
</div>
<!--/row-->
</div>
<div class="tab-pane" id="edit">
<form method="post" action="./save_network_device.asp">
<input type="hidden" name="type" value="switch">
<input type="hidden" name="id" value="<%=switchid%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Switch Name <span class="text-danger">*</span></label>
<div class="col-lg-9">
<input type="text" name="switchname" class="form-control"
value="<%=Server.HTMLEncode(rs("switchname"))%>"
required maxlength="100"
placeholder="e.g., Core-Switch-01">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Model</label>
<div class="col-lg-9">
<div class="input-group">
<select name="modelid" id="modelid_edit" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
selected = ""
If Not IsNull(rs("modelid")) And rs("modelid") <> "" Then
If CStr(rsModels("modelnumberid")) = CStr(rs("modelid")) Then
selected = "selected"
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
<option value="new">+ Add New Model</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addModelBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">Select a model or click "New" to add one</small>
</div>
</div>
<!-- Hidden section for adding new model -->
<div id="newModelSection_edit" class="form-group row" style="display:none;">
<div class="col-lg-9 offset-lg-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Model</h6>
<div class="form-group">
<label for="newmodelnumber_edit">Model Number <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmodelnumber_edit" name="newmodelnumber"
maxlength="255" placeholder="e.g., Catalyst 2960">
</div>
<div class="form-group">
<label for="newvendorid_edit">Vendor <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newvendorid_edit" name="newvendorid">
<option value="">-- Select Vendor --</option>
<%
Dim rsVendors
strSQL2 = "SELECT vendorid, vendor FROM vendors WHERE isactive = 1 ORDER BY vendor ASC"
Set rsVendors = objConn.Execute(strSQL2)
While Not rsVendors.EOF
Response.Write("<option value='" & rsVendors("vendorid") & "'>" & Server.HTMLEncode(rsVendors("vendor")) & "</option>")
rsVendors.MoveNext
Wend
rsVendors.Close
Set rsVendors = Nothing
%>
<option value="new">+ Add New Vendor</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addVendorBtn_edit">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new vendor -->
<div id="newVendorSection_edit" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Vendor</h6>
<div class="form-group">
<label for="newvendorname_edit">Vendor Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newvendorname_edit" name="newvendorname"
maxlength="50" placeholder="e.g., Cisco, Aruba, Juniper">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewVendor_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelnotes_edit">Model Notes</label>
<textarea class="form-control" id="newmodelnotes_edit" name="newmodelnotes"
rows="2" maxlength="255"
placeholder="Additional notes about this model..."></textarea>
</div>
<div class="form-group">
<label for="newmodeldocpath_edit">Documentation Path</label>
<input type="text" class="form-control" id="newmodeldocpath_edit" name="newmodeldocpath"
maxlength="255" placeholder="\\server\docs\model.pdf or http://...">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewModel_edit">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Serial Number</label>
<div class="col-lg-9">
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(rs("serialnumber"))%>"
maxlength="100" placeholder="e.g., SN123456789">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">IP Address</label>
<div class="col-lg-9">
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(rs("ipaddress"))%>"
maxlength="45" pattern="^[0-9\.:]*$"
placeholder="e.g., 192.168.1.100">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Description</label>
<div class="col-lg-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes..."><%=Server.HTMLEncode(rs("description"))%></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label"></label>
<div class="col-lg-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If rs("isactive") = True Or rs("isactive") = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
</div>
</div>
<!-- Hidden coordinate fields -->
<input type="hidden" id="maptop" name="maptop" value="<%=rs("maptop")%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=rs("mapleft")%>">
<div class="form-group row">
<label class="col-lg-3 col-form-label form-control-label">Map Position</label>
<div class="col-lg-9">
<button type="button" class="btn btn-secondary btn-sm" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%
If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) And rs("maptop") <> "" And rs("mapleft") <> "" Then
Response.Write("Current position: X=" & rs("mapleft") & ", Y=" & rs("maptop"))
Else
Response.Write("No position set - click button to select")
End If
%>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-9 offset-lg-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<a href="network_devices.asp?filter=Switch" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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">
</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>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<style>
.location-popup-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
}
.location-popup {
display: none;
position: fixed;
background: #2a2a2a;
border-radius: 6px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
z-index: 9999;
overflow: hidden;
border: 1px solid #444;
}
.location-popup-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #444;
}
.location-popup-close {
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
padding: 0;
transition: background 0.2s;
}
.location-popup-close:hover {
background: rgba(255,255,255,0.3);
}
.location-popup-body {
padding: 0;
}
.location-popup iframe {
display: block;
border: none;
}
/* Theme-specific link colors */
body.bg-theme1 .location-link,
body.bg-theme2 .location-link,
body.bg-theme3 .location-link,
body.bg-theme4 .location-link,
body.bg-theme5 .location-link,
body.bg-theme6 .location-link { color: #007bff !important; }
body.bg-theme7 .location-link { color: #17a2b8 !important; }
body.bg-theme8 .location-link { color: #ffc107 !important; }
body.bg-theme9 .location-link { color: #6c757d !important; }
body.bg-theme10 .location-link { color: #8b6f47 !important; }
body.bg-theme11 .location-link { color: #42a5f5 !important; }
body.bg-theme12 .location-link { color: #ab47bc !important; }
body.bg-theme13 .location-link { color: #ef5350 !important; }
body.bg-theme14 .location-link { color: #66bb6a !important; }
body.bg-theme15 .location-link { color: #5c6bc0 !important; }
body.bg-theme16 .location-link { color: #9c27b0 !important; }
</style>
<script>
$(document).ready(function() {
// Create popup elements
var $overlay = $('<div class="location-popup-overlay"></div>').appendTo('body');
var $popup = $('<div class="location-popup"></div>').appendTo('body');
$popup.html(
'<div class="location-popup-header">' +
'<h6 style="margin:0; font-size:16px;"><i class="zmdi zmdi-pin"></i> <span class="location-title">Loading...</span></h6>' +
'<button class="location-popup-close" title="Close (Esc)">&times;</button>' +
'</div>' +
'<div class="location-popup-body">' +
'<iframe src="" width="440" height="340"></iframe>' +
'</div>'
);
var $iframe = $popup.find('iframe');
var $title = $popup.find('.location-title');
var currentSwitchId = null;
// Function to show popup with smart positioning
function showLocationPopup(switchId, locationName, mouseEvent) {
if (currentSwitchId === switchId && $popup.is(':visible')) {
return;
}
currentSwitchId = switchId;
$title.text('Switch ' + locationName);
$iframe.attr('src', './displaylocation.asp?type=switch&id=' + switchId);
// Position popup using viewport coordinates
var popupWidth = 440;
var popupHeight = 400;
var mouseX = mouseEvent.clientX;
var mouseY = mouseEvent.clientY;
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var left, top;
// Horizontal positioning
left = mouseX + 10;
if (left + popupWidth > windowWidth - 10) {
left = mouseX - popupWidth - 10;
}
if (left < 10) {
left = 10;
}
// Vertical positioning
top = mouseY - 50;
if (top + popupHeight > windowHeight - 10) {
top = windowHeight - popupHeight - 10;
}
if (top < 10) {
top = 10;
}
$popup.css({
left: left + 'px',
top: top + 'px',
display: 'block'
});
$overlay.fadeIn(200);
$popup.fadeIn(200);
}
function hideLocationPopup() {
$overlay.fadeOut(200);
$popup.fadeOut(200);
setTimeout(function() {
$iframe.attr('src', '');
currentSwitchId = null;
}, 200);
}
var hoverTimer = null;
$('.location-link').on('mouseenter', function(e) {
var $link = $(this);
var switchId = $link.data('switchid');
var locationName = $link.text().trim();
var mouseEvent = e;
if (hoverTimer) {
clearTimeout(hoverTimer);
}
hoverTimer = setTimeout(function() {
showLocationPopup(switchId, locationName, mouseEvent);
}, 300);
});
$('.location-link').on('mouseleave', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$overlay.on('click', hideLocationPopup);
$('.location-popup-close').on('click', hideLocationPopup);
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $popup.is(':visible')) {
hideLocationPopup();
}
});
$popup.on('mouseenter', function() {
if (hoverTimer) {
clearTimeout(hoverTimer);
hoverTimer = null;
}
});
$popup.on('mouseleave', function() {
hideLocationPopup();
});
// Model/Vendor nested add functionality for Edit tab
$('#addModelBtn_edit, #modelid_edit').on('change click', function() {
if ($('#modelid_edit').val() === 'new' || $(this).attr('id') === 'addModelBtn_edit') {
$('#modelid_edit').val('new');
$('#newModelSection_edit').slideDown();
$('#newmodelnumber_edit').prop('required', true);
$('#newvendorid_edit').prop('required', true);
}
});
$('#cancelNewModel_edit').on('click', function() {
$('#newModelSection_edit').slideUp();
$('#newVendorSection_edit').slideUp();
$('#modelid_edit').val('');
$('#newmodelnumber_edit').val('').prop('required', false);
$('#newvendorid_edit').val('').prop('required', false);
$('#newmodelnotes_edit').val('');
$('#newmodeldocpath_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Show/hide new vendor section for Edit tab
$('#addVendorBtn_edit, #newvendorid_edit').on('change click', function() {
if ($('#newvendorid_edit').val() === 'new' || $(this).attr('id') === 'addVendorBtn_edit') {
$('#newvendorid_edit').val('new');
$('#newVendorSection_edit').slideDown();
$('#newvendorname_edit').prop('required', true);
}
});
$('#cancelNewVendor_edit').on('click', function() {
$('#newVendorSection_edit').slideUp();
$('#newvendorid_edit').val('');
$('#newvendorname_edit').val('').prop('required', false);
});
// Form validation for Edit tab
$('form').on('submit', function(e) {
if ($('#modelid_edit').val() === 'new') {
if ($('#newmodelnumber_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a model number or select an existing model');
$('#newmodelnumber_edit').focus();
return false;
}
if ($('#newvendorid_edit').val() === '' || $('#newvendorid_edit').val() === 'new') {
if ($('#newvendorid_edit').val() === 'new') {
if ($('#newvendorname_edit').val().trim() === '') {
e.preventDefault();
alert('Please enter a vendor name or select an existing vendor');
$('#newvendorname_edit').focus();
return false;
}
} else {
e.preventDefault();
alert('Please select a vendor or add a new one');
$('#newvendorid_edit').focus();
return false;
}
}
}
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
rs.Close
Set rs = Nothing
objConn.Close
%>

270
displayusb.asp Normal file
View File

@@ -0,0 +1,270 @@
<!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
%>
<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">
<%
Dim showFilter
showFilter = Request.QueryString("filter")
If showFilter = "" Then showFilter = "all"
%>
<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-usb"></i> USB Devices
<% If showFilter = "available" Then %>
<span class="badge badge-success">Available Only</span>
<% ElseIf showFilter = "checkedout" Then %>
<span class="badge badge-warning">Checked Out Only</span>
<% Else %>
<span class="badge badge-info">All Devices</span>
<% End If %>
</h5>
<div>
<% If showFilter <> "all" Then %>
<a href="./displayusb.asp" class="btn btn-info btn-sm">
<i class="zmdi zmdi-view-list-alt"></i> Show All
</a>
<% End If %>
<% If showFilter <> "available" Then %>
<a href="./displayusb.asp?filter=available" class="btn btn-success btn-sm">
<i class="zmdi zmdi-check-circle"></i> Available Only
</a>
<% End If %>
<% If showFilter <> "checkedout" Then %>
<a href="./displayusb.asp?filter=checkedout" class="btn btn-warning btn-sm">
<i class="zmdi zmdi-time"></i> Checked Out
</a>
<% End If %>
<a href="./checkout_usb.asp" class="btn btn-primary btn-sm">
<i class="zmdi zmdi-arrow-right"></i> Checkout
</a>
<a href="./checkin_usb.asp" class="btn btn-secondary btn-sm">
<i class="zmdi zmdi-arrow-left"></i> Check-in
</a>
<a href="./addusb.asp" class="btn btn-success btn-sm">
<i class="zmdi zmdi-plus-circle"></i> Add USB
</a>
</div>
</div>
<div class="table-responsive">
<table id="usbTable" class="table table-hover table-striped">
<thead>
<tr>
<th scope="col">Serial Number</th>
<th scope="col">Name</th>
<th scope="col">Business Unit</th>
<th scope="col">Status</th>
<th scope="col">Current Holder</th>
<th scope="col">Checkout Time</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<%
Dim strSQL, rs
' Query USB devices with current checkout status
strSQL = "SELECT m.machineid, m.serialnumber, m.alias, bu.businessunit, " & _
"uc.checkoutid, uc.sso AS current_holder, uc.checkout_time, uc.checkout_reason, " & _
"CASE WHEN uc.checkoutid IS NOT NULL THEN 'Checked Out' ELSE 'Available' END AS status " & _
"FROM machines m " & _
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " & _
"LEFT JOIN usb_checkouts uc ON m.machineid = uc.machineid AND uc.checkin_time IS NULL " & _
"WHERE m.machinetypeid = 44 AND m.isactive = 1 "
' Apply filter
If showFilter = "available" Then
strSQL = strSQL & "AND uc.checkoutid IS NULL "
ElseIf showFilter = "checkedout" Then
strSQL = strSQL & "AND uc.checkoutid IS NOT NULL "
End If
strSQL = strSQL & "ORDER BY m.serialnumber ASC"
Set rs = objConn.Execute(strSQL)
Dim rowCount
rowCount = 0
While Not rs.EOF
rowCount = rowCount + 1
Dim machineId, serialNum, usbAlias, businessUnit, statusText, currentHolder, checkoutTime, checkoutReason
Dim statusClass, checkoutId
machineId = rs("machineid")
serialNum = rs("serialnumber") & ""
usbAlias = rs("alias") & ""
businessUnit = rs("businessunit") & ""
statusText = rs("status") & ""
currentHolder = rs("current_holder") & ""
checkoutId = rs("checkoutid")
' Handle 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
checkoutReason = rs("checkout_reason") & ""
' Status styling
If statusText = "Available" Then
statusClass = "success"
Else
statusClass = "warning"
End If
%>
<tr>
<td><code><%=Server.HTMLEncode(serialNum)%></code></td>
<td><%=Server.HTMLEncode(usbAlias)%></td>
<td><%=Server.HTMLEncode(businessUnit)%></td>
<td><span class="badge badge-<%=statusClass%>"><%=Server.HTMLEncode(statusText)%></span></td>
<td>
<% If currentHolder <> "" Then %>
<strong><%=Server.HTMLEncode(currentHolder)%></strong>
<% If checkoutReason <> "" Then %>
<br><small class="text-muted" title="<%=Server.HTMLEncode(checkoutReason)%>"><%=Server.HTMLEncode(Left(checkoutReason, 30))%><% If Len(checkoutReason) > 30 Then Response.Write("...") End If %></small>
<% End If %>
<% Else %>
<span class="text-muted">-</span>
<% End If %>
</td>
<td><%=Server.HTMLEncode(checkoutTime)%></td>
<td>
<% If IsNull(checkoutId) Then %>
<a href="./checkout_usb.asp?serial=<%=Server.URLEncode(serialNum)%>" class="btn btn-sm btn-primary" title="Checkout this USB">
<i class="zmdi zmdi-arrow-right"></i>
</a>
<% Else %>
<a href="./checkin_usb.asp?serial=<%=Server.URLEncode(serialNum)%>" class="btn btn-sm btn-success" title="Check-in this USB">
<i class="zmdi zmdi-arrow-left"></i>
</a>
<% End If %>
<a href="./usb_history.asp?machineid=<%=machineId%>" class="btn btn-sm btn-secondary" title="View history">
<i class="zmdi zmdi-time"></i>
</a>
</td>
</tr>
<%
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
If rowCount = 0 Then
%>
<tr>
<td colspan="7" class="text-center text-muted">
<i class="zmdi zmdi-info zmdi-hc-2x"></i><br>
No USB devices found.
<% If showFilter <> "all" Then %>
<br><a href="./displayusb.asp">Show all devices</a>
<% Else %>
<br><a href="./addusb.asp">Add a USB device</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%> USB device(s)
<% If showFilter <> "all" 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() {
$('#usbTable').DataTable({
"order": [[0, "asc"]],
"pageLength": 25,
"language": {
"emptyTable": "No USB devices found"
}
});
});
</script>
</body>
</html>

View File

@@ -1,214 +1,166 @@
# Database Migration - Current Status Summary # Database Migration - Status Summary
**Date:** 2025-11-06 **Last Updated:** 2025-11-25
**Session End:** Ready to create Phase 1 SQL scripts **Current Phase:** Phase 2 COMPLETE, Phase 3 PLANNED
**Status:** Design 100% Complete ✅
--- ---
## Design Complete ✅ ## Migration Status
All design decisions finalized and documented: | Phase | Status | Description | Completed |
|-------|--------|-------------|-----------|
1. Communications infrastructure (generic `address` field) | **Phase 1** | COMPLETE | Schema changes (tables, columns, indexes) | Nov 6, 2025 |
2. Compliance tracking (from inventory.xlsx) | **Phase 2** | COMPLETE | PC migration to machines table | Nov 10, 2025 |
3. ✅ Warranty management (simplified) | **Phase 3** | COMPLETE | Network devices - legacy tables dropped | Nov 25, 2025 |
4. ✅ Machine relationships (dualpath, controller associations)
5. ✅ Controller fields (controllertypeid, controllerosid)
6. ✅ 100% inventory.xlsx column coverage (35/35 columns)
--- ---
## Final Table Counts ## Phase 1: Schema Changes (COMPLETE)
**New Tables:** 7 **Completed:** November 6, 2025
1. comstypes (8 columns)
2. communications (9 columns)
3. compliance (15 columns) - includes MFT
4. compliancescans (5 columns)
5. warranties (5 columns)
6. relationshiptypes (5 columns)
7. machinerelationships (6 columns)
**Modified Tables:** 2 ### New Tables Created (7)
1. machines (+11 columns) - now 21 total 1. `comstypes` - Communication types (IP, Serial, etc.)
2. businessunits (+2 columns) - now 6 total 2. `communications` - Unified network interfaces
3. `warranties` - Warranty tracking
4. `compliance` - Compliance tracking
5. `compliancescans` - Scan history
6. `relationshiptypes` - Relationship type definitions
7. `machinerelationships` - Machine-to-machine relationships
**Renamed:** pcstatus → machinestatus ### Tables Modified (2)
1. `machines` - Added 11 columns (hostname, serialnumber, osid, pctypeid, etc.)
2. `businessunits` - Added liaison fields
**Deprecated:** pc, pc_comm_config, pc_network_interfaces, pctype ### Tables Renamed
- `pcstatus``machinestatus`
**Total New Columns:** 61
--- ---
## Final machines Table (21 columns) ## Phase 2: PC Migration (COMPLETE)
1. machineid (PK) **Completed:** November 10, 2025
2. machinetypeid (FK) - includes PC types
3. machinenumber
4. alias
5. hostname (NEW - for PCs)
6. serialnumber (NEW)
7. loggedinuser (NEW - for PCs)
8. modelnumberid (FK)
9. **controllertypeid (NEW - for CNCs)**
10. **controllerosid (NEW - controller OS)**
11. **osid (NEW - for PCs)**
12. machinestatusid (NEW)
13. businessunitid (FK)
14. printerid (FK)
15. mapleft
16. maptop
17. isactive
18. islocationonly
19. machinenotes
20. lastupdated (NEW)
21. dateadded (NEW)
**Key:** Both PC OS and Controller OS use the same `operatingsystems` table! ### Data Migrated
- **277 PCs** migrated from `pc` table → `machines` table
- **705+ network interfaces** → `communications` table
- **Dualpath relationships** → `machinerelationships` table
- **PC→Equipment relationships** → `machinerelationships` table
### Schema Changes
- PCs identified by `pctypeid IS NOT NULL` in machines table
- Network interfaces use `communications.address` field
- Relationships use `machinerelationships` table
### Pages Updated
- displaypcs.asp, displaypc.asp, editpc.asp
- displaymachines.asp, displaymachine.asp
- network_map.asp, network_devices.asp
- All save/update device pages
### API Fixes
- Fixed 36+ IIf() bugs in api.asp
- Fixed PC→Machine relationship creation
- PowerShell data collection fully working
--- ---
## Inventory.xlsx Coverage: 100% (35/35) ## Phase 3: Network Devices (COMPLETE)
All columns mapped to database: **Completed:** November 25, 2025
- ✅ VLAN → communications.settings JSON
- ✅ MFT → compliance.mft
- ✅ OT Asset Fields → machinerelationships table
See: `INVENTORY_COLUMN_MAPPING.md` for complete mapping ### What Happened
- Legacy tables were essentially empty (only 3 servers had data)
- Network devices were already being added directly to `machines` table
- Dropped all legacy network device tables
### Tables Dropped
- `servers` (3 records - not migrated, stale data)
- `switches` (empty)
- `cameras` (empty)
- `accesspoints` (empty)
- `idfs` (empty)
### Current Network Device Types in machines Table
| machinetypeid | Type |
|---------------|------|
| 16 | Access Point |
| 17 | IDF |
| 18 | Camera |
| 19 | Switch |
| 20 | Server |
### Printers
- Stay in separate `printers` table (by design - unique fields, workflows)
--- ---
## Documentation Files ## Current Architecture
1. **DATABASE_MIGRATION_FINAL_DESIGN.md** (23KB) ```
- Complete specification machines table (unified)
- All table structures ├── Equipment (machinetypeid 1-24, pctypeid IS NULL)
- Migration strategy ├── PCs (machinetypeid 25-29, pctypeid IS NOT NULL)
- Risk mitigation └── [Future] Network Devices (machinetypeid 30-36)
2. **MIGRATION_QUICK_REFERENCE.md** (4.6KB) printers table (separate)
- Quick lookup
- Table summaries
- Key decisions
3. **MACHINE_RELATIONSHIPS_EXAMPLES.md** (9.4KB) communications table (all network interfaces)
- Real-world examples
- Query patterns
- ASP code samples
4. **INVENTORY_COLUMN_MAPPING.md** (NEW - 8KB) machinerelationships table (all relationships)
- 100% column coverage ```
- Export query
- Mapping notes
--- ---
## Next Steps (When Ready) ## Key Queries
### Phase 1: Create SQL Scripts (8 scripts) ```sql
-- All PCs
SELECT * FROM machines WHERE pctypeid IS NOT NULL;
1. **Script 01:** Create communications infrastructure -- All Equipment (non-PC)
- comstypes table SELECT * FROM machines WHERE pctypeid IS NULL;
- communications table
2. **Script 02:** Extend machines table -- PCs with network info
- Add 11 new columns SELECT m.hostname, m.serialnumber, c.address
- Add indexes and FKs FROM machines m
LEFT JOIN communications c ON m.machineid = c.machineid
WHERE m.pctypeid IS NOT NULL;
3. **Script 03:** Create PC machine types -- PC → Equipment relationships
- Insert into machinetypes table SELECT
pc.hostname AS pc_name,
4. **Script 04:** Create warranty infrastructure eq.machinenumber AS equipment_name
- warranties table FROM machinerelationships mr
JOIN machines pc ON mr.machineid = pc.machineid
5. **Script 05:** Create compliance infrastructure JOIN machines eq ON mr.related_machineid = eq.machineid
- compliance table (15 columns - includes MFT) JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid
- compliancescans table WHERE rt.relationshiptype = 'Controls';
```
6. **Script 06:** Extend businessunits table
- Add liaisonname, liaisonsso
7. **Script 07:** Rename pcstatus to machinestatus
- RENAME TABLE
- Rename columns
8. **Script 08:** Create machine relationships infrastructure
- relationshiptypes table
- machinerelationships table
**Plus:** 8 corresponding rollback scripts
**Estimated Time:** 25 minutes
**Reversibility:** Full (rollback scripts provided)
--- ---
## Key Design Decisions ## Deprecated Tables (Phase 2)
### ✅ Generic `address` Field These tables are deprecated but kept for rollback safety:
One field for IP, COM1, USB, etc. Type determined by `comstypeid`.
### ✅ Controller Fields in machines Table - `pc` → Use `machines WHERE pctypeid IS NOT NULL`
- controllertypeid (FK → controllertypes) - `pc_network_interfaces` → Use `communications`
- controllerosid (FK → operatingsystems) - `pc_comm_config` → Use `communications`
- Same operatingsystems table used for both PC OS and Controller OS - `pc_dualpath_assignments` → Use `machinerelationships`
- `pcstatus` → Use `machinestatus`
### ✅ Machine Relationships **Recommendation:** Drop after 30 days of stable operation
- Dualpath: Machines sharing controller
- Controlled By: PC controlling machine
- Future: Clusters, backups, master-slave, etc.
### ✅ VLAN in JSON
Stored in communications.settings instead of dedicated column.
### ✅ MFT Field
Added to compliance table for Managed File Transfer tracking.
### ✅ Simplified Warranties
Just warrantyname and enddate - minimal approach.
### ✅ Liaison in businessunits
No separate liaisons table - added directly to businessunits.
--- ---
## Migration Volumes (Estimated) ## Related Documentation
- machines: 543 total (266 existing + 277 from PCs) - [DATABASE_MIGRATION_FINAL_DESIGN.md](DATABASE_MIGRATION_FINAL_DESIGN.md) - Phase 1 spec
- communications: ~650+ records - [PC_MACHINES_CONSOLIDATION_PLAN.md](PC_MACHINES_CONSOLIDATION_PLAN.md) - Phase 2 plan
- warranties: ~277+ records - [PHASE3_NETWORK_DEVICES_MIGRATION_PLAN.md](PHASE3_NETWORK_DEVICES_MIGRATION_PLAN.md) - Phase 3 plan
- compliance: TBD (from inventory.xlsx import) - [MIGRATION_QUICK_REFERENCE.md](MIGRATION_QUICK_REFERENCE.md) - Quick lookup
- compliancescans: TBD (ongoing logging)
- machinerelationships: ~50+ (dualpath pairs + PC controllers)
--- ---
## Questions to Revisit (Optional) **Last Updated:** 2025-11-25
None currently - all design decisions finalized!
---
## Session Notes
**What was accomplished:**
- Designed 7 new tables
- Extended 2 existing tables
- Achieved 100% inventory.xlsx coverage
- Documented machine relationships pattern
- Finalized controller field approach
- Created comprehensive documentation
**Ready for:**
- Phase 1 SQL script creation
- Dev environment testing
- Data migration planning
---
**Status:** Ready to proceed with implementation whenever you're ready!
**Last Updated:** 2025-11-06 (End of design session)

View File

@@ -1,346 +1,211 @@
# ShopDB Documentation # ShopDB Documentation
Welcome to the ShopDB documentation! This folder contains everything you need to understand, develop, and maintain the ShopDB application. **Last Updated:** 2025-11-25
**Current Status:** Phase 2 Complete, Phase 3 Planned
---
## Project Status Overview
### Migration Progress
| Phase | Status | Description | Completed |
|-------|--------|-------------|-----------|
| **Phase 1** | COMPLETE | Schema changes - new tables, columns, indexes | Nov 6, 2025 |
| **Phase 2** | COMPLETE | PC migration to unified machines table | Nov 10, 2025 |
| **Phase 3** | PLANNED | Network devices migration (servers, switches, cameras) | TBD |
### Current Architecture
```
machines table (unified)
├── Equipment (machinetypeid 1-24, pctypeid IS NULL)
└── PCs (machinetypeid 25-29, pctypeid IS NOT NULL)
printers table (separate - by design)
Network devices (Phase 3 will migrate):
- servers, switches, cameras, accesspoints, idfs
- Will become machinetypeid 30-36 in machines table
```
### Key Accomplishments (Oct-Nov 2025)
- Consolidated PCs into unified `machines` table (277 PCs migrated)
- Created `communications` table for all network interfaces (705+ records)
- Created `machinerelationships` table for PC/equipment relationships
- Modernized all PC pages (displaypcs, displaypc, editpc)
- Fixed 36+ API bugs for PowerShell data collection
- Added compliance and warranty tracking infrastructure
- Implemented network map for all device types
--- ---
## Documentation Overview ## Documentation Overview
### 📘 For New Team Members ### For New Team Members
**Start here in this order:** **Start here in this order:**
1. **[QUICK_REFERENCE.md](QUICK_REFERENCE.md)** ⭐ START HERE 1. **[QUICK_REFERENCE.md](QUICK_REFERENCE.md)** - Quick facts, common tasks, cheat sheets (15 min)
- Quick facts, common tasks, cheat sheets
- Perfect for daily reference
- **Time to read:** 15 minutes
2. **[GIT_WORKFLOW.md](GIT_WORKFLOW.md)** 🔧 MANDATORY 2. **[ASP_DEVELOPMENT_GUIDE.md](ASP_DEVELOPMENT_GUIDE.md)** - Dev environment setup, VBScript patterns (30 min)
- Git workflow and commit standards
- How to commit and push changes
- **MUST READ before making any code changes**
- **Time to read:** 20 minutes
3. **[ASP_DEVELOPMENT_GUIDE.md](ASP_DEVELOPMENT_GUIDE.md)** 3. **[STANDARDS.md](STANDARDS.md)** - Coding standards, security requirements (45 min)
- Development environment setup
- How to start/stop the dev environment
- VBScript/ASP basics and patterns
- **Time to read:** 30 minutes
4. **[DEEP_DIVE_REPORT.md](DEEP_DIVE_REPORT.md)** 📚 COMPREHENSIVE 4. **[DEEP_DIVE_REPORT.md](DEEP_DIVE_REPORT.md)** - Complete database/architecture docs (reference)
- Complete database schema documentation
- Application architecture deep dive
- Data flows and workflows
- Technical debt analysis
- Recommendations and roadmap
- **Time to read:** 2-3 hours (reference material)
5. **[STANDARDS.md](STANDARDS.md)** ⚠️ MANDATORY 5. **[NESTED_ENTITY_CREATION.md](NESTED_ENTITY_CREATION.md)** - Complex forms, inline entity creation (20 min)
- Coding standards (MUST follow)
- Security requirements
- Database access patterns
- Input validation rules
- Error handling standards
- **Time to read:** 45 minutes
6. **[NESTED_ENTITY_CREATION.md](NESTED_ENTITY_CREATION.md)**
- How to create complex forms
- Nested entity management (e.g., add printer + create new model inline)
- **Time to read:** 20 minutes
7. **[GIT_SETUP_GUIDE.md](GIT_SETUP_GUIDE.md)**
- Setting up Gitea (Git server with web UI)
- SSH key configuration
- First-time Git setup
- **Time to read:** 30 minutes (one-time setup)
8. **[GITEA_FEATURES_GUIDE.md](GITEA_FEATURES_GUIDE.md)**
- Using Gitea Projects (Kanban boards)
- Issue tracking and bug management
- Wiki for collaborative documentation
- Pull requests and code review
- Milestones and releases
- **Time to read:** 45 minutes
--- ---
## Quick Navigation ## Migration Documentation
### By Role ### Phase 1 & 2 (Complete)
**Developers:** | Document | Description |
1. Read: QUICK_REFERENCE.md |----------|-------------|
2. **MANDATORY: GIT_WORKFLOW.md** ⚠️ | [DATABASE_MIGRATION_FINAL_DESIGN.md](DATABASE_MIGRATION_FINAL_DESIGN.md) | Complete Phase 1 specification |
3. Setup: ASP_DEVELOPMENT_GUIDE.md, GIT_SETUP_GUIDE.md | [MIGRATION_QUICK_REFERENCE.md](MIGRATION_QUICK_REFERENCE.md) | Quick lookup for migration |
4. Standards: STANDARDS.md | [PC_MACHINES_CONSOLIDATION_PLAN.md](PC_MACHINES_CONSOLIDATION_PLAN.md) | Phase 2 PC migration plan |
5. Deep dive: DEEP_DIVE_REPORT.md (sections 2, 3, 6) | [MACHINE_RELATIONSHIPS_EXAMPLES.md](MACHINE_RELATIONSHIPS_EXAMPLES.md) | Relationship query patterns |
6. Advanced: NESTED_ENTITY_CREATION.md
7. Project Management: GITEA_FEATURES_GUIDE.md
**Database Administrators:** ### Phase 3 (Planned)
1. Read: QUICK_REFERENCE.md (Database section)
2. Read: DEEP_DIVE_REPORT.md (Section 1: Database Architecture)
3. Review: STANDARDS.md (Database Access Standards)
4. Reference: SQL queries in QUICK_REFERENCE.md
**System Administrators:** | Document | Description |
1. Read: ASP_DEVELOPMENT_GUIDE.md (Prerequisites, Troubleshooting) |----------|-------------|
2. Read: DEEP_DIVE_REPORT.md (Section 7.3: For System Administrators) | [PHASE3_NETWORK_DEVICES_MIGRATION_PLAN.md](PHASE3_NETWORK_DEVICES_MIGRATION_PLAN.md) | Network devices migration plan |
3. Reference: QUICK_REFERENCE.md (Common Tasks)
**Business Analysts:**
1. Read: DEEP_DIVE_REPORT.md (Executive Summary, Section 1, Section 7.4)
2. Reference: QUICK_REFERENCE.md (Key Views, SQL Queries)
**Project Managers:**
1. Read: DEEP_DIVE_REPORT.md (Executive Summary, Section 4: Technical Debt, Section 6: Recommendations)
2. Read: GITEA_FEATURES_GUIDE.md (Projects, Issues, Milestones, Releases)
--- ---
## By Topic ## Core Documentation
### Standards & Development
| Document | Purpose | Status |
|----------|---------|--------|
| [STANDARDS.md](STANDARDS.md) | Coding standards, security | Current |
| [ASP_DEVELOPMENT_GUIDE.md](ASP_DEVELOPMENT_GUIDE.md) | Dev setup, patterns | Current |
| [QUICK_REFERENCE.md](QUICK_REFERENCE.md) | Cheat sheets | Current |
| [NESTED_ENTITY_CREATION.md](NESTED_ENTITY_CREATION.md) | Complex forms | Current |
### Architecture & Design
| Document | Purpose | Status |
|----------|---------|--------|
| [DEEP_DIVE_REPORT.md](DEEP_DIVE_REPORT.md) | Complete system documentation | Current |
| [INFRASTRUCTURE_FINAL_ARCHITECTURE.md](INFRASTRUCTURE_FINAL_ARCHITECTURE.md) | Infrastructure design | Current |
| [NETWORK_DEVICES_UNIFIED_DESIGN.md](NETWORK_DEVICES_UNIFIED_DESIGN.md) | Network unification design | Current |
---
## SQL Migration Scripts
All migration scripts are in `/sql/migration_phase*/` folders:
```
sql/
├── migration_phase1/ # Schema changes (8 scripts + rollbacks)
├── migration_phase2/ # PC data migration (8 scripts)
├── migration_phase3/ # Network devices (planned)
└── *.sql # Utility scripts
```
---
## Quick Start
### Dev Environment
```bash
# Start dev environment
~/start-dev-env.sh
# Check status
~/status-dev-env.sh
# Access application
http://192.168.122.151:8080
```
### Git (Gitea)
```bash
# Gitea web UI
http://localhost:3000
# Clone repo
git clone ssh://git@localhost:2222/cproudlock/shopdb.git
```
### Database ### Database
- **Schema Overview:** DEEP_DIVE_REPORT.md → Section 1
- **Quick Reference:** QUICK_REFERENCE.md → Core Tables Cheat Sheet
- **Access Patterns:** STANDARDS.md → Database Access Standards
- **Views:** DEEP_DIVE_REPORT.md → Section 1.3
- **Sample Queries:** QUICK_REFERENCE.md → Useful SQL Queries
### Development ```bash
- **Git Workflow:** GIT_WORKFLOW.md → Complete workflow guide ⚠️ MANDATORY # Connect to MySQL
- **Git Setup:** GIT_SETUP_GUIDE.md → Gitea installation and SSH keys docker exec -it dev-mysql mysql -u root -prootpassword shopdb
- **Project Management:** GITEA_FEATURES_GUIDE.md → Issues, Projects, Wiki, PRs
- **Setup Environment:** ASP_DEVELOPMENT_GUIDE.md → Project Setup
- **Coding Patterns:** ASP_DEVELOPMENT_GUIDE.md → Common VBScript/ASP Patterns
- **Standards:** STANDARDS.md → All sections
- **Quick Reference:** QUICK_REFERENCE.md → Key VBScript Patterns
### Architecture # Quick queries
- **Overview:** DEEP_DIVE_REPORT.md → Section 2 SELECT COUNT(*) FROM machines WHERE pctypeid IS NOT NULL; -- PCs
- **File Structure:** DEEP_DIVE_REPORT.md → Section 2.2 SELECT COUNT(*) FROM machines WHERE pctypeid IS NULL; -- Equipment
- **Data Flows:** DEEP_DIVE_REPORT.md → Section 3 SELECT COUNT(*) FROM printers WHERE isactive = 1; -- Printers
- **Diagrams:** DEEP_DIVE_REPORT.md → Sections 9, 10 ```
### Security
- **Standards:** STANDARDS.md → Security Standards
- **Issues:** DEEP_DIVE_REPORT.md → Section 4.1
- **Checklist:** QUICK_REFERENCE.md → Security Checklist
### Troubleshooting
- **Dev Environment:** ASP_DEVELOPMENT_GUIDE.md → Troubleshooting
- **Quick Fixes:** QUICK_REFERENCE.md → Troubleshooting
- **Common Issues:** DEEP_DIVE_REPORT.md → Section 4
--- ---
## Document Maintenance ## Key Database Tables
### When to Update ### Core Tables (Phase 2 Schema)
**QUICK_REFERENCE.md:** | Table | Purpose | Records |
- New common task identified |-------|---------|---------|
- New frequently-used query | `machines` | All equipment + PCs | 500+ |
- New troubleshooting tip | `communications` | Network interfaces | 700+ |
| `machinerelationships` | PC/equipment links | 50+ |
| `printers` | Printers (separate) | 200+ |
| `warranties` | Warranty tracking | var |
| `compliance` | Compliance data | var |
**ASP_DEVELOPMENT_GUIDE.md:** ### Key Views
- Development environment changes
- New tools or dependencies
- Setup process changes
**DEEP_DIVE_REPORT.md:** | View | Purpose |
- Major schema changes |------|---------|
- New features added | `vw_network_devices` | All network devices unified |
- Architecture changes | `vw_active_pcs` | Active PCs with details |
- Quarterly review updates | `vw_machine_relationships` | Relationship summary |
**STANDARDS.md:**
- New coding standards adopted
- Security policy changes
- New validation patterns
- New error codes
**NESTED_ENTITY_CREATION.md:**
- New nested entity patterns
- Complex form examples
### How to Update
1. **Small Updates:** Edit the file directly, commit to Git (once setup)
2. **Major Updates:** Create a copy, edit, have peer review, then replace
3. **Always Update:** "Last Updated" date at bottom of each file
4. **Document Changes:** Note what changed in Git commit message
--- ---
## Document Status ## Recent Session Summaries
| Document | Last Updated | Status | Review Cycle | Located in project root:
|----------|--------------|--------|--------------|
| QUICK_REFERENCE.md | 2025-10-20 | ✅ Current | As needed |
| GIT_WORKFLOW.md | 2025-10-20 | ✅ Current | Quarterly |
| GIT_SETUP_GUIDE.md | 2025-10-20 | ✅ Current | Annually |
| GITEA_FEATURES_GUIDE.md | 2025-10-20 | ✅ Current | Quarterly |
| ASP_DEVELOPMENT_GUIDE.md | 2025-10-10 | ✅ Current | Quarterly |
| DEEP_DIVE_REPORT.md | 2025-10-20 | ✅ Current | Quarterly |
| STANDARDS.md | 2025-10-10 | ✅ Current | Semi-annually |
| NESTED_ENTITY_CREATION.md | 2025-10-10 | ✅ Current | Annually |
| README.md (this file) | 2025-10-20 | ✅ Current | As needed |
--- | File | Date | Focus |
|------|------|-------|
## Quick Start for New Developers | SESSION_SUMMARY_2025-11-13.md | Nov 13 | Phase 2 testing, network_map fixes |
| SESSION_SUMMARY_2025-11-10.md | Nov 10 | Relationship fixes, Phase 3 planning |
### Day 1 Checklist
- [ ] Read QUICK_REFERENCE.md (15 min)
- [ ] **Read GIT_WORKFLOW.md (20 min) - MANDATORY** ⚠️
- [ ] Follow ASP_DEVELOPMENT_GUIDE.md to setup environment (1-2 hours)
- [ ] Verify Git repository is initialized
- [ ] Browse application at http://192.168.122.151:8080
- [ ] Read STANDARDS.md (45 min)
- [ ] Make a test edit, commit, and push to Git
### Week 1 Checklist
- [ ] Read DEEP_DIVE_REPORT.md Executive Summary
- [ ] Read DEEP_DIVE_REPORT.md Section 1 (Database)
- [ ] Read DEEP_DIVE_REPORT.md Section 2 (Architecture)
- [ ] Read GITEA_FEATURES_GUIDE.md (Issues, Projects, Wiki)
- [ ] Create your first issue in Gitea
- [ ] Explore all display*.asp pages
- [ ] Run sample SQL queries from QUICK_REFERENCE.md
- [ ] Understand PC-to-machine assignment logic
### Month 1 Checklist
- [ ] Complete DEEP_DIVE_REPORT.md
- [ ] Implement a small feature end-to-end
- [ ] Review NESTED_ENTITY_CREATION.md
- [ ] Contribute a documentation improvement
- [ ] Pair program with experienced team member
---
## External Resources
### Classic ASP / VBScript
- [Microsoft ASP Reference](https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms525334(v=vs.90))
- [VBScript Language Reference](https://learn.microsoft.com/en-us/previous-versions//d1wf56tt(v=vs.85))
- [W3Schools ASP Tutorial](https://www.w3schools.com/asp/)
### MySQL
- [MySQL 5.6 Reference Manual](https://dev.mysql.com/doc/refman/5.6/en/)
- [MySQL FULLTEXT Search](https://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html)
- [MySQL Performance Tuning](https://dev.mysql.com/doc/refman/5.6/en/optimization.html)
### Frontend
- [Bootstrap 4.6 Documentation](https://getbootstrap.com/docs/4.6/)
- [jQuery Documentation](https://api.jquery.com/)
- [Material Design Iconic Font](https://zavoloklom.github.io/material-design-iconic-font/)
- [FullCalendar v3](https://fullcalendar.io/docs/v3)
- [DataTables](https://datatables.net/)
--- ---
## Getting Help ## Getting Help
### Documentation Issues 1. Check [QUICK_REFERENCE.md](QUICK_REFERENCE.md) first
- Document unclear? Create an issue or update it yourself! 2. Search [DEEP_DIVE_REPORT.md](DEEP_DIVE_REPORT.md)
- Found an error? Fix it and commit 3. Review [STANDARDS.md](STANDARDS.md) for coding questions
- Missing information? Add it! 4. Check session summaries for recent changes
### Technical Questions
- Check QUICK_REFERENCE.md first
- Search DEEP_DIVE_REPORT.md
- Ask team lead
- Create documentation if answer isn't documented
### Code Questions
- Review STANDARDS.md
- Check ASP_DEVELOPMENT_GUIDE.md for patterns
- Look at similar existing code
- Ask for code review
---
## Contributing to Documentation
We encourage all team members to improve documentation!
### Guidelines
1. **Be Clear** - Write for someone who doesn't know the system
2. **Be Concise** - Respect the reader's time
3. **Be Accurate** - Test commands/code before documenting
4. **Be Current** - Update dates when you edit
5. **Be Helpful** - Include examples and context
### What to Document
- Solutions to problems you encountered
- Common tasks you perform
- Tricky patterns or gotchas
- New features or changes
- Helpful queries or scripts
### How to Contribute
1. Edit the relevant .md file
2. Update "Last Updated" date
3. Commit with descriptive message
4. (Optional) Have peer review for major changes
--- ---
## Version History ## Version History
**v1.3** - 2025-10-20 | Version | Date | Changes |
- Added GIT_WORKFLOW.md (mandatory Git workflow documentation) |---------|------|---------|
- Added GIT_SETUP_GUIDE.md (Gitea setup guide) | v2.0 | 2025-11-25 | Updated for Phase 2 completion, cleanup |
- Updated README.md with Git workflow references | v1.3 | 2025-10-20 | Added Git workflow documentation |
- Established mandatory commit-after-every-change policy | v1.2 | 2025-10-20 | Added DEEP_DIVE_REPORT, QUICK_REFERENCE |
| v1.1 | 2025-10-10 | Added STANDARDS, NESTED_ENTITY_CREATION |
**v1.2** - 2025-10-20 | v1.0 | 2025-10-09 | Initial ASP_DEVELOPMENT_GUIDE |
- Added DEEP_DIVE_REPORT.md (comprehensive technical report)
- Added QUICK_REFERENCE.md (cheat sheets)
- Added this README.md
- Updated ASP_DEVELOPMENT_GUIDE.md with documentation references
**v1.1** - 2025-10-10
- Added STANDARDS.md (coding standards)
- Added NESTED_ENTITY_CREATION.md
- Updated ASP_DEVELOPMENT_GUIDE.md
**v1.0** - 2025-10-09
- Initial ASP_DEVELOPMENT_GUIDE.md created
---
## Future Documentation Plans
- [ ] API Documentation (when APIs expand)
- [ ] Deployment Guide (CI/CD pipeline)
- [ ] Security Audit Report
- [ ] Performance Optimization Guide
- [ ] Testing Guide (when tests implemented)
- [ ] Video tutorials (screen recordings)
- [ ] FAQ document
- [ ] Glossary of GE-specific terms
--- ---
**Maintained By:** Development Team **Maintained By:** Development Team
**Questions?** Ask team lead or update docs directly **Last Updated:** 2025-11-25
**Feedback?** Create issue or improve the docs yourself!
---
## Summary
You now have comprehensive documentation covering:
**Quick Reference** - Daily cheat sheet
**Git Workflow** - Mandatory version control workflow ⚠️
**Development Guide** - Environment setup
**Deep Dive Report** - Complete technical documentation
**Standards** - Mandatory coding rules
**Advanced Patterns** - Complex forms
**Start with QUICK_REFERENCE.md, then read GIT_WORKFLOW.md before making any code changes!**
Happy coding! 🚀

View File

@@ -1,119 +0,0 @@
<%@ Language=VBScript %>
<%
Option Explicit
' Inline SQL connection (from sql.asp)
Dim objConn, strSQL
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "DSN=shopdb;UID=shopdbuser;PWD=shopdbuser1!;"
' Get form data
Dim appid, appname, appdescription, supportteamid
Dim applicationnotes, installpath, documentationpath, image
Dim isinstallable, isactive, ishidden, isprinter, islicenced
appid = Trim(Request.Form("appid"))
appname = Trim(Request.Form("appname"))
appdescription = Trim(Request.Form("appdescription"))
supportteamid = Trim(Request.Form("supportteamid"))
applicationnotes = Trim(Request.Form("applicationnotes"))
installpath = Trim(Request.Form("installpath"))
documentationpath = Trim(Request.Form("documentationpath"))
image = Trim(Request.Form("image"))
' Checkboxes - ensure they are always integers 0 or 1
If Request.Form("isinstallable") = "1" Then
isinstallable = 1
Else
isinstallable = 0
End If
If Request.Form("isactive") = "1" Then
isactive = 1
Else
isactive = 0
End If
If Request.Form("ishidden") = "1" Then
ishidden = 1
Else
ishidden = 0
End If
If Request.Form("isprinter") = "1" Then
isprinter = 1
Else
isprinter = 0
End If
If Request.Form("islicenced") = "1" Then
islicenced = 1
Else
islicenced = 0
End If
' Simple validation
If Not IsNumeric(appid) Or CLng(appid) < 1 Then
Response.Write("Invalid appid")
objConn.Close
Response.End
End If
If Len(appname) < 1 Or Len(appname) > 50 Then
Response.Write("Invalid appname length")
objConn.Close
Response.End
End If
' Build parameterized UPDATE
Dim cmd, param
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = "UPDATE applications SET appname = ?, appdescription = ?, supportteamid = ?, " & _
"applicationnotes = ?, installpath = ?, documentationpath = ?, image = ?, " & _
"isinstallable = ?, isactive = ?, ishidden = ?, isprinter = ?, islicenced = ? " & _
"WHERE appid = ?"
cmd.CommandType = 1
' Add parameters manually
Set param = cmd.CreateParameter("p1", 200, 1, 50, appname)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p2", 200, 1, 255, appdescription)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p3", 3, 1, 4, CLng(supportteamid))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p4", 200, 1, 512, applicationnotes)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p5", 200, 1, 255, installpath)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p6", 200, 1, 512, documentationpath)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p7", 200, 1, 255, image)
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p8", 11, 1, , CBool(isinstallable))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p9", 11, 1, , CBool(isactive))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p10", 11, 1, , CBool(ishidden))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p11", 11, 1, , CBool(isprinter))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p12", 11, 1, , CBool(islicenced))
cmd.Parameters.Append param
Set param = cmd.CreateParameter("p13", 3, 1, 4, CLng(appid))
cmd.Parameters.Append param
' Execute
On Error Resume Next
cmd.Execute
If Err.Number <> 0 Then
Response.Write("Error: " & Err.Description)
objConn.Close
Response.End
End If
objConn.Close
' Redirect on success
Response.Redirect("displayapplication.asp?appid=" & Server.URLEncode(appid))
%>

View File

@@ -1,187 +0,0 @@
<%@ Language=VBScript %>
<%
Option Explicit
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/encoding.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!--#include file="./includes/db_helpers.asp"-->
<%
'=============================================================================
' FILE: editapplication.asp
' PURPOSE: Update an existing application record
'
' PARAMETERS:
' appid (Form, Required) - Integer ID of application to update
' appname (Form, Required) - Application name (1-50 chars)
' appdescription (Form, Optional) - Description (max 255 chars)
' supportteamid (Form, Required) - Support team ID
' applicationnotes (Form, Optional) - Notes (max 512 chars)
' installpath (Form, Optional) - Installation path/URL (max 255 chars)
' documentationpath (Form, Optional) - Documentation path/URL (max 512 chars)
' image (Form, Optional) - Image filename (max 255 chars)
' isinstallable, isactive, ishidden, isprinter, islicenced (Form, Optional) - Checkboxes (0/1)
'
' SECURITY:
' - Uses parameterized queries
' - Validates all inputs
' - HTML encodes outputs
'
' AUTHOR: Claude Code
' CREATED: 2025-10-12
'=============================================================================
'-----------------------------------------------------------------------------
' INITIALIZATION
'-----------------------------------------------------------------------------
Call InitializeErrorHandling("editapplication.asp")
' Get and validate required inputs
Dim appid, appname, appdescription, supportteamid
Dim applicationnotes, installpath, documentationpath, image
Dim isinstallable, isactive, ishidden, isprinter, islicenced
appid = Trim(Request.Form("appid"))
appname = Trim(Request.Form("appname"))
appdescription = Trim(Request.Form("appdescription"))
supportteamid = Trim(Request.Form("supportteamid"))
applicationnotes = Trim(Request.Form("applicationnotes"))
installpath = Trim(Request.Form("installpath"))
documentationpath = Trim(Request.Form("documentationpath"))
image = Trim(Request.Form("image"))
' Checkboxes - convert to bit values
If Request.Form("isinstallable") = "1" Then
isinstallable = 1
Else
isinstallable = 0
End If
If Request.Form("isactive") = "1" Then
isactive = 1
Else
isactive = 0
End If
If Request.Form("ishidden") = "1" Then
ishidden = 1
Else
ishidden = 0
End If
If Request.Form("isprinter") = "1" Then
isprinter = 1
Else
isprinter = 0
End If
If Request.Form("islicenced") = "1" Then
islicenced = 1
Else
islicenced = 0
End If
'-----------------------------------------------------------------------------
' VALIDATE INPUTS
'-----------------------------------------------------------------------------
' Validate appid
If Not ValidateID(appid) Then
Call HandleValidationError("displayapplications.asp", "INVALID_ID")
End If
' Verify the application exists - DISABLED DUE TO CACHING ISSUE
' If Not RecordExists(objConn, "applications", "appid", appid) Then
' Call HandleValidationError("displayapplications.asp", "NOT_FOUND")
' End If
' Validate appname (required, 1-50 chars)
If Len(appname) < 1 Or Len(appname) > 50 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
' Validate supportteamid
If Not ValidateID(supportteamid) Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_ID")
End If
' Verify support team exists - DISABLED DUE TO CACHING ISSUE
' If Not RecordExists(objConn, "supportteams", "supporteamid", supportteamid) Then
' Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
' End If
' Validate field lengths
If Len(appdescription) > 255 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
If Len(applicationnotes) > 512 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
If Len(installpath) > 255 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
If Len(documentationpath) > 512 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
If Len(image) > 255 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
'-----------------------------------------------------------------------------
' DATABASE UPDATE
'-----------------------------------------------------------------------------
Dim strSQL
strSQL = "UPDATE applications SET " & _
"appname = ?, " & _
"appdescription = ?, " & _
"supportteamid = ?, " & _
"applicationnotes = ?, " & _
"installpath = ?, " & _
"documentationpath = ?, " & _
"image = ?, " & _
"isinstallable = ?, " & _
"isactive = ?, " & _
"ishidden = ?, " & _
"isprinter = ?, " & _
"islicenced = ? " & _
"WHERE appid = ?"
Dim recordsAffected
recordsAffected = ExecuteParameterizedUpdate(objConn, strSQL, Array( _
appname, _
appdescription, _
supportteamid, _
applicationnotes, _
installpath, _
documentationpath, _
image, _
CInt(isinstallable), _
CInt(isactive), _
CInt(ishidden), _
CInt(isprinter), _
CInt(islicenced), _
appid _
))
Call CheckForErrors()
'-----------------------------------------------------------------------------
' CLEANUP AND REDIRECT
'-----------------------------------------------------------------------------
Call CleanupResources()
If recordsAffected > 0 Then
Response.Redirect("displayapplication.asp?appid=" & Server.URLEncode(appid))
Else
Response.Write("<html><body>")
Response.Write("<h3>Error: No records were updated.</h3>")
Response.Write("<p><a href='displayapplication.asp?appid=" & Server.HTMLEncode(appid) & "'>Go Back</a></p>")
Response.Write("</body></html>")
End If
%>

View File

@@ -1,120 +0,0 @@
<%@ Language=VBScript %>
<%
Option Explicit
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/encoding.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!--#include file="./includes/db_helpers.asp"-->
<%
'=============================================================================
' FILE: editapplication_v2.asp (TEST VERSION)
' PURPOSE: Update an existing application record
'=============================================================================
Call InitializeErrorHandling("editapplication_v2.asp")
' Get and validate inputs
Dim appid, appname, appdescription, supportteamid
Dim applicationnotes, installpath, documentationpath, image
Dim isinstallable, isactive, ishidden, isprinter, islicenced
appid = Trim(Request.Form("appid"))
appname = Trim(Request.Form("appname"))
appdescription = Trim(Request.Form("appdescription"))
supportteamid = Trim(Request.Form("supportteamid"))
applicationnotes = Trim(Request.Form("applicationnotes"))
installpath = Trim(Request.Form("installpath"))
documentationpath = Trim(Request.Form("documentationpath"))
image = Trim(Request.Form("image"))
' Checkboxes - ensure they are always integers 0 or 1
If Request.Form("isinstallable") = "1" Then
isinstallable = 1
Else
isinstallable = 0
End If
If Request.Form("isactive") = "1" Then
isactive = 1
Else
isactive = 0
End If
If Request.Form("ishidden") = "1" Then
ishidden = 1
Else
ishidden = 0
End If
If Request.Form("isprinter") = "1" Then
isprinter = 1
Else
isprinter = 0
End If
If Request.Form("islicenced") = "1" Then
islicenced = 1
Else
islicenced = 0
End If
' Validate appid
If Not ValidateID(appid) Then
Call HandleValidationError("displayapplications.asp", "INVALID_ID")
End If
' Validate appname (required, 1-50 chars)
If Len(appname) < 1 Or Len(appname) > 50 Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
End If
' Validate supportteamid
If Not ValidateID(supportteamid) Then
Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_ID")
End If
' Validate field lengths
If Len(appdescription) > 255 Then Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
If Len(applicationnotes) > 512 Then Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
If Len(installpath) > 255 Then Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
If Len(documentationpath) > 512 Then Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
If Len(image) > 255 Then Call HandleValidationError("displayapplication.asp?appid=" & appid, "INVALID_INPUT")
' DATABASE UPDATE
Dim strSQL
strSQL = "UPDATE applications SET " & _
"appname = ?, " & _
"appdescription = ?, " & _
"supportteamid = ?, " & _
"applicationnotes = ?, " & _
"installpath = ?, " & _
"documentationpath = ?, " & _
"image = ?, " & _
"isinstallable = ?, " & _
"isactive = ?, " & _
"ishidden = ?, " & _
"isprinter = ?, " & _
"islicenced = ? " & _
"WHERE appid = ?"
Dim recordsAffected
recordsAffected = ExecuteParameterizedUpdate(objConn, strSQL, Array( _
appname, appdescription, supportteamid, applicationnotes, _
installpath, documentationpath, image, _
CInt(isinstallable), CInt(isactive), CInt(ishidden), CInt(isprinter), CInt(islicenced), appid _
))
Call CheckForErrors()
Call CleanupResources()
If recordsAffected > 0 Then
Response.Redirect("displayapplication.asp?appid=" & Server.URLEncode(appid))
Else
Response.Write("<html><body>")
Response.Write("<h3>Error: No records were updated.</h3>")
Response.Write("<p><a href='displayapplication.asp?appid=" & Server.HTMLEncode(appid) & "'>Go Back</a></p>")
Response.Write("</body></html>")
End If
%>

View File

@@ -34,7 +34,7 @@
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_ "LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_ "LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_ "LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
"WHERE m.machineid = ? AND m.pctypeid IS NOT NULL" "WHERE m.machineid = ? AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
Dim cmd, rsMachine Dim cmd, rsMachine
Set cmd = Server.CreateObject("ADODB.Command") Set cmd = Server.CreateObject("ADODB.Command")

View File

@@ -559,7 +559,7 @@
<option value="">-- None --</option> <option value="">-- None --</option>
<% <%
Dim rsControlPCs Dim rsControlPCs
strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE pctypeid IS NOT NULL AND isactive = 1 ORDER BY machinenumber ASC" strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) AND isactive = 1 ORDER BY machinenumber ASC"
Set rsControlPCs = objconn.Execute(strSQL) Set rsControlPCs = objconn.Execute(strSQL)
While Not rsControlPCs.EOF While Not rsControlPCs.EOF
Dim controlPCDisplay, selectedControlPC Dim controlPCDisplay, selectedControlPC

View File

@@ -145,8 +145,8 @@
Dim rsBusinessUnits, currentBusinessUnitId Dim rsBusinessUnits, currentBusinessUnitId
currentBusinessUnitId = rs("businessunitid") & "" currentBusinessUnitId = rs("businessunitid") & ""
Set rsBusinessUnits = objConn.Execute("SELECT businessunitid, businessunit FROM businessunits WHERE isactive = 1 ORDER BY businessunit") Set rsBusinessUnits = objConn.Execute("SELECT businessunitid, businessunit FROM businessunits WHERE isactive = 1 ORDER BY businessunit")
While Not rsBusinessUnits.EOF
Dim isSelectedBU Dim isSelectedBU
While Not rsBusinessUnits.EOF
isSelectedBU = "" isSelectedBU = ""
If currentBusinessUnitId <> "" And IsNumeric(currentBusinessUnitId) Then If currentBusinessUnitId <> "" And IsNumeric(currentBusinessUnitId) Then
If CLng(rsBusinessUnits("businessunitid")) = CLng(currentBusinessUnitId) Then If CLng(rsBusinessUnits("businessunitid")) = CLng(currentBusinessUnitId) Then
@@ -165,6 +165,29 @@
<small class="form-text text-muted">Select a specific business unit or leave blank to apply to all</small> <small class="form-text text-muted">Select a specific business unit or leave blank to apply to all</small>
</div> </div>
<div class="form-group">
<label for="appid">Related Application <span class="text-muted">(Optional)</span></label>
<select class="form-control" id="appid" name="appid">
<option value="">-- No Application --</option>
<%
Dim rsApps, currentAppId
currentAppId = rs("appid") & ""
Set rsApps = objConn.Execute("SELECT appid, appname FROM applications WHERE isactive = 1 ORDER BY appname")
While Not rsApps.EOF
If currentAppId <> "" And CStr(rsApps("appid")) = currentAppId Then
Response.Write("<option value=""" & rsApps("appid") & """ selected>" & Server.HTMLEncode(rsApps("appname") & "") & "</option>")
Else
Response.Write("<option value=""" & rsApps("appid") & """>" & Server.HTMLEncode(rsApps("appname") & "") & "</option>")
End If
rsApps.MoveNext
Wend
rsApps.Close
Set rsApps = Nothing
%>
</select>
<small class="form-text text-muted">Link this notification to a specific application (e.g., for software updates)</small>
</div>
<div class="form-group"> <div class="form-group">
<label for="ticketnumber">Ticket Number</label> <label for="ticketnumber">Ticket Number</label>
<input type="text" class="form-control" id="ticketnumber" name="ticketnumber" <input type="text" class="form-control" id="ticketnumber" name="ticketnumber"

View File

@@ -13,9 +13,9 @@
theme="bg-theme1" theme="bg-theme1"
END IF END IF
' Get and validate pcid parameter ' Get and validate machineid parameter (Phase 2: PCs are in machines table)
Dim machineid, machineData, strSQL Dim machineid, machineData, strSQL
machineid = Request.QueryString("pcid") machineid = Request.QueryString("machineid")
' Security validation - ensure pcid is numeric ' Security validation - ensure pcid is numeric
If NOT IsNumeric(machineid) OR machineid = "" Then If NOT IsNumeric(machineid) OR machineid = "" Then
@@ -24,8 +24,8 @@
End If End If
' Load PC data (pctypeid IS NOT NULL identifies PCs) ' Load PC data (pctypeid IS NOT NULL identifies PCs)
strSQL = "SELECT m.*, " &_ strSQL = "SELECT m.*, m.machinetypeid AS pcmachinetypeid, " &_
"mo.modelnumber, mo.vendorid AS modelvendorid, mo.machinetypeid, mo.image AS modelimage, " &_ "mo.modelnumber, mo.vendorid AS modelvendorid, mo.machinetypeid AS modelmachinetypeid, mo.image AS modelimage, " &_
"v.vendor, " &_ "v.vendor, " &_
"bu.businessunit, " &_ "bu.businessunit, " &_
"mt.machinetype " &_ "mt.machinetype " &_
@@ -34,7 +34,7 @@
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_ "LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_ "LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_ "LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
"WHERE m.machineid = ? AND m.pctypeid IS NOT NULL" "WHERE m.machineid = ? AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
Dim cmd, rsMachine Dim cmd, rsMachine
Set cmd = Server.CreateObject("ADODB.Command") Set cmd = Server.CreateObject("ADODB.Command")
@@ -54,7 +54,7 @@
End If End If
' Store machine data ' Store machine data
Dim serialnumber, hostname, machinenumber, modelid, businessunitid, alias, machinenotes, mapleft, maptop Dim serialnumber, hostname, machinenumber, modelid, businessunitid, alias, machinenotes, mapleft, maptop, pcMachineTypeId, currentMachineStatusId
serialnumber = "" : If NOT IsNull(rsMachine("serialnumber")) Then serialnumber = rsMachine("serialnumber") & "" serialnumber = "" : If NOT IsNull(rsMachine("serialnumber")) Then serialnumber = rsMachine("serialnumber") & ""
hostname = "" : If NOT IsNull(rsMachine("hostname")) Then hostname = rsMachine("hostname") & "" hostname = "" : If NOT IsNull(rsMachine("hostname")) Then hostname = rsMachine("hostname") & ""
machinenumber = "" : If NOT IsNull(rsMachine("machinenumber")) Then machinenumber = rsMachine("machinenumber") & "" machinenumber = "" : If NOT IsNull(rsMachine("machinenumber")) Then machinenumber = rsMachine("machinenumber") & ""
@@ -64,6 +64,8 @@
machinenotes = "" : If NOT IsNull(rsMachine("machinenotes")) Then machinenotes = rsMachine("machinenotes") & "" machinenotes = "" : If NOT IsNull(rsMachine("machinenotes")) Then machinenotes = rsMachine("machinenotes") & ""
mapleft = "" : If NOT IsNull(rsMachine("mapleft")) Then mapleft = rsMachine("mapleft") mapleft = "" : If NOT IsNull(rsMachine("mapleft")) Then mapleft = rsMachine("mapleft")
maptop = "" : If NOT IsNull(rsMachine("maptop")) Then maptop = rsMachine("maptop") maptop = "" : If NOT IsNull(rsMachine("maptop")) Then maptop = rsMachine("maptop")
pcMachineTypeId = 0 : If NOT IsNull(rsMachine("pcmachinetypeid")) Then pcMachineTypeId = CLng(rsMachine("pcmachinetypeid"))
currentMachineStatusId = "" : If NOT IsNull(rsMachine("machinestatusid")) Then currentMachineStatusId = rsMachine("machinestatusid")
rsMachine.Close rsMachine.Close
Set rsMachine = Nothing Set rsMachine = Nothing
@@ -247,6 +249,25 @@
<small class="form-text text-muted">Network hostname for this PC</small> <small class="form-text text-muted">Network hostname for this PC</small>
</div> </div>
<div class="form-group">
<label for="machinestatusid">Machine Status</label>
<select class="form-control" id="machinestatusid" name="machinestatusid">
<%
Dim rsMachineStatus
Set rsMachineStatus = objConn.Execute("SELECT machinestatusid, machinestatus FROM machinestatus WHERE isactive = 1 ORDER BY machinestatusid")
While Not rsMachineStatus.EOF
Dim selectedMachineStatus
selectedMachineStatus = ""
If CStr(rsMachineStatus("machinestatusid")) = CStr(currentMachineStatusId) Then selectedMachineStatus = " selected"
Response.Write("<option value='" & rsMachineStatus("machinestatusid") & "'" & selectedMachineStatus & ">" & Server.HTMLEncode(rsMachineStatus("machinestatus") & "") & "</option>" & vbCrLf)
rsMachineStatus.MoveNext
Wend
rsMachineStatus.Close
Set rsMachineStatus = Nothing
%>
</select>
</div>
<div class="form-group"> <div class="form-group">
<label for="modelid">Model <span class="text-danger">*</span></label> <label for="modelid">Model <span class="text-danger">*</span></label>
<div class="input-group"> <div class="input-group">
@@ -566,8 +587,23 @@
<select class="form-control" id="controllingpc" name="controllingpc"> <select class="form-control" id="controllingpc" name="controllingpc">
<option value="">-- None --</option> <option value="">-- None --</option>
<% <%
Dim rsControlPCs ' Filter controlled machines based on PC type
strSQL = "SELECT machineid, machinenumber, alias FROM machines WHERE pctypeid IS NULL AND isactive = 1 ORDER BY machinenumber ASC" ' PC - CMM (41) -> CMM equipment (machinetypeid 3)
' PC - Wax Trace (42) -> Wax Trace equipment (machinetypeid 5)
' PC - Measuring Tool (43) -> Measuring Machine equipment (machinetypeid 23)
Dim rsControlPCs, equipmentTypeFilter
equipmentTypeFilter = ""
Select Case pcMachineTypeId
Case 41
equipmentTypeFilter = " AND m.machinetypeid = 3" ' CMM
Case 42
equipmentTypeFilter = " AND m.machinetypeid = 5" ' Wax Trace
Case 43
equipmentTypeFilter = " AND m.machinetypeid = 23" ' Measuring Machine
End Select
strSQL = "SELECT m.machineid, m.machinenumber, m.alias FROM machines m " &_
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " &_
"WHERE m.pctypeid IS NULL AND m.isactive = 1" & equipmentTypeFilter & " ORDER BY m.machinenumber ASC"
Set rsControlPCs = objconn.Execute(strSQL) Set rsControlPCs = objconn.Execute(strSQL)
While Not rsControlPCs.EOF While Not rsControlPCs.EOF
Dim controlPCDisplay, selectedControlPC Dim controlPCDisplay, selectedControlPC
@@ -589,7 +625,18 @@
Set rsControlPCs = Nothing Set rsControlPCs = Nothing
%> %>
</select> </select>
<small class="form-text text-muted">Select a machine that this PC controls</small> <%
' Show filter info for specialized PCs
If pcMachineTypeId = 41 Then
Response.Write("<small class='form-text text-info'><i class='zmdi zmdi-filter-list'></i> Filtered to CMM equipment only</small>")
ElseIf pcMachineTypeId = 42 Then
Response.Write("<small class='form-text text-info'><i class='zmdi zmdi-filter-list'></i> Filtered to Wax Trace equipment only</small>")
ElseIf pcMachineTypeId = 43 Then
Response.Write("<small class='form-text text-info'><i class='zmdi zmdi-filter-list'></i> Filtered to Measuring Machine equipment only</small>")
Else
Response.Write("<small class='form-text text-muted'>Select a machine that this PC controls</small>")
End If
%>
</div> </div>
<!-- Dualpath relationships don't typically apply to PCs --> <!-- Dualpath relationships don't typically apply to PCs -->

View File

@@ -1,211 +0,0 @@
<html>
<head>
<link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"-->
</head>
<body>
<div class="page">
<%
' Get and validate all inputs
Dim printerid, modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, machineid, maptop, mapleft
printerid = Trim(Request.Querystring("printerid"))
modelid = Trim(Request.Form("modelid"))
serialnumber = Trim(Request.Form("serialnumber"))
ipaddress = Trim(Request.Form("ipaddress"))
fqdn = Trim(Request.Form("fqdn"))
printercsfname = Trim(Request.Form("printercsfname"))
printerwindowsname = Trim(Request.Form("printerwindowsname"))
machineid = Trim(Request.Form("machineid"))
maptop = Trim(Request.Form("maptop"))
mapleft = Trim(Request.Form("mapleft"))
' Get form inputs for new model
Dim newmodelnumber, newvendorid, newmodelnotes, newmodeldocpath
newmodelnumber = Trim(Request.Form("newmodelnumber"))
newvendorid = Trim(Request.Form("newvendorid"))
newmodelnotes = Trim(Request.Form("newmodelnotes"))
newmodeldocpath = Trim(Request.Form("newmodeldocpath"))
' Get form inputs for new vendor
Dim newvendorname
newvendorname = Trim(Request.Form("newvendorname"))
' Validate required fields
If Not IsNumeric(printerid) Or CLng(printerid) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid printer ID.</div>")
Response.Write("<a href='displayprinters.asp'>Go back</a>")
objConn.Close
Response.End
End If
If modelid <> "new" And (Not IsNumeric(modelid)) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid model ID.</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
If Not IsNumeric(machineid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid machine ID.</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Validate field lengths
If Len(serialnumber) > 100 Or Len(fqdn) > 255 Or Len(printercsfname) > 50 Or Len(printerwindowsname) > 255 Then
Response.Write("<div class='alert alert-danger'>Error: Field length exceeded.</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Handle new model creation
If modelid = "new" Then
If Len(newmodelnumber) = 0 Then
Response.Write("<div class='alert alert-danger'>New model number is required</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
If Len(newvendorid) = 0 Then
Response.Write("<div class='alert alert-danger'>Vendor is required for new model</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
If Len(newmodelnumber) > 255 Or Len(newmodelnotes) > 255 Or Len(newmodeldocpath) > 255 Then
Response.Write("<div class='alert alert-danger'>Model field length exceeded</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Handle new vendor creation (nested)
If newvendorid = "new" Then
If Len(newvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New vendor name is required</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
If Len(newvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Vendor name too long</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Escape single quotes
Dim escapedVendorName
escapedVendorName = Replace(newvendorname, "'", "''")
' Insert new vendor (with isprinter=1)
Dim sqlNewVendor
sqlNewVendor = "INSERT INTO vendors (vendor, isactive, isprinter, ispc, ismachine) " & _
"VALUES ('" & escapedVendorName & "', 1, 1, 0, 0)"
On Error Resume Next
objConn.Execute sqlNewVendor
If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new vendor: " & Err.Description & "</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Get the newly created vendor ID
Dim rsNewVendor
Set rsNewVendor = objConn.Execute("SELECT LAST_INSERT_ID() AS newid")
newvendorid = CLng(rsNewVendor("newid"))
rsNewVendor.Close
Set rsNewVendor = Nothing
On Error Goto 0
End If
' Escape single quotes for model
Dim escapedModelNumber, escapedModelNotes, escapedModelDocPath
escapedModelNumber = Replace(newmodelnumber, "'", "''")
escapedModelNotes = Replace(newmodelnotes, "'", "''")
escapedModelDocPath = Replace(newmodeldocpath, "'", "''")
' Insert new model
Dim sqlNewModel
sqlNewModel = "INSERT INTO models (modelnumber, vendorid, notes, documentationpath, isactive) " & _
"VALUES ('" & escapedModelNumber & "', " & newvendorid & ", '" & escapedModelNotes & "', '" & escapedModelDocPath & "', 1)"
On Error Resume Next
objConn.Execute sqlNewModel
If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new model: " & Err.Description & "</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
' Get the newly created model ID
Dim rsNewModel
Set rsNewModel = objConn.Execute("SELECT LAST_INSERT_ID() AS newid")
modelid = CLng(rsNewModel("newid"))
rsNewModel.Close
Set rsNewModel = Nothing
On Error Goto 0
End If
' Escape single quotes
serialnumber = Replace(serialnumber, "'", "''")
ipaddress = Replace(ipaddress, "'", "''")
fqdn = Replace(fqdn, "'", "''")
printercsfname = Replace(printercsfname, "'", "''")
printerwindowsname = Replace(printerwindowsname, "'", "''")
' Handle map coordinates - default to 50 if not provided
Dim maptopSQL, mapleftSQL
If maptop <> "" And IsNumeric(maptop) Then
maptopSQL = maptop
Else
maptopSQL = "50"
End If
If mapleft <> "" And IsNumeric(mapleft) Then
mapleftSQL = mapleft
Else
mapleftSQL = "50"
End If
' Build UPDATE statement
Dim strSQL
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
On Error Resume Next
objConn.Execute strSQL
If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error: " & Err.Description & "</div>")
Response.Write("<a href='displayprinter.asp?printerid=" & printerid & "'>Go back</a>")
objConn.Close
Response.End
End If
objConn.Close
%>
<meta http-equiv="refresh" content="0; url=./displayprinter.asp?printerid=<%=Server.HTMLEncode(printerid)%>">
</div>
</body>
</html>

View File

@@ -19,7 +19,7 @@
END IF END IF
' Get and validate all inputs ' Get and validate all inputs
Dim printerid, modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, installpath, machineid, maptop, mapleft Dim printerid, modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, printerpin, installpath, machineid, maptop, mapleft
printerid = Trim(Request.Querystring("printerid")) printerid = Trim(Request.Querystring("printerid"))
modelid = Trim(Request.Form("modelid")) modelid = Trim(Request.Form("modelid"))
serialnumber = Trim(Request.Form("serialnumber")) serialnumber = Trim(Request.Form("serialnumber"))
@@ -27,6 +27,7 @@
fqdn = Trim(Request.Form("fqdn")) fqdn = Trim(Request.Form("fqdn"))
printercsfname = Trim(Request.Form("printercsfname")) printercsfname = Trim(Request.Form("printercsfname"))
printerwindowsname = Trim(Request.Form("printerwindowsname")) printerwindowsname = Trim(Request.Form("printerwindowsname"))
printerpin = Trim(Request.Form("printerpin"))
installpath = Trim(Request.Form("installpath")) installpath = Trim(Request.Form("installpath"))
machineid = Trim(Request.Form("machineid")) machineid = Trim(Request.Form("machineid"))
maptop = Trim(Request.Form("maptop")) maptop = Trim(Request.Form("maptop"))
@@ -188,10 +189,18 @@
mapleftValue = 50 mapleftValue = 50
End If End If
' Handle optional PIN - use NULL if not provided
Dim printerpinValue
If printerpin <> "" Then
printerpinValue = printerpin
Else
printerpinValue = Null
End If
' Update printer using parameterized query ' Update printer using parameterized query
Dim strSQL Dim strSQL
strSQL = "UPDATE printers SET modelid = ?, serialnumber = ?, ipaddress = ?, fqdn = ?, " & _ strSQL = "UPDATE printers SET modelid = ?, serialnumber = ?, ipaddress = ?, fqdn = ?, " & _
"printercsfname = ?, printerwindowsname = ?, installpath = ?, machineid = ?, maptop = ?, mapleft = ? " & _ "printercsfname = ?, printerwindowsname = ?, printerpin = ?, installpath = ?, machineid = ?, maptop = ?, mapleft = ? " & _
"WHERE printerid = ?" "WHERE printerid = ?"
On Error Resume Next On Error Resume Next
@@ -208,6 +217,7 @@
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@fqdn", 200, 1, 255, fqdn) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@fqdn", 200, 1, 255, fqdn)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@printercsfname", 200, 1, 50, printercsfname) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@printercsfname", 200, 1, 50, printercsfname)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@printerwindowsname", 200, 1, 255, printerwindowsname) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@printerwindowsname", 200, 1, 255, printerwindowsname)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@printerpin", 200, 1, 10, printerpinValue)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@installpath", 200, 1, 100, installpath) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@installpath", 200, 1, 100, installpath)
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@machineid", 3, 1, , CLng(machineid)) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@maptop", 3, 1, , maptopValue) cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@maptop", 3, 1, , maptopValue)

View File

@@ -1,28 +0,0 @@
-- Find duplicate vendors
SELECT
vendor,
COUNT(*) as count,
GROUP_CONCAT(vendorid ORDER BY vendorid) as vendor_ids
FROM vendors
GROUP BY LOWER(TRIM(vendor))
HAVING COUNT(*) > 1
ORDER BY count DESC, vendor;
-- Find duplicate models
SELECT
modelnumber,
vendorid,
COUNT(*) as count,
GROUP_CONCAT(modelnumberid ORDER BY modelnumberid) as model_ids
FROM models
GROUP BY LOWER(TRIM(modelnumber)), vendorid
HAVING COUNT(*) > 1
ORDER BY count DESC, modelnumber;
-- Find vendors with case/spacing differences
SELECT
vendor,
vendorid,
LOWER(TRIM(vendor)) as normalized
FROM vendors
ORDER BY normalized, vendorid;

View File

@@ -6,7 +6,6 @@
<title>West Jefferson DT Homepage 2.0</title> <title>West Jefferson DT Homepage 2.0</title>
<!-- loader--> <!-- loader-->
<link href="assets/css/pace.min.css" rel="stylesheet"/> <link href="assets/css/pace.min.css" rel="stylesheet"/>
<script src="assets/js/pace.min.j2s"></script>
<!--favicon--> <!--favicon-->
<link rel="icon" href="assets/images/favicon.ico" type="image/x-icon"> <link rel="icon" href="assets/images/favicon.ico" type="image/x-icon">
<!-- simplebar CSS--> <!-- simplebar CSS-->

View File

@@ -1,3 +1,34 @@
<%
' Calculate fiscal week (GE fiscal year starts first Monday of January)
Dim fwToday, fwYearStart, fwFirstMonday, fwDayOfWeek, fwDaysFromStart, fiscalWeek
fwToday = Date()
' Find first Monday of current year
fwYearStart = DateSerial(Year(fwToday), 1, 1)
fwDayOfWeek = Weekday(fwYearStart, vbMonday) ' 1=Monday, 7=Sunday
If fwDayOfWeek = 1 Then
fwFirstMonday = fwYearStart
Else
fwFirstMonday = DateAdd("d", 8 - fwDayOfWeek, fwYearStart)
End If
' If we're before the first Monday, use previous year's week count
If fwToday < fwFirstMonday Then
Dim fwPrevYearStart, fwPrevFirstMonday, fwPrevDayOfWeek
fwPrevYearStart = DateSerial(Year(fwToday) - 1, 1, 1)
fwPrevDayOfWeek = Weekday(fwPrevYearStart, vbMonday)
If fwPrevDayOfWeek = 1 Then
fwPrevFirstMonday = fwPrevYearStart
Else
fwPrevFirstMonday = DateAdd("d", 8 - fwPrevDayOfWeek, fwPrevYearStart)
End If
fwDaysFromStart = DateDiff("d", fwPrevFirstMonday, fwToday)
fiscalWeek = Int(fwDaysFromStart / 7) + 1
Else
fwDaysFromStart = DateDiff("d", fwFirstMonday, fwToday)
fiscalWeek = Int(fwDaysFromStart / 7) + 1
End If
%>
<!--Start sidebar-wrapper--> <!--Start sidebar-wrapper-->
<div id="sidebar-wrapper" data-simplebar="" data-simplebar-auto-hide="true"> <div id="sidebar-wrapper" data-simplebar="" data-simplebar-auto-hide="true">
<div class="brand-logo"> <div class="brand-logo">
@@ -6,6 +37,7 @@
<h5 class="logo-text">West Jefferson</h5> <h5 class="logo-text">West Jefferson</h5>
</a> </a>
</div> </div>
<div style="font-size: 10px; color: #888; text-align: center; padding-bottom: 8px;">Fiscal Week <%=fiscalWeek%></div>
<ul class="sidebar-menu do-nicescrol"> <ul class="sidebar-menu do-nicescrol">
<li class="sidebar-header">MAIN NAVIGATION</li> <li class="sidebar-header">MAIN NAVIGATION</li>
<li> <li>
@@ -53,7 +85,9 @@
<li><a href="./displaysubnets.asp"><i class="zmdi zmdi-network text-danger"></i><span>Network</span></a></li> <li><a href="./displaysubnets.asp"><i class="zmdi zmdi-network text-danger"></i><span>Network</span></a></li>
<li><a href="./network_devices.asp"><i class="zmdi zmdi-device-hub text-info"></i><span>Network Devices</span></a></li> <li><a href="./network_devices.asp"><i class="zmdi zmdi-device-hub text-info"></i><span>Network Devices</span></a></li>
<li><a href="./displaypcs.asp"><i class="zmdi zmdi-desktop-windows text-primary"></i><span>PC Admin</span></a></li> <li><a href="./displaypcs.asp"><i class="zmdi zmdi-desktop-windows text-primary"></i><span>PC Admin</span></a></li>
<li><a href="./displayusb.asp"><i class="zmdi zmdi-usb text-purple"></i><span>USB Devices</span></a></li>
<li><a href="./displaynotifications.asp"><i class="zmdi zmdi zmdi-notifications-none text-success"></i><span>Notifications</span></a></li> <li><a href="./displaynotifications.asp"><i class="zmdi zmdi zmdi-notifications-none text-success"></i><span>Notifications</span></a></li>
<li><a href="./tv-dashboard/" target="_blank"><i class="zmdi zmdi-tv text-warning"></i><span>Lobby Display</span></a></li>
<li><a href="javaScript:void();"><i class="zmdi zmdi-share text-info"></i> <span>Information</span></a></li> <li><a href="javaScript:void();"><i class="zmdi zmdi-share text-info"></i> <span>Information</span></a></li>
</ul> </ul>

214
includes/response.asp Normal file
View File

@@ -0,0 +1,214 @@
<%
'=============================================================================
' FILE: includes/response.asp
' PURPOSE: Styled error and success response pages for form submissions
' USAGE: Include this file, then call ShowError() or ShowSuccess()
'=============================================================================
Sub ShowError(errorMessage, backUrl)
%>
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="header.asp"-->
<style>
.response-container {
min-height: 60vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.response-icon {
font-size: 80px;
margin-bottom: 20px;
}
.response-icon.error { color: #f44336; }
.response-icon.success { color: #28a745; }
.response-message {
font-size: 24px;
margin-bottom: 30px;
}
.alert-custom {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.alert-error {
background-color: rgba(244, 67, 54, 0.1);
border-color: rgba(244, 67, 54, 0.3);
color: #f44336;
}
.alert-success {
background-color: rgba(40, 167, 69, 0.1);
border-color: rgba(40, 167, 69, 0.3);
color: #28a745;
}
</style>
</head>
<%
Dim respTheme
respTheme = Request.Cookies("theme")
If respTheme = "" Then respTheme = "bg-theme1"
%>
<body class="bg-theme <%=respTheme%>">
<!-- 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="leftsidebar.asp"-->
<!--#include file="topbarheader.asp"-->
<div class="clearfix"></div>
<div class="content-wrapper">
<div class="container-fluid">
<div class="response-container">
<div>
<div class="response-icon error">
<i class="zmdi zmdi-alert-triangle"></i>
</div>
<div class="response-message">Error</div>
<div class="alert-custom alert-error">
<strong><i class="zmdi zmdi-info"></i> Details:</strong><br>
<%=Server.HTMLEncode(errorMessage)%>
</div>
<div style="margin-top: 30px;">
<a href="<%=Server.HTMLEncode(backUrl)%>" class="btn btn-primary btn-lg">
<i class="zmdi zmdi-arrow-left"></i> Go Back
</a>
<a href="default.asp" class="btn btn-secondary btn-lg">
<i class="zmdi zmdi-home"></i> Dashboard
</a>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container"><div class="text-center"></div></div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
</body>
</html>
<%
End Sub
Sub ShowSuccess(successMessage, redirectUrl, entityName)
%>
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="header.asp"-->
<style>
.response-container {
min-height: 60vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.response-icon {
font-size: 80px;
margin-bottom: 20px;
}
.response-icon.error { color: #f44336; }
.response-icon.success { color: #28a745; }
.response-message {
font-size: 24px;
margin-bottom: 30px;
}
.alert-custom {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.alert-error {
background-color: rgba(244, 67, 54, 0.1);
border-color: rgba(244, 67, 54, 0.3);
color: #f44336;
}
.alert-success {
background-color: rgba(40, 167, 69, 0.1);
border-color: rgba(40, 167, 69, 0.3);
color: #28a745;
}
</style>
<meta http-equiv="refresh" content="2; url=<%=Server.HTMLEncode(redirectUrl)%>">
</head>
<%
Dim succTheme
succTheme = Request.Cookies("theme")
If succTheme = "" Then succTheme = "bg-theme1"
%>
<body class="bg-theme <%=succTheme%>">
<!-- 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="leftsidebar.asp"-->
<!--#include file="topbarheader.asp"-->
<div class="clearfix"></div>
<div class="content-wrapper">
<div class="container-fluid">
<div class="response-container">
<div>
<div class="response-icon success">
<i class="zmdi zmdi-check-circle"></i>
</div>
<div class="response-message">Success!</div>
<div class="alert-custom alert-success">
<strong><i class="zmdi zmdi-check"></i></strong>
<%=Server.HTMLEncode(successMessage)%>
</div>
<div style="margin-top: 20px; opacity: 0.7;">
Redirecting to <%=Server.HTMLEncode(entityName)%>...
</div>
<div style="margin-top: 30px;">
<a href="<%=Server.HTMLEncode(redirectUrl)%>" class="btn btn-primary btn-lg">
<i class="zmdi zmdi-arrow-right"></i> Go Now
</a>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container"><div class="text-center"></div></div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
</body>
</html>
<%
End Sub
%>

View File

@@ -1,5 +1,5 @@
<% <%
Dim objConn ' objConn - script-global connection object (no Dim for global scope)
Session.Timeout=15 Session.Timeout=15
Set objConn=Server.CreateObject("ADODB.Connection") Set objConn=Server.CreateObject("ADODB.Connection")
objConn.ConnectionString="DSN=shopdb;Uid=root;Pwd=WJF11sql;Option=3;Pooling=True;Max Pool Size=100;" objConn.ConnectionString="DSN=shopdb;Uid=root;Pwd=WJF11sql;Option=3;Pooling=True;Max Pool Size=100;"

View File

@@ -133,7 +133,7 @@ Set rsStatus = Nothing
"LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _ "LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _
"LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _ "LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _
"LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _ "LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _
"WHERE m.isactive = 1 AND m.pctypeid IS NOT NULL " "WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Apply filters ' Apply filters
whereClause = "" whereClause = ""
@@ -162,7 +162,7 @@ Set rsStatus = Nothing
while not rs.eof while not rs.eof
%> %>
<td><a href="./displaypc.asp?pcid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><% <td><a href="./displaypc.asp?machineid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><%
Dim displayName Dim displayName
If IsNull(rs("hostname")) Or rs("hostname") = "" Then If IsNull(rs("hostname")) Or rs("hostname") = "" Then
displayName = rs("serialnumber") displayName = rs("serialnumber")

185
logs/api-2025-11-21.log Executable file
View File

@@ -0,0 +1,185 @@
11/21/2025 1:26:21 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:26:21 PM - Hostname: H2PRFM94
11/21/2025 1:26:21 PM - Serial: 2PRFM94
11/21/2025 1:26:21 PM - PC Type: Standard
11/21/2025 1:26:22 PM - Created new vendor ID: 34
11/21/2025 1:26:22 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 1:26:22 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 1:26:22 PM - Updating existing PC, machineid: 5360
11/21/2025 1:26:22 PM - UPDATE SQL built: UPDATE machines SET serialnumber = '2PRFM94', modelnumberid = 1, machinetypeid = 33, loggedinuser = '570005354', machinenumber = NULL, osid = 18, machinestatusid = 3, lastupdated = NOW() WHERE machine...
11/21/2025 1:26:22 PM - InsertOrUpdatePC returning machineid: 5360
11/21/2025 1:26:22 PM - PC record created/updated. machineid: 5360
11/21/2025 1:27:05 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:27:05 PM - Hostname: TESTPC002
11/21/2025 1:27:05 PM - Serial: TEST002
11/21/2025 1:27:05 PM - PC Type: Standard
11/21/2025 1:27:05 PM - Found existing vendor ID: 34
11/21/2025 1:27:05 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 1:27:05 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 1:27:05 PM - Inserting new PC
11/21/2025 1:27:05 PM - Building INSERT SQL...
11/21/2025 1:27:05 PM - Values: hostname=TESTPC002, serial=TEST002
11/21/2025 1:27:05 PM - SQL built successfully, executing...
11/21/2025 1:27:05 PM - Retrieved new machineid from LAST_INSERT_ID: 5470
11/21/2025 1:27:05 PM - InsertOrUpdatePC returning machineid: 5470
11/21/2025 1:27:05 PM - PC record created/updated. machineid: 5470
11/21/2025 1:29:53 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:29:53 PM - Hostname: TESTPC003
11/21/2025 1:29:53 PM - Serial: TEST003
11/21/2025 1:29:53 PM - PC Type: Standard
11/21/2025 1:29:53 PM - Found existing vendor ID: 34
11/21/2025 1:29:53 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 1:29:53 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 1:29:53 PM - Inserting new PC
11/21/2025 1:29:53 PM - Building INSERT SQL...
11/21/2025 1:29:53 PM - Values: hostname=TESTPC003, serial=TEST003
11/21/2025 1:29:53 PM - SQL built successfully, executing...
11/21/2025 1:29:54 PM - Retrieved new machineid from LAST_INSERT_ID: 5471
11/21/2025 1:29:54 PM - InsertOrUpdatePC returning machineid: 5471
11/21/2025 1:29:54 PM - PC record created/updated. machineid: 5471
11/21/2025 1:33:19 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:33:19 PM - Hostname: APITEST-STD01
11/21/2025 1:33:19 PM - Serial: APITEST001
11/21/2025 1:33:19 PM - PC Type: Standard
11/21/2025 1:33:19 PM - Found existing vendor ID: 34
11/21/2025 1:33:19 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 1:33:20 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 1:33:20 PM - Inserting new PC
11/21/2025 1:33:20 PM - Building INSERT SQL...
11/21/2025 1:33:20 PM - Values: hostname=APITEST-STD01, serial=APITEST001
11/21/2025 1:33:20 PM - SQL built successfully, executing...
11/21/2025 1:33:20 PM - Retrieved new machineid from LAST_INSERT_ID: 5472
11/21/2025 1:33:20 PM - InsertOrUpdatePC returning machineid: 5472
11/21/2025 1:33:20 PM - PC record created/updated. machineid: 5472
11/21/2025 1:33:51 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:33:51 PM - Hostname: APITEST-SHOP01
11/21/2025 1:33:51 PM - Serial: APITEST002
11/21/2025 1:33:51 PM - PC Type: Shopfloor
11/21/2025 1:33:51 PM - ClearShopfloorData: Cannot find machineid for hostname: APITEST-SHOP01
11/21/2025 1:33:51 PM - Found existing vendor ID: 12
11/21/2025 1:33:51 PM - Mapped pcType 'Shopfloor' to machinetypeid: 35
11/21/2025 1:33:51 PM - Vendor ID: 12, Model ID: 1, Machine Type ID: 35
11/21/2025 1:33:51 PM - Inserting new PC
11/21/2025 1:33:52 PM - Building INSERT SQL...
11/21/2025 1:33:52 PM - Values: hostname=APITEST-SHOP01, serial=APITEST002
11/21/2025 1:33:52 PM - SQL built successfully, executing...
11/21/2025 1:33:52 PM - Retrieved new machineid from LAST_INSERT_ID: 5473
11/21/2025 1:33:52 PM - InsertOrUpdatePC returning machineid: 5473
11/21/2025 1:33:52 PM - PC record created/updated. machineid: 5473
11/21/2025 1:33:52 PM - ERROR inserting network interface: [MySQL][ODBC 9.4(w) Driver][mysqld-5.6.51]Unknown column 'gateway' in 'field list'
11/21/2025 1:33:52 PM - ERROR inserting network interface: [MySQL][ODBC 9.4(w) Driver][mysqld-5.6.51]Unknown column 'gateway' in 'field list'
11/21/2025 1:33:52 PM - Network interfaces inserted: 0
11/21/2025 1:33:52 PM - Comm configs inserted: 0
11/21/2025 1:33:52 PM - ERROR inserting DNC config: [MySQL][ODBC 9.4(w) Driver][mysqld-5.6.51]Unknown column 'machineid' in 'field list'
11/21/2025 1:33:52 PM - DNC config inserted: False
11/21/2025 1:33:52 PM - CreatePCMachineRelationship: Executing SQL: SELECT machineid FROM machines WHERE machinenumber = 'M1234' AND machinetypeid NOT IN (33,34,35)
11/21/2025 1:33:52 PM - CreatePCMachineRelationship: Equipment not found for machine number: M1234
11/21/2025 1:33:52 PM - PC-Machine relationship created: False
11/21/2025 1:35:26 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:35:26 PM - Hostname: APITEST-SHOP02
11/21/2025 1:35:26 PM - Serial: APITEST003
11/21/2025 1:35:26 PM - PC Type: Shopfloor
11/21/2025 1:35:26 PM - ClearShopfloorData: Cannot find machineid for hostname: APITEST-SHOP02
11/21/2025 1:35:27 PM - Found existing vendor ID: 12
11/21/2025 1:35:27 PM - Mapped pcType 'Shopfloor' to machinetypeid: 35
11/21/2025 1:35:27 PM - Vendor ID: 12, Model ID: 1, Machine Type ID: 35
11/21/2025 1:35:27 PM - Inserting new PC
11/21/2025 1:35:27 PM - Building INSERT SQL...
11/21/2025 1:35:27 PM - Values: hostname=APITEST-SHOP02, serial=APITEST003
11/21/2025 1:35:27 PM - SQL built successfully, executing...
11/21/2025 1:35:27 PM - Retrieved new machineid from LAST_INSERT_ID: 5474
11/21/2025 1:35:27 PM - InsertOrUpdatePC returning machineid: 5474
11/21/2025 1:35:27 PM - PC record created/updated. machineid: 5474
11/21/2025 1:35:27 PM - Network interfaces inserted: 2
11/21/2025 1:35:27 PM - CreatePCMachineRelationship: Executing SQL: SELECT machineid FROM machines WHERE machinenumber = 'M1234' AND machinetypeid NOT IN (33,34,35)
11/21/2025 1:35:27 PM - CreatePCMachineRelationship: Equipment not found for machine number: M1234
11/21/2025 1:35:27 PM - PC-Machine relationship created: False
11/21/2025 1:36:43 PM - UpdatePrinterMapping: hostname=APITEST-STD01, printerFQDN=Printer-10-80-92-48.printer.geaerospace.net
11/21/2025 1:37:06 PM - UpdatePrinterMapping: hostname=APITEST-STD01, printerFQDN=Printer-10-80-92-48.printer.geaerospace.net
11/21/2025 1:37:20 PM - UpdatePrinterMapping: hostname=APITEST-STD01, printerFQDN=10.80.92.48
11/21/2025 1:39:58 PM - UpdateInstalledApps: hostname=APITEST-STD01
11/21/2025 1:39:58 PM - Parsed apps array, count: 2
11/21/2025 1:39:58 PM - App 0: name='', version=''
11/21/2025 1:39:58 PM - App 1: name='', version=''
11/21/2025 1:39:58 PM - Installed apps inserted: 0
11/21/2025 1:43:34 PM - UpdateInstalledApps: hostname=APITEST-STD01
11/21/2025 1:43:34 PM - Parsed apps array, count: 2
11/21/2025 1:43:34 PM - App 0: name='Microsoft Office', version='16.0'
11/21/2025 1:43:34 PM - GetOrCreateApplication called with appName='Microsoft Office', appVersion='16.0'
11/21/2025 1:43:34 PM - ERROR querying applications: Variable is undefined
11/21/2025 1:43:34 PM - GetOrCreateApplication returned appid: 0
11/21/2025 1:43:34 PM - App 1: name='Chrome', version='120.0'
11/21/2025 1:43:34 PM - GetOrCreateApplication called with appName='Chrome', appVersion='120.0'
11/21/2025 1:43:34 PM - ERROR querying applications: Variable is undefined
11/21/2025 1:43:34 PM - GetOrCreateApplication returned appid: 0
11/21/2025 1:43:35 PM - Installed apps inserted: 0
11/21/2025 12:13:39 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:13:39 PM - Hostname: TESTPC-V4
11/21/2025 12:13:39 PM - Serial: TEST123
11/21/2025 12:13:39 PM - PC Type: Standard
11/21/2025 12:13:39 PM - Found existing vendor ID: 34
11/21/2025 12:13:39 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 12:13:39 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 12:13:39 PM - Inserting new PC
11/21/2025 12:13:39 PM - Building INSERT SQL...
11/21/2025 12:13:39 PM - Values: hostname=TESTPC-V4, serial=TEST123
11/21/2025 12:13:39 PM - SQL built successfully, executing...
11/21/2025 12:13:39 PM - Retrieved new machineid from LAST_INSERT_ID: 5475
11/21/2025 12:13:39 PM - InsertOrUpdatePC returning machineid: 5475
11/21/2025 12:13:39 PM - PC record created/updated. machineid: 5475
11/21/2025 12:17:19 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:17:19 PM - Hostname: TESTPC-V6
11/21/2025 12:17:19 PM - Serial: TEST123V6
11/21/2025 12:17:20 PM - PC Type: Standard
11/21/2025 12:17:20 PM - Found existing vendor ID: 34
11/21/2025 12:17:20 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 12:17:20 PM - Vendor ID: 34, Model ID: 1, Machine Type ID: 33
11/21/2025 12:17:20 PM - Inserting new PC
11/21/2025 12:17:20 PM - Building INSERT SQL...
11/21/2025 12:17:20 PM - Values: hostname=TESTPC-V6, serial=TEST123V6
11/21/2025 12:17:20 PM - SQL built successfully, executing...
11/21/2025 12:17:20 PM - Retrieved new machineid from LAST_INSERT_ID: 5476
11/21/2025 12:17:20 PM - InsertOrUpdatePC returning machineid: 5476
11/21/2025 12:17:20 PM - PC record created/updated. machineid: 5476
11/21/2025 12:20:14 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:20:14 PM - Hostname: TESTPC-V7
11/21/2025 12:20:14 PM - Serial: TEST123V7
11/21/2025 12:20:15 PM - PC Type: Standard
11/21/2025 12:20:15 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 12:20:15 PM - Vendor ID: 34, Model ID: 98, Machine Type ID: 33
11/21/2025 12:20:15 PM - Inserting new PC
11/21/2025 12:20:15 PM - Building INSERT SQL...
11/21/2025 12:20:15 PM - Values: hostname=TESTPC-V7, serial=TEST123V7
11/21/2025 12:20:15 PM - SQL built successfully, executing...
11/21/2025 12:20:15 PM - Retrieved new machineid from LAST_INSERT_ID: 5477
11/21/2025 12:20:15 PM - InsertOrUpdatePC returning machineid: 5477
11/21/2025 12:20:15 PM - PC record created/updated. machineid: 5477
11/21/2025 12:22:09 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:22:09 PM - Hostname: TESTPC-V8
11/21/2025 12:22:09 PM - Serial: TEST123V8
11/21/2025 12:22:09 PM - PC Type: Standard
11/21/2025 12:22:10 PM - Mapped pcType 'Standard' to machinetypeid: 33
11/21/2025 12:22:10 PM - Vendor ID: 34, Model ID: 98, Machine Type ID: 33
11/21/2025 12:22:10 PM - Inserting new PC
11/21/2025 12:22:10 PM - Building INSERT SQL...
11/21/2025 12:22:10 PM - Values: hostname=TESTPC-V8, serial=TEST123V8
11/21/2025 12:22:10 PM - SQL built successfully, executing...
11/21/2025 12:22:10 PM - Retrieved new machineid from LAST_INSERT_ID: 5478
11/21/2025 12:22:10 PM - InsertOrUpdatePC returning machineid: 5478
11/21/2025 12:22:10 PM - PC record created/updated. machineid: 5478
11/21/2025 12:26:13 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:26:13 PM - Hostname: TESTPC-V10
11/21/2025 12:26:13 PM - Serial: TEST123V10
11/21/2025 12:26:13 PM - PC Type: Standard
11/21/2025 12:26:48 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 12:26:48 PM - Hostname: TESTPC-V10B
11/21/2025 12:26:48 PM - Serial: TEST123V10B
11/21/2025 12:26:48 PM - PC Type: Standard
11/21/2025 12:26:48 PM - PC record created/updated. machineid: 5479
11/21/2025 1:01:43 PM - UpdatePrinterMapping: hostname=TESTPC-V10B, printerFQDN=10.80.92.57
11/21/2025 1:04:25 PM - === NEW updateCompleteAsset REQUEST ===
11/21/2025 1:04:25 PM - Hostname: TESTPC-V13
11/21/2025 1:04:25 PM - Serial: TEST123V13
11/21/2025 1:04:25 PM - PC Type: Standard
11/21/2025 1:04:25 PM - PC record created/updated. machineid: 5480
11/21/2025 1:04:33 PM - UpdatePrinterMapping: hostname=TESTPC-V13, printerFQDN=10.80.92.57

29
logs/api-2025-12-02.log Executable file
View File

@@ -0,0 +1,29 @@
12/2/2025 4:23:21 AM - UpdateInstalledApps: hostname=G7B48FZ3ESF
12/2/2025 4:23:21 AM - Parsed apps array, count: 2
12/2/2025 4:23:21 AM - App 0: appid=30, appname='Tanium', version='7.4.7.1179'
12/2/2025 4:23:22 AM - GetOrCreateAppVersion called with appId=30, appVersion='7.4.7.1179'
12/2/2025 4:23:22 AM - Version not found, creating new...
12/2/2025 4:23:22 AM - Created new app version with id: 1
12/2/2025 4:23:22 AM - GetOrCreateAppVersion returned appversionid: 1
12/2/2025 4:23:22 AM - ERROR inserting installedapp: Type mismatch
12/2/2025 4:23:22 AM - App 1: appid=7, appname='Oracle', version='11r2'
12/2/2025 4:23:22 AM - GetOrCreateAppVersion called with appId=7, appVersion='11r2'
12/2/2025 4:23:22 AM - Version not found, creating new...
12/2/2025 4:23:22 AM - Created new app version with id: 2
12/2/2025 4:23:22 AM - GetOrCreateAppVersion returned appversionid: 2
12/2/2025 4:23:22 AM - ERROR inserting installedapp: Type mismatch
12/2/2025 4:23:22 AM - Installed apps inserted: 0
12/2/2025 4:29:48 AM - UpdateInstalledApps: hostname=G7B48FZ3ESF
12/2/2025 4:29:48 AM - Parsed apps array, count: 1
12/2/2025 4:29:48 AM - App 0: appid=30, appname='Tanium', version='7.4.7.1179'
12/2/2025 4:29:48 AM - GetOrCreateAppVersion called with appId=30, appVersion='7.4.7.1179'
12/2/2025 4:29:48 AM - Found existing appversionid: 1
12/2/2025 4:29:48 AM - GetOrCreateAppVersion returned appversionid: 1
12/2/2025 4:29:48 AM - Installed apps inserted: 1
12/2/2025 5:03:28 AM - UpdateInstalledApps: hostname=G9KN7PZ3ESF
12/2/2025 5:03:28 AM - Parsed apps array, count: 1
12/2/2025 5:03:28 AM - App 0: appid=30, appname='Tanium', version='7.4.7.1179'
12/2/2025 5:03:28 AM - GetOrCreateAppVersion called with appId=30, appVersion='7.4.7.1179'
12/2/2025 5:03:28 AM - Found existing appversionid: 1
12/2/2025 5:03:28 AM - GetOrCreateAppVersion returned appversionid: 1
12/2/2025 5:03:28 AM - Installed apps inserted: 1

25
logs/api-2025-12-03.log Executable file
View File

@@ -0,0 +1,25 @@
12/3/2025 9:22:06 AM - === NEW updateCompleteAsset REQUEST ===
12/3/2025 9:22:06 AM - Hostname: TEST-CMM-PC
12/3/2025 9:22:06 AM - Serial: TESTCMM123
12/3/2025 9:22:06 AM - PC Type: CMM
12/3/2025 9:22:06 AM - PC record created/updated. machineid: 5778
12/3/2025 9:23:38 AM - === NEW updateCompleteAsset REQUEST ===
12/3/2025 9:23:38 AM - Hostname: TEST-CMM-PC2
12/3/2025 9:23:38 AM - Serial: TESTCMM456
12/3/2025 9:23:38 AM - PC Type: CMM
12/3/2025 9:23:39 AM - PC record created/updated. machineid: 5779
12/3/2025 9:23:52 AM - === NEW updateCompleteAsset REQUEST ===
12/3/2025 9:23:52 AM - Hostname: TEST-WAXTRACE-PC
12/3/2025 9:23:53 AM - Serial: TESTWAX123
12/3/2025 9:23:53 AM - PC Type: WaxTrace
12/3/2025 9:23:53 AM - PC record created/updated. machineid: 5780
12/3/2025 9:24:17 AM - === NEW updateCompleteAsset REQUEST ===
12/3/2025 9:24:17 AM - Hostname: TEST-KEYENCE-PC
12/3/2025 9:24:17 AM - Serial: TESTKEY123
12/3/2025 9:24:17 AM - PC Type: Keyence
12/3/2025 9:24:17 AM - PC record created/updated. machineid: 5781
12/3/2025 9:42:01 AM - === NEW updateCompleteAsset REQUEST ===
12/3/2025 9:42:01 AM - Hostname: TEST-CMM-PC
12/3/2025 9:42:01 AM - Serial: TESTCMM999
12/3/2025 9:42:01 AM - PC Type: CMM
12/3/2025 9:42:01 AM - PC record created/updated. machineid: 5782

6
logs/api-2025-12-04.log Executable file
View File

@@ -0,0 +1,6 @@
12/4/2025 1:36:22 PM - === NEW updateCompleteAsset REQUEST ===
12/4/2025 1:36:22 PM - Hostname: TEST-CURL-PC
12/4/2025 1:36:22 PM - Serial: CURL12345
12/4/2025 1:36:22 PM - PC Type: Shopfloor
12/4/2025 1:36:22 PM - ClearShopfloorData: Cannot find machineid for hostname: TEST-CURL-PC
12/4/2025 1:36:23 PM - PC record created/updated. machineid: 5780

View File

@@ -570,7 +570,7 @@
<option value="">-- None --</option> <option value="">-- None --</option>
<% <%
Dim rsControlPCs Dim rsControlPCs
strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE pctypeid IS NOT NULL AND isactive = 1 ORDER BY machinenumber ASC" strSQL = "SELECT machineid, machinenumber, hostname FROM machines WHERE machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43) AND isactive = 1 ORDER BY machinenumber ASC"
Set rsControlPCs = objconn.Execute(strSQL) Set rsControlPCs = objconn.Execute(strSQL)
While Not rsControlPCs.EOF While Not rsControlPCs.EOF
Dim controlPCDisplay, selectedControlPC Dim controlPCDisplay, selectedControlPC

525
machine_map.asp Normal file
View File

@@ -0,0 +1,525 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
<link rel="stylesheet" href="./leaflet/leaflet.css">
<script src="./leaflet/leaflet.js"></script>
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
%>
<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="row">
<div class="col-lg-9">
<div class="card">
<div class="card-body" style="padding:0;">
<div style="padding:15px; border-bottom:1px solid #444;">
<h5 class="card-title" style="margin:0; display:inline-block;">
<i class='zmdi zmdi-reader'></i>&nbsp;&nbsp;Machine Map
</h5>
<div style="float:right;">
<input type="text" id="machineSearch" class="form-control form-control-sm" placeholder="Search by name, serial, vendor, model..." style="display:inline-block; width:200px; margin-right:10px;">
<label style="margin-right:5px; display:inline-block; color:#aaa;">BU:</label>
<select id="businessUnitFilter" class="form-control form-control-sm" style="display:inline-block; width:120px; margin-right:10px;">
<option value="all">All</option>
<%
' Get business units for dropdown
Dim rsBU, strBUSQL
strBUSQL = "SELECT businessunitid, businessunit FROM businessunits WHERE isactive = 1 ORDER BY businessunit"
Set rsBU = objConn.Execute(strBUSQL)
Do While Not rsBU.EOF
Response.Write("<option value='" & rsBU("businessunitid") & "'>" & Server.HTMLEncode(rsBU("businessunit")) & "</option>")
rsBU.MoveNext
Loop
rsBU.Close
Set rsBU = Nothing
%>
</select>
<label style="margin-right:5px; display:inline-block; color:#aaa;">Type:</label>
<select id="machineTypeFilter" class="form-control form-control-sm" style="display:inline-block; width:140px; margin-right:10px;">
<option value="all">All Types</option>
<%
' Get machine types for dropdown (exclude PC types and network device types)
Dim rsMT, strMTSQL
strMTSQL = "SELECT machinetypeid, machinetype FROM machinetypes WHERE machinetypeid < 16 AND isactive = 1 ORDER BY machinetype"
Set rsMT = objConn.Execute(strMTSQL)
Do While Not rsMT.EOF
Response.Write("<option value='" & rsMT("machinetypeid") & "'>" & Server.HTMLEncode(rsMT("machinetype")) & "</option>")
rsMT.MoveNext
Loop
rsMT.Close
Set rsMT = Nothing
%>
</select>
<label style="margin-right:5px; display:inline-block; color:#aaa;">Status:</label>
<select id="machineStatusFilter" class="form-control form-control-sm" style="display:inline-block; width:120px;">
<option value="all">All</option>
<%
' Get machine statuses for dropdown
Dim rsMS, strMSSQL
strMSSQL = "SELECT machinestatusid, machinestatus FROM machinestatus ORDER BY machinestatus"
Set rsMS = objConn.Execute(strMSSQL)
Do While Not rsMS.EOF
Response.Write("<option value='" & rsMS("machinestatusid") & "'>" & Server.HTMLEncode(rsMS("machinestatus")) & "</option>")
rsMS.MoveNext
Loop
rsMS.Close
Set rsMS = Nothing
%>
</select>
</div>
</div>
<div id="map"></div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card">
<div class="card-header" style="background: linear-gradient(45deg, #667eea, #764ba2); color: white;">
<i class="zmdi zmdi-info"></i> Legend
</div>
<div class="card-body">
<p style="font-size:12px; color:#aaa; margin-bottom:15px;">
Machine type color codes:
</p>
<div style="margin-bottom:20px;">
<%
' Get machine types with colors for legend
Dim rsLegend, strLegendSQL
strLegendSQL = "SELECT machinetypeid, machinetype FROM machinetypes WHERE machinetypeid < 16 AND isactive = 1 ORDER BY machinetype"
Set rsLegend = objConn.Execute(strLegendSQL)
Do While Not rsLegend.EOF
Dim legendColor
Select Case rsLegend("machinetypeid")
Case 1: legendColor = "#4CAF50" ' CNC
Case 2: legendColor = "#2196F3" ' Grinder
Case 3: legendColor = "#FF9800" ' Lathe
Case 4: legendColor = "#F44336" ' Mill
Case 5: legendColor = "#9C27B0" ' CMM
Case 6: legendColor = "#00BCD4" ' EDM
Case 7: legendColor = "#E91E63" ' Press
Case 8: legendColor = "#607D8B" ' Saw
Case 9: legendColor = "#795548" ' Welder
Case 10: legendColor = "#FF5722" ' Drill
Case 11: legendColor = "#3F51B5" ' Robot
Case 12: legendColor = "#8BC34A" ' Inspection
Case 13: legendColor = "#CDDC39" ' Assembly
Case 14: legendColor = "#FFC107" ' Other
Case 15: legendColor = "#009688" ' Wash
Case Else: legendColor = "#FFC107"
End Select
Response.Write("<div style='margin:8px 0; display:flex; align-items:center;'>")
Response.Write("<span style='display:inline-block; width:16px; height:16px; background:" & legendColor & "; border-radius:50%; margin-right:10px; border:2px solid #fff; box-shadow:0 2px 5px rgba(0,0,0,0.5);'></span>")
Response.Write("<span style='font-size:13px; color:#fff;'>" & Server.HTMLEncode(rsLegend("machinetype")) & "</span>")
Response.Write("</div>")
rsLegend.MoveNext
Loop
rsLegend.Close
Set rsLegend = Nothing
%>
</div>
<div style="margin-top:20px; padding:15px; background:#2a2a2a; border-radius:4px; font-size:12px;">
<strong style="color:#4fc3f7;">Tips:</strong>
<ul style="margin:8px 0; padding-left:20px; color:#aaa;">
<li style="margin:5px 0;">Hover over markers for details</li>
<li style="margin:5px 0;">Use search to find specific machines</li>
<li style="margin:5px 0;">Filter by BU, type, or status</li>
<li style="margin:5px 0;">Click "View Details" for full information</li>
</ul>
</div>
</div>
</div>
</div>
</div><!--End Row-->
</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>
</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>
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
<script src="assets/js/sidebar-menu.js"></script>
<script src="assets/js/app-script.js"></script>
<style>
#map {
width: 100%;
height: calc(100vh - 250px);
min-height: 600px;
background-color: #1a1a1a;
}
.leaflet-control-zoom a {
background-color: #2a2a2a !important;
color: #fff !important;
border-color: #444 !important;
}
.leaflet-control-zoom a:hover {
background-color: #3a3a3a !important;
}
.leaflet-bar {
border: 1px solid #444 !important;
}
.leaflet-popup-content-wrapper {
background: #1f1f1f !important;
color: #fff !important;
box-shadow: 0 3px 14px rgba(0,0,0,0.6) !important;
border-radius: 4px !important;
padding: 0 !important;
}
.leaflet-popup-content {
margin: 0 !important;
}
.leaflet-popup-tip-container {
display: none !important;
}
.leaflet-popup-close-button {
color: #fff !important;
font-size: 24px !important;
padding: 4px 8px 0 0 !important;
}
.leaflet-control-attribution {
display: none !important;
}
</style>
<script>
// Get current theme
var bodyClass = document.body.className;
var themeMatch = bodyClass.match(/bg-theme(\d+)/);
var theme = themeMatch ? 'bg-theme' + themeMatch[1] : 'bg-theme1';
var themeConfig = {
'bg-theme1': { bg: '#2a2a2a', filter: 'brightness(0.7) contrast(1.1)', gradient: 'linear-gradient(45deg, #3a3a3a, #4a4a4a)' },
'bg-theme7': { bg: '#0c675e', filter: 'brightness(0.8) contrast(1.1) hue-rotate(-10deg)', gradient: 'linear-gradient(45deg, #0c675e, #069e90)' },
'bg-theme11': { bg: '#1565C0', filter: 'brightness(0.85) contrast(1.05) hue-rotate(-5deg)', gradient: 'linear-gradient(45deg, #1565C0, #1E88E5)' }
};
var config = themeConfig[theme] || { bg: '#1a1a1a', filter: 'brightness(0.7) contrast(1.1)', gradient: 'linear-gradient(45deg, #667eea, #764ba2)' };
document.getElementById('map').style.backgroundColor = config.bg;
var map = L.map('map', {
crs: L.CRS.Simple,
minZoom: -3
});
var bounds = [[0,0], [2550,3300]];
var lightThemes = ['bg-theme11', 'bg-theme13'];
var mapImage = lightThemes.includes(theme) ? './images/sitemap2025-light.png' : './images/sitemap2025-dark.png';
var image = L.imageOverlay(mapImage, bounds);
image.on('load', function() {
var imgElement = this.getElement();
if (imgElement) {
imgElement.style.filter = config.filter;
}
});
image.addTo(map);
var center = [1275, 1650];
map.setView(center, -2.3);
// Store machine data and markers
var machineMarkers = [];
// Machine type colors
var machineTypeColors = {
'1': '#4CAF50', // CNC
'2': '#2196F3', // Grinder
'3': '#FF9800', // Lathe
'4': '#F44336', // Mill
'5': '#9C27B0', // CMM
'6': '#00BCD4', // EDM
'7': '#E91E63', // Press
'8': '#607D8B', // Saw
'9': '#795548', // Welder
'10': '#FF5722', // Drill
'11': '#3F51B5', // Robot
'12': '#8BC34A', // Inspection
'13': '#CDDC39', // Assembly
'14': '#FFC107', // Other
'15': '#009688', // Wash
'default': '#FFC107'
};
<%
' Query active machines with map coordinates (equipment only, not PCs or network devices)
Dim strSQL, rs, mapleft, maptop, machineid, machinenumber, machineType, machineTypeId
Dim modelnumber, vendor, alias, serialnumber, businessunitid, businessunit, machinestatusid, machinestatus
strSQL = "SELECT m.machineid, m.machinenumber, m.alias, m.serialnumber, " &_
"m.mapleft, m.maptop, m.businessunitid, m.machinestatusid, " &_
"mt.machinetypeid, mt.machinetype, " &_
"mo.modelnumber, v.vendor, " &_
"bu.businessunit, ms.machinestatus " &_
"FROM machines m " &_
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " &_
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
"LEFT JOIN vendors v ON mo.vendorid = v.vendorid " &_
"LEFT JOIN businessunits bu ON m.businessunitid = bu.businessunitid " &_
"LEFT JOIN machinestatus ms ON m.machinestatusid = ms.machinestatusid " &_
"WHERE mo.machinetypeid < 33 " &_
"AND m.pctypeid IS NULL " &_
"AND m.isactive = 1 " &_
"AND m.mapleft IS NOT NULL " &_
"AND m.maptop IS NOT NULL " &_
"ORDER BY mt.machinetype, m.machinenumber ASC"
Set rs = objConn.Execute(strSQL)
Do While Not rs.EOF
mapleft = rs("mapleft")
maptop = rs("maptop")
maptop = 2550 - maptop
machineid = rs("machineid")
machinenumber = rs("machinenumber") & ""
If Not IsNull(rs("machinetypeid")) Then
machineTypeId = rs("machinetypeid")
Else
machineTypeId = 0
End If
If Not IsNull(rs("machinetype")) Then
machineType = rs("machinetype")
Else
machineType = "Unknown"
End If
If Not IsNull(rs("alias")) And rs("alias") <> "" Then
alias = rs("alias")
Else
alias = machinenumber
End If
If Not IsNull(rs("modelnumber")) Then
modelnumber = rs("modelnumber")
Else
modelnumber = "N/A"
End If
If Not IsNull(rs("vendor")) Then
vendor = rs("vendor")
Else
vendor = "N/A"
End If
If Not IsNull(rs("serialnumber")) And rs("serialnumber") <> "" Then
serialnumber = rs("serialnumber")
Else
serialnumber = "N/A"
End If
If Not IsNull(rs("businessunitid")) Then
businessunitid = rs("businessunitid")
Else
businessunitid = 0
End If
If Not IsNull(rs("businessunit")) Then
businessunit = rs("businessunit")
Else
businessunit = "N/A"
End If
If Not IsNull(rs("machinestatusid")) Then
machinestatusid = rs("machinestatusid")
Else
machinestatusid = 0
End If
If Not IsNull(rs("machinestatus")) Then
machinestatus = rs("machinestatus")
Else
machinestatus = "N/A"
End If
%>
(function() {
var machineId = '<%=machineid%>';
var machineName = '<%=Server.HTMLEncode(alias)%>';
var machineNumber = '<%=Server.HTMLEncode(machinenumber)%>';
var machineType = '<%=Server.HTMLEncode(machineType)%>';
var machineTypeId = '<%=machineTypeId%>';
var model = '<%=Server.HTMLEncode(modelnumber)%>';
var vendor = '<%=Server.HTMLEncode(vendor)%>';
var serialNumber = '<%=Server.HTMLEncode(serialnumber)%>';
var businessUnitId = '<%=businessunitid%>';
var businessUnit = '<%=Server.HTMLEncode(businessunit)%>';
var machineStatusId = '<%=machinestatusid%>';
var machineStatus = '<%=Server.HTMLEncode(machinestatus)%>';
// Get color for this machine type
var color = machineTypeColors[machineTypeId] || machineTypeColors['default'];
// Create custom marker icon
var icon = L.divIcon({
html: '<div style="background:' + color + '; width:20px; height:20px; border-radius:50%; border:2px solid #fff; box-shadow:0 2px 5px rgba(0,0,0,0.5);"></div>',
iconSize: [20, 20],
iconAnchor: [10, 10],
popupAnchor: [0, -5],
className: 'custom-marker'
});
var marker = L.marker([<%=maptop%>, <%=mapleft%>], {
title: machineName,
icon: icon,
machineId: machineId,
machineTypeId: machineTypeId
}).addTo(map);
// Store marker with searchable data for filtering
machineMarkers.push({
marker: marker,
machineTypeId: machineTypeId,
businessUnitId: businessUnitId,
machineStatusId: machineStatusId,
searchData: {
name: machineName.toLowerCase(),
number: machineNumber.toLowerCase(),
type: machineType.toLowerCase(),
vendor: vendor.toLowerCase(),
model: model.toLowerCase(),
serial: serialNumber.toLowerCase(),
bu: businessUnit.toLowerCase()
}
});
// Open popup on hover
var popupTimeout;
marker.on('mouseover', function() {
clearTimeout(popupTimeout);
this.openPopup();
});
marker.on('mouseout', function(e) {
var popup = this.getPopup();
var popupElement = popup.getElement();
popupTimeout = setTimeout(function() {
marker.closePopup();
}, 800);
if (popupElement) {
popupElement.addEventListener('mouseenter', function() {
clearTimeout(popupTimeout);
});
popupElement.addEventListener('mouseleave', function() {
marker.closePopup();
});
}
});
var detailUrl = './displaymachine.asp?machineid=' + machineId;
var popupContent = '<div style="background:#1f1f1f; color:#fff; min-width:250px; border-radius:4px; overflow:hidden;">' +
'<div style="background:' + config.gradient + '; padding:10px 15px; border-bottom:1px solid #444;">' +
'<h6 style="margin:0; color:#fff; font-size:14px;">' + machineName + '</h6>' +
'</div>' +
'<div style="padding:10px 15px; font-size:12px;">' +
'<div style="margin:5px 0;"><strong style="color:#aaa;">Number:</strong> <span style="color:#fff;">' + machineNumber + '</span></div>' +
'<div style="margin:5px 0;"><strong style="color:#aaa;">Type:</strong> <span style="color:' + color + '; font-weight:bold;">' + machineType + '</span></div>' +
'<div style="margin:5px 0;"><strong style="color:#aaa;">Status:</strong> <span style="color:#fff;">' + machineStatus + '</span></div>' +
(businessUnit !== 'N/A' ? '<div style="margin:5px 0;"><strong style="color:#aaa;">Business Unit:</strong> <span style="color:#fff;">' + businessUnit + '</span></div>' : '') +
(vendor !== 'N/A' ? '<div style="margin:5px 0;"><strong style="color:#aaa;">Vendor:</strong> <span style="color:#fff;">' + vendor + '</span></div>' : '') +
(model !== 'N/A' ? '<div style="margin:5px 0;"><strong style="color:#aaa;">Model:</strong> <span style="color:#fff;">' + model + '</span></div>' : '') +
(serialNumber !== 'N/A' ? '<div style="margin:5px 0;"><strong style="color:#aaa;">Serial:</strong> <span style="color:#fff;">' + serialNumber + '</span></div>' : '') +
'</div>' +
'<div style="padding:10px 15px; border-top:1px solid #444; text-align:center;">' +
'<a href="' + detailUrl + '" style="display:inline-block; background:' + config.gradient + '; color:#fff; padding:8px 18px; border-radius:4px; text-decoration:none; font-size:13px; font-weight:500; transition:all 0.2s;" target="_blank" onmouseover="this.style.opacity=\'0.9\'" onmouseout="this.style.opacity=\'1\'"><i class="zmdi zmdi-eye"></i> View Details</a>' +
'</div>' +
'</div>';
marker.bindPopup(popupContent);
})();
<%
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
objConn.Close
%>
// Combined filter functionality (type + BU + status + search)
function applyFilters() {
var selectedType = document.getElementById('machineTypeFilter').value;
var selectedBU = document.getElementById('businessUnitFilter').value;
var selectedStatus = document.getElementById('machineStatusFilter').value;
var searchTerm = document.getElementById('machineSearch').value.toLowerCase().trim();
machineMarkers.forEach(function(item) {
var typeMatch = (selectedType === 'all' || item.machineTypeId == selectedType);
var buMatch = (selectedBU === 'all' || item.businessUnitId == selectedBU);
var statusMatch = (selectedStatus === 'all' || item.machineStatusId == selectedStatus);
var searchMatch = true;
if (searchTerm !== '') {
searchMatch = item.searchData.name.indexOf(searchTerm) > -1 ||
item.searchData.number.indexOf(searchTerm) > -1 ||
item.searchData.type.indexOf(searchTerm) > -1 ||
item.searchData.vendor.indexOf(searchTerm) > -1 ||
item.searchData.model.indexOf(searchTerm) > -1 ||
item.searchData.serial.indexOf(searchTerm) > -1 ||
item.searchData.bu.indexOf(searchTerm) > -1;
}
// Show marker only if it matches all filters
if (typeMatch && buMatch && statusMatch && searchMatch) {
item.marker.setOpacity(1);
} else {
item.marker.setOpacity(0.15);
}
});
}
// Listen to filter changes
document.getElementById('machineTypeFilter').addEventListener('change', applyFilters);
document.getElementById('businessUnitFilter').addEventListener('change', applyFilters);
document.getElementById('machineStatusFilter').addEventListener('change', applyFilters);
// Listen to search input with debouncing
var searchTimeout;
document.getElementById('machineSearch').addEventListener('input', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(applyFilters, 300);
});
</script>
</body>
</html>

View File

@@ -224,6 +224,7 @@ var machineTypeColors = {
' Query active network infrastructure with map coordinates ' Query active network infrastructure with map coordinates
Dim strSQL, rs, mapleft, maptop, machineid, machinenumber, machineType, machineTypeId, modelnumber, vendor, alias, ipaddress, sourceTable Dim strSQL, rs, mapleft, maptop, machineid, machinenumber, machineType, machineTypeId, modelnumber, vendor, alias, ipaddress, sourceTable
' NOTE: machinetypeid is now sourced from models table (models.machinetypeid) not machines table
strSQL = "SELECT printers.printerid AS id, machines.machinenumber AS name, machines.alias, " &_ strSQL = "SELECT printers.printerid AS id, machines.machinenumber AS name, machines.alias, " &_
"printers.mapleft, printers.maptop, printers.ipaddress, NULL AS machinetypeid, " &_ "printers.mapleft, printers.maptop, printers.ipaddress, NULL AS machinetypeid, " &_
"'Printer' AS type, models.modelnumber, vendors.vendor, 'printers' AS source " &_ "'Printer' AS type, models.modelnumber, vendors.vendor, 'printers' AS source " &_
@@ -238,14 +239,14 @@ strSQL = "SELECT printers.printerid AS id, machines.machinenumber AS name, machi
"UNION ALL " &_ "UNION ALL " &_
"" &_ "" &_
"SELECT m.machineid AS id, m.machinenumber AS name, m.alias, " &_ "SELECT m.machineid AS id, m.machinenumber AS name, m.alias, " &_
"m.mapleft, m.maptop, c.address AS ipaddress, m.machinetypeid, " &_ "m.mapleft, m.maptop, c.address AS ipaddress, mo.machinetypeid, " &_
"mt.machinetype AS type, mo.modelnumber, v.vendor, 'machines' AS source " &_ "mt.machinetype AS type, mo.modelnumber, v.vendor, 'machines' AS source " &_
"FROM machines m " &_ "FROM machines m " &_
"INNER JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " &_
"LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " &_ "LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid " &_
"LEFT JOIN machinetypes mt ON mo.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 mt.machinetypeid IN (16, 17, 18, 19, 20) " &_ "WHERE mo.machinetypeid IN (16, 17, 18, 19, 20) " &_
"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 " &_

View File

@@ -133,7 +133,7 @@ Set rsStatus = Nothing
"LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _ "LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _
"LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _ "LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _
"LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _ "LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _
"WHERE m.isactive = 1 AND m.pctypeid IS NOT NULL " "WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Apply filters ' Apply filters
whereClause = "" whereClause = ""
@@ -162,7 +162,7 @@ Set rsStatus = Nothing
while not rs.eof while not rs.eof
%> %>
<td><a href="./displaypc.asp?pcid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><% <td><a href="./displaypc.asp?machineid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><%
Dim displayName Dim displayName
If IsNull(rs("hostname")) Or rs("hostname") = "" Then If IsNull(rs("hostname")) Or rs("hostname") = "" Then
displayName = rs("serialnumber") displayName = rs("serialnumber")

View File

@@ -133,7 +133,7 @@ Set rsStatus = Nothing
"LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _ "LEFT JOIN communications c ON c.machineid = m.machineid AND c.isprimary = 1 " & _
"LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _ "LEFT JOIN pctype ON m.pctypeid = pctype.pctypeid " & _
"LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _ "LEFT JOIN machinestatus ON m.machinestatusid = machinestatus.machinestatusid " & _
"WHERE m.isactive = 1 AND m.pctypeid IS NOT NULL " "WHERE m.isactive = 1 AND m.machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
' Apply filters ' Apply filters
whereClause = "" whereClause = ""
@@ -162,7 +162,7 @@ Set rsStatus = Nothing
while not rs.eof while not rs.eof
%> %>
<td><a href="./displaypc.asp?pcid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><% <td><a href="./displaypc.asp?machineid=<%Response.Write(rs("machineid"))%>" title="Click to Show PC Details"><%
Dim displayName Dim displayName
If IsNull(rs("hostname")) Or rs("hostname") = "" Then If IsNull(rs("hostname")) Or rs("hostname") = "" Then
displayName = rs("serialnumber") displayName = rs("serialnumber")

View File

@@ -7,7 +7,7 @@
'============================================================================= '=============================================================================
%> %>
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<% <%
' Universal save endpoint for all network devices ' Universal save endpoint for all network devices
' Saves to unified machines table with appropriate machinetypeid ' Saves to unified machines table with appropriate machinetypeid
@@ -20,18 +20,16 @@ isDelete = Trim(Request.Form("delete"))
' Validate device type ' Validate device type
If deviceType <> "idf" And deviceType <> "server" And deviceType <> "switch" And deviceType <> "camera" And deviceType <> "accesspoint" Then If deviceType <> "idf" And deviceType <> "server" And deviceType <> "switch" And deviceType <> "camera" And deviceType <> "accesspoint" Then
Response.Write("<html><body><div style='color:red;'>Error: Invalid device type</div>")
Response.Write("<a href='network_devices.asp'>Back to Network Devices</a></body></html>")
objConn.Close objConn.Close
ShowError "Invalid device type.", "network_devices.asp"
Response.End Response.End
End If End If
' Validate device ID ' Validate device ID
If deviceId = "" Then deviceId = "0" If deviceId = "" Then deviceId = "0"
If Not IsNumeric(deviceId) Then If Not IsNumeric(deviceId) Then
Response.Write("<html><body><div style='color:red;'>Error: Invalid device ID</div>")
Response.Write("<a href='network_devices.asp'>Back to Network Devices</a></body></html>")
objConn.Close objConn.Close
ShowError "Invalid device ID.", "network_devices.asp"
Response.End Response.End
End If End If
@@ -99,17 +97,15 @@ End If
' Validate name field (required for all) ' Validate name field (required for all)
If deviceName = "" Then If deviceName = "" Then
Response.Write("<html><body><div style='color:red;'>Error: " & deviceDisplayName & " name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError deviceDisplayName & " name is required.", "network_devices.asp"
Response.End Response.End
End If End If
' Validate field lengths ' Validate field lengths
If Len(deviceName) > 100 Or Len(description) > 255 Then If Len(deviceName) > 100 Or Len(description) > 255 Then
Response.Write("<html><body><div style='color:red;'>Error: Field length exceeded</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "Field length exceeded.", "network_devices.asp"
Response.End Response.End
End If End If
@@ -136,34 +132,32 @@ macaddress = Trim(Request.Form("macaddress"))
' Handle new model creation ' Handle new model creation
If modelid = "new" Then If modelid = "new" Then
Dim newmodelnumber, newvendorid, newmodelnotes, newmodeldocpath, newvendorname Dim newmodelnumber, newvendorid, newmodelnotes, newmodeldocpath, newvendorname, newmodelmachinetypeid
newmodelnumber = Trim(Request.Form("newmodelnumber")) newmodelnumber = Trim(Request.Form("newmodelnumber"))
newvendorid = Trim(Request.Form("newvendorid")) newvendorid = Trim(Request.Form("newvendorid"))
newmodelnotes = Trim(Request.Form("newmodelnotes")) newmodelnotes = Trim(Request.Form("newmodelnotes"))
newmodeldocpath = Trim(Request.Form("newmodeldocpath")) newmodeldocpath = Trim(Request.Form("newmodeldocpath"))
newvendorname = Trim(Request.Form("newvendorname")) newvendorname = Trim(Request.Form("newvendorname"))
newmodelmachinetypeid = Trim(Request.Form("newmodelmachinetypeid"))
' Validate required fields for new model ' Validate required fields for new model
If newmodelnumber = "" Then If newmodelnumber = "" Then
Response.Write("<html><body><div style='color:red;'>Error: Model number is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "Model number is required.", "network_devices.asp"
Response.End Response.End
End If End If
If newvendorid = "" Then If newvendorid = "" Then
Response.Write("<html><body><div style='color:red;'>Error: Vendor is required for new model</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "Vendor is required for new model.", "network_devices.asp"
Response.End Response.End
End If End If
' Handle new vendor creation (nested) ' Handle new vendor creation (nested)
If newvendorid = "new" Then If newvendorid = "new" Then
If newvendorname = "" Then If newvendorname = "" Then
Response.Write("<html><body><div style='color:red;'>Error: Vendor name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "Vendor name is required.", "network_devices.asp"
Response.End Response.End
End If End If
@@ -179,10 +173,11 @@ If modelid = "new" Then
On Error Resume Next On Error Resume Next
cmdNewVendor.Execute cmdNewVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<html><body><div style='color:red;'>Error creating vendor: " & Server.HTMLEncode(Err.Description) & "</div>") Dim vendorErr
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>") vendorErr = Err.Description
Set cmdNewVendor = Nothing Set cmdNewVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating vendor: " & vendorErr, "network_devices.asp"
Response.End Response.End
End If End If
@@ -198,23 +193,29 @@ If modelid = "new" Then
' Insert new model using parameterized query ' Insert new model using parameterized query
Dim sqlNewModel, cmdNewModel Dim sqlNewModel, cmdNewModel
sqlNewModel = "INSERT INTO models (modelnumber, vendorid, notes, documentationpath, isactive) VALUES (?, ?, ?, ?, 1)" sqlNewModel = "INSERT INTO models (modelnumber, vendorid, machinetypeid, notes, documentationpath, isactive) VALUES (?, ?, ?, ?, ?, 1)"
Set cmdNewModel = Server.CreateObject("ADODB.Command") Set cmdNewModel = Server.CreateObject("ADODB.Command")
cmdNewModel.ActiveConnection = objConn cmdNewModel.ActiveConnection = objConn
cmdNewModel.CommandText = sqlNewModel cmdNewModel.CommandText = sqlNewModel
cmdNewModel.CommandType = 1 cmdNewModel.CommandType = 1
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@modelnumber", 200, 1, 50, newmodelnumber) cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@modelnumber", 200, 1, 50, newmodelnumber)
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@vendorid", 3, 1, , CLng(newvendorid)) cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@vendorid", 3, 1, , CLng(newvendorid))
If newmodelmachinetypeid <> "" Then
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@machinetypeid", 3, 1, , CLng(newmodelmachinetypeid))
Else
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@machinetypeid", 3, 1, , Null)
End If
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@notes", 200, 1, 500, newmodelnotes) cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@notes", 200, 1, 500, newmodelnotes)
cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@documentationpath", 200, 1, 500, newmodeldocpath) cmdNewModel.Parameters.Append cmdNewModel.CreateParameter("@documentationpath", 200, 1, 500, newmodeldocpath)
On Error Resume Next On Error Resume Next
cmdNewModel.Execute cmdNewModel.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<html><body><div style='color:red;'>Error creating model: " & Server.HTMLEncode(Err.Description) & "</div>") Dim modelErr
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>") modelErr = Err.Description
Set cmdNewModel = Nothing Set cmdNewModel = Nothing
objConn.Close objConn.Close
ShowError "Error creating model: " & modelErr, "network_devices.asp"
Response.End Response.End
End If End If
@@ -249,9 +250,8 @@ If deviceType = "camera" Then
' Validate required fields for new IDF ' Validate required fields for new IDF
If newidfname = "" Then If newidfname = "" Then
Response.Write("<html><body><div style='color:red;'>Error: IDF name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "IDF name is required.", "network_devices.asp"
Response.End Response.End
End If End If
@@ -270,10 +270,11 @@ If deviceType = "camera" Then
On Error Resume Next On Error Resume Next
cmdNewIdf.Execute cmdNewIdf.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<html><body><div style='color:red;'>Error creating IDF: " & Server.HTMLEncode(Err.Description) & "</div>") Dim idfErr
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>") idfErr = Err.Description
Set cmdNewIdf = Nothing Set cmdNewIdf = Nothing
objConn.Close objConn.Close
ShowError "Error creating IDF: " & idfErr, "network_devices.asp"
Response.End Response.End
End If End If
@@ -289,9 +290,8 @@ If deviceType = "camera" Then
' Validate required idfid for cameras ' Validate required idfid for cameras
If idfid = "" Or Not IsNumeric(idfid) Or CLng(idfid) < 1 Then If idfid = "" Or Not IsNumeric(idfid) Or CLng(idfid) < 1 Then
Response.Write("<html><body><div style='color:red;'>Error: IDF location is required for cameras</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>")
objConn.Close objConn.Close
ShowError "IDF location is required for cameras.", "network_devices.asp"
Response.End Response.End
End If End If
@@ -345,10 +345,11 @@ If deviceId = "0" Then
On Error Resume Next On Error Resume Next
cmdDevice.Execute cmdDevice.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<html><body><div style='color:red;'>Error saving device: " & Server.HTMLEncode(Err.Description) & "</div>") Dim saveErr
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>") saveErr = Err.Description
Set cmdDevice = Nothing Set cmdDevice = Nothing
objConn.Close objConn.Close
ShowError "Error saving device: " & saveErr, "network_devices.asp"
Response.End Response.End
End If End If
Set cmdDevice = Nothing Set cmdDevice = Nothing
@@ -382,10 +383,11 @@ Else
On Error Resume Next On Error Resume Next
cmdDevice.Execute cmdDevice.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<html><body><div style='color:red;'>Error updating device: " & Server.HTMLEncode(Err.Description) & "</div>") Dim updateErr
Response.Write("<a href='javascript:history.back()'>Go back</a></body></html>") updateErr = Err.Description
Set cmdDevice = Nothing Set cmdDevice = Nothing
objConn.Close objConn.Close
ShowError "Error updating device: " & updateErr, "network_devices.asp"
Response.End Response.End
End If End If
Set cmdDevice = Nothing Set cmdDevice = Nothing
@@ -472,7 +474,7 @@ If deviceType = "camera" And idfid <> "" And Not IsNull(idfRelationshipTypeId) T
Set cmdInsertRel = Nothing Set cmdInsertRel = Nothing
End If End If
' Success - redirect to list ' Success - show success message
objConn.Close objConn.Close
Response.Redirect(redirectUrl) ShowSuccess deviceDisplayName & " saved successfully.", redirectUrl, deviceDisplayName
%> %>

View File

@@ -1,170 +0,0 @@
<%@ Language=VBScript %>
<%
Option Explicit
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/encoding.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!--#include file="./includes/db_helpers.asp"-->
<%
'=============================================================================
' FILE: saveapplication.asp
' PURPOSE: Insert a new application record
'
' PARAMETERS:
' appname (Form, Required) - Application name (1-50 chars)
' appdescription (Form, Optional) - Description (max 255 chars)
' supportteamid (Form, Required) - Support team ID
' applicationnotes (Form, Optional) - Notes (max 512 chars)
' installpath (Form, Optional) - Installation path/URL (max 255 chars)
' documentationpath (Form, Optional) - Documentation path/URL (max 512 chars)
' image (Form, Optional) - Image filename (max 255 chars)
' isinstallable, isactive, ishidden, isprinter, islicenced (Form, Optional) - Checkboxes (0/1)
'
' SECURITY:
' - Uses parameterized queries
' - Validates all inputs
' - HTML encodes outputs
'
' AUTHOR: Claude Code
' CREATED: 2025-10-12
'=============================================================================
'-----------------------------------------------------------------------------
' INITIALIZATION
'-----------------------------------------------------------------------------
Call InitializeErrorHandling("saveapplication.asp")
' Get and validate inputs
Dim appname, appdescription, supportteamid
Dim applicationnotes, installpath, documentationpath, image
Dim isinstallable, isactive, ishidden, isprinter, islicenced
appname = Trim(Request.Form("appname"))
appdescription = Trim(Request.Form("appdescription"))
supportteamid = Trim(Request.Form("supportteamid"))
applicationnotes = Trim(Request.Form("applicationnotes"))
installpath = Trim(Request.Form("installpath"))
documentationpath = Trim(Request.Form("documentationpath"))
image = Trim(Request.Form("image"))
' Checkboxes - convert to bit values
If Request.Form("isinstallable") = "1" Then
isinstallable = 1
Else
isinstallable = 0
End If
If Request.Form("isactive") = "1" Then
isactive = 1
Else
isactive = 0
End If
If Request.Form("ishidden") = "1" Then
ishidden = 1
Else
ishidden = 0
End If
If Request.Form("isprinter") = "1" Then
isprinter = 1
Else
isprinter = 0
End If
If Request.Form("islicenced") = "1" Then
islicenced = 1
Else
islicenced = 0
End If
'-----------------------------------------------------------------------------
' VALIDATE INPUTS
'-----------------------------------------------------------------------------
' Validate appname (required, 1-50 chars)
If Len(appname) < 1 Or Len(appname) > 50 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
' Validate supportteamid
If Not ValidateID(supportteamid) Then
Call HandleValidationError("addapplication.asp", "INVALID_ID")
End If
' Verify support team exists
If Not RecordExists(objConn, "supportteams", "supporteamid", supportteamid) Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
' Validate field lengths
If Len(appdescription) > 255 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
If Len(applicationnotes) > 512 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
If Len(installpath) > 255 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
If Len(documentationpath) > 512 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
If Len(image) > 255 Then
Call HandleValidationError("addapplication.asp", "INVALID_INPUT")
End If
'-----------------------------------------------------------------------------
' DATABASE INSERT
'-----------------------------------------------------------------------------
Dim strSQL
strSQL = "INSERT INTO applications (" & _
"appname, appdescription, supportteamid, applicationnotes, " & _
"installpath, documentationpath, image, " & _
"isinstallable, isactive, ishidden, isprinter, islicenced" & _
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
Dim recordsAffected
recordsAffected = ExecuteParameterizedInsert(objConn, strSQL, Array( _
appname, _
appdescription, _
supportteamid, _
applicationnotes, _
installpath, _
documentationpath, _
image, _
CInt(isinstallable), _
CInt(isactive), _
CInt(ishidden), _
CInt(isprinter), _
CInt(islicenced) _
))
Call CheckForErrors()
' Get the newly created application ID
Dim newAppId
newAppId = GetLastInsertId(objConn)
'-----------------------------------------------------------------------------
' CLEANUP AND REDIRECT
'-----------------------------------------------------------------------------
Call CleanupResources()
If recordsAffected > 0 And newAppId > 0 Then
' Redirect to the newly created application
Response.Redirect("displayapplication.asp?appid=" & Server.URLEncode(CStr(newAppId)))
Else
Response.Write("<html><body>")
Response.Write("<h3>Error: Application could not be created.</h3>")
Response.Write("<p><a href='addapplication.asp'>Go Back</a></p>")
Response.Write("</body></html>")
End If
%>

View File

@@ -6,6 +6,7 @@
' UPDATED: 2025-10-27 - Migrated to secure patterns ' UPDATED: 2025-10-27 - Migrated to secure patterns
'============================================================================= '=============================================================================
%><!--#include file="./includes/sql.asp"--> %><!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<% <%
' Get all form data ' Get all form data
Dim appname, appdescription, supportteamid Dim appname, appdescription, supportteamid
@@ -60,32 +61,29 @@ End If
' Basic validation ' Basic validation
If Len(appname) < 1 Or Len(appname) > 50 Then If Len(appname) < 1 Or Len(appname) > 50 Then
Response.Write("Error: Application name must be 1-50 characters")
objConn.Close objConn.Close
ShowError "Application name must be 1-50 characters", "addapplication.asp"
Response.End Response.End
End If End If
' Validate support team is selected ' Validate support team is selected
If supportteamid = "" Then If supportteamid = "" Then
Response.Write("<div class='alert alert-danger'>Error: Please select a support team.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Please select a support team.", "addapplication.asp"
Response.End Response.End
End If End If
' Check if we need to create a new support team first ' Check if we need to create a new support team first
If supportteamid = "new" Then If supportteamid = "new" Then
If newsupportteamname = "" Then If newsupportteamname = "" Then
Response.Write("<div class='alert alert-danger'>Error: Support team name is required.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Support team name is required.", "addapplication.asp"
Response.End Response.End
End If End If
If Len(newsupportteamname) > 50 Then If Len(newsupportteamname) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: Support team name too long.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Support team name too long.", "addapplication.asp"
Response.End Response.End
End If End If
@@ -101,18 +99,16 @@ If supportteamid = "new" Then
Set rsCheck = cmdCheck.Execute Set rsCheck = cmdCheck.Execute
If rsCheck.EOF Then If rsCheck.EOF Then
rsCheck.Close rsCheck.Close
Response.Write("<div class='alert alert-danger'>Error: Database query failed.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Database query failed.", "addapplication.asp"
Response.End Response.End
End If End If
If Not IsNull(rsCheck("cnt")) Then If Not IsNull(rsCheck("cnt")) Then
If CLng(rsCheck("cnt")) > 0 Then If CLng(rsCheck("cnt")) > 0 Then
rsCheck.Close rsCheck.Close
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Support team '" & Server.HTMLEncode(newsupportteamname) & "' already exists.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Support team '" & Server.HTMLEncode(newsupportteamname) & "' already exists.", "addapplication.asp"
Response.End Response.End
End If End If
End If End If
@@ -126,16 +122,14 @@ If supportteamid = "new" Then
newappownersso = Trim(Request.Form("newappownersso")) newappownersso = Trim(Request.Form("newappownersso"))
If newappownername = "" Or newappownersso = "" Then If newappownername = "" Or newappownersso = "" Then
Response.Write("<div class='alert alert-danger'>Error: App owner name and SSO are required.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "App owner name and SSO are required.", "addapplication.asp"
Response.End Response.End
End If End If
If Len(newappownername) > 50 Or Len(newappownersso) > 50 Then If Len(newappownername) > 50 Or Len(newappownersso) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: App owner name or SSO too long.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "App owner name or SSO too long.", "addapplication.asp"
Response.End Response.End
End If End If
@@ -151,18 +145,16 @@ If supportteamid = "new" Then
Set rsCheck = cmdCheck.Execute Set rsCheck = cmdCheck.Execute
If rsCheck.EOF Then If rsCheck.EOF Then
rsCheck.Close rsCheck.Close
Response.Write("<div class='alert alert-danger'>Error: Database query failed (app owner check).</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Database query failed (app owner check).", "addapplication.asp"
Response.End Response.End
End If End If
If Not IsNull(rsCheck("cnt")) Then If Not IsNull(rsCheck("cnt")) Then
If CLng(rsCheck("cnt")) > 0 Then If CLng(rsCheck("cnt")) > 0 Then
rsCheck.Close rsCheck.Close
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: App owner with this name or SSO already exists.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "App owner with this name or SSO already exists.", "addapplication.asp"
Response.End Response.End
End If End If
End If End If
@@ -183,10 +175,9 @@ If supportteamid = "new" Then
cmdOwner.Execute cmdOwner.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating app owner: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
Set cmdOwner = Nothing Set cmdOwner = Nothing
objConn.Close objConn.Close
ShowError "Error creating app owner: " & Server.HTMLEncode(Err.Description), "addapplication.asp"
Response.End Response.End
End If End If
Set cmdOwner = Nothing Set cmdOwner = Nothing
@@ -204,9 +195,8 @@ If supportteamid = "new" Then
Else Else
' Validate existing app owner ID ' Validate existing app owner ID
If Not IsNumeric(newappownerid) Or CLng(newappownerid) < 1 Then If Not IsNumeric(newappownerid) Or CLng(newappownerid) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid app owner.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid app owner.", "addapplication.asp"
Response.End Response.End
End If End If
End If End If
@@ -226,10 +216,9 @@ If supportteamid = "new" Then
cmdTeam.Execute cmdTeam.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating support team: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
Set cmdTeam = Nothing Set cmdTeam = Nothing
objConn.Close objConn.Close
ShowError "Error creating support team: " & Server.HTMLEncode(Err.Description), "addapplication.asp"
Response.End Response.End
End If End If
Set cmdTeam = Nothing Set cmdTeam = Nothing
@@ -247,9 +236,8 @@ If supportteamid = "new" Then
Else Else
' Validate existing support team ID ' Validate existing support team ID
If Not IsNumeric(supportteamid) Or CLng(supportteamid) < 1 Then If Not IsNumeric(supportteamid) Or CLng(supportteamid) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid support team ID.</div>")
Response.Write("<a href='addapplication.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid support team ID.", "addapplication.asp"
Response.End Response.End
End If End If
End If End If
@@ -286,9 +274,9 @@ cmdApp.Parameters.Append cmdApp.CreateParameter("@islicenced", 11, 1, , CBool(is
cmdApp.Execute cmdApp.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("Error: " & Server.HTMLEncode(Err.Description))
Set cmdApp = Nothing Set cmdApp = Nothing
objConn.Close objConn.Close
ShowError Server.HTMLEncode(Err.Description), "addapplication.asp"
Response.End Response.End
End If End If
@@ -311,8 +299,8 @@ Set rsNew = Nothing
objConn.Close objConn.Close
If newAppId > 0 Then If newAppId > 0 Then
Response.Redirect("displayapplication.asp?appid=" & newAppId) ShowSuccess "Application added successfully.", "displayapplication.asp?appid=" & newAppId, "application details"
Else Else
Response.Write("Error: Could not retrieve new application ID") ShowError "Could not retrieve new application ID.", "addapplication.asp"
End If End If
%> %>

109
savecheckin_usb.asp Normal file
View File

@@ -0,0 +1,109 @@
<%
'=============================================================================
' FILE: savecheckin_usb.asp
' PURPOSE: Process USB check-in request
' SECURITY: Parameterized queries, input validation
' CREATED: 2025-12-07
'=============================================================================
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<%
' Get form values
Dim checkoutid, waswiped, notes
checkoutid = Trim(Request.Form("checkoutid"))
waswiped = Trim(Request.Form("waswiped"))
notes = Trim(Request.Form("notes"))
' Validate checkoutid
If checkoutid = "" Or Not IsNumeric(checkoutid) Then
objConn.Close
ShowError "Invalid checkout ID.", "checkin_usb.asp"
Response.End
End If
' Validate waswiped - must be checked (value = "1")
Dim wipedValue
If waswiped = "1" Then
wipedValue = 1
Else
objConn.Close
ShowError "You must confirm the USB has been wiped before check-in.", "checkin_usb.asp"
Response.End
End If
' Verify the checkout record exists and is still open
Dim checkSQL, cmdCheck, rsCheck
checkSQL = "SELECT uc.checkoutid, uc.machineid, uc.sso, m.serialnumber, m.alias " & _
"FROM usb_checkouts uc " & _
"JOIN machines m ON uc.machineid = m.machineid " & _
"WHERE uc.checkoutid = ? AND uc.checkin_time IS NULL"
Set cmdCheck = Server.CreateObject("ADODB.Command")
cmdCheck.ActiveConnection = objConn
cmdCheck.CommandText = checkSQL
cmdCheck.CommandType = 1
cmdCheck.Parameters.Append cmdCheck.CreateParameter("@checkoutid", 3, 1, , CLng(checkoutid))
Set rsCheck = cmdCheck.Execute
If rsCheck.EOF Then
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
objConn.Close
ShowError "Checkout record not found or already checked in.", "checkin_usb.asp"
Response.End
End If
Dim serialnumber, usbAlias, sso
serialnumber = rsCheck("serialnumber") & ""
usbAlias = rsCheck("alias") & ""
sso = rsCheck("sso") & ""
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
' Update checkout record with check-in info
Dim updateSQL, cmdUpdate
updateSQL = "UPDATE usb_checkouts SET checkin_time = NOW(), was_wiped = ?, checkin_notes = ? WHERE checkoutid = ?"
Set cmdUpdate = Server.CreateObject("ADODB.Command")
cmdUpdate.ActiveConnection = objConn
cmdUpdate.CommandText = updateSQL
cmdUpdate.CommandType = 1
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@waswiped", 3, 1, , wipedValue)
If notes = "" Then
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@notes", 200, 1, 1000, Null)
Else
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@notes", 200, 1, 1000, notes)
End If
cmdUpdate.Parameters.Append cmdUpdate.CreateParameter("@checkoutid", 3, 1, , CLng(checkoutid))
On Error Resume Next
cmdUpdate.Execute
If Err.Number = 0 Then
Set cmdUpdate = Nothing
objConn.Close
' Build display name
Dim displayName
If usbAlias <> "" And usbAlias <> serialnumber Then
displayName = serialnumber & " (" & usbAlias & ")"
Else
displayName = serialnumber
End If
ShowSuccess "USB '" & Server.HTMLEncode(displayName) & "' checked in successfully. Previously held by SSO " & Server.HTMLEncode(sso) & ".", "displayusb.asp", "USB Check-in"
Else
Dim updateErr
updateErr = Err.Description
Set cmdUpdate = Nothing
objConn.Close
ShowError "Error checking in USB: " & Server.HTMLEncode(updateErr), "checkin_usb.asp"
End If
%>

126
savecheckout_usb.asp Normal file
View File

@@ -0,0 +1,126 @@
<%
'=============================================================================
' FILE: savecheckout_usb.asp
' PURPOSE: Process USB checkout request
' SECURITY: Parameterized queries, input validation
' CREATED: 2025-12-07
'=============================================================================
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<%
' Get form values
Dim machineid, sso, reason
machineid = Trim(Request.Form("machineid"))
sso = Trim(Request.Form("sso"))
reason = Trim(Request.Form("reason"))
' Validate machineid
If machineid = "" Or Not IsNumeric(machineid) Then
objConn.Close
ShowError "Invalid USB device ID.", "checkout_usb.asp"
Response.End
End If
' Validate SSO - must be 9 digits
If sso = "" Or Len(sso) <> 9 Then
objConn.Close
ShowError "SSO must be exactly 9 digits.", "checkout_usb.asp"
Response.End
End If
' Verify SSO is numeric
Dim i, c
For i = 1 To Len(sso)
c = Mid(sso, i, 1)
If c < "0" Or c > "9" Then
objConn.Close
ShowError "SSO must contain only digits.", "checkout_usb.asp"
Response.End
End If
Next
' Verify the USB device exists and is available
Dim checkSQL, cmdCheck, rsCheck
checkSQL = "SELECT m.machineid, m.serialnumber, m.alias, " & _
"(SELECT COUNT(*) FROM usb_checkouts uc WHERE uc.machineid = m.machineid AND uc.checkin_time IS NULL) AS is_checked_out " & _
"FROM machines m " & _
"WHERE m.machineid = ? AND m.machinetypeid = 44 AND m.isactive = 1"
Set cmdCheck = Server.CreateObject("ADODB.Command")
cmdCheck.ActiveConnection = objConn
cmdCheck.CommandText = checkSQL
cmdCheck.CommandType = 1
cmdCheck.Parameters.Append cmdCheck.CreateParameter("@machineid", 3, 1, , CLng(machineid))
Set rsCheck = cmdCheck.Execute
If rsCheck.EOF Then
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
objConn.Close
ShowError "USB device not found.", "checkout_usb.asp"
Response.End
End If
Dim serialnumber, usbAlias, isCheckedOut
serialnumber = rsCheck("serialnumber") & ""
usbAlias = rsCheck("alias") & ""
If IsNull(rsCheck("is_checked_out")) Or rsCheck("is_checked_out") = "" Then
isCheckedOut = 0
Else
isCheckedOut = CLng(rsCheck("is_checked_out"))
End If
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
If isCheckedOut > 0 Then
objConn.Close
ShowError "USB device '" & Server.HTMLEncode(serialnumber) & "' is already checked out.", "checkout_usb.asp"
Response.End
End If
' Insert checkout record
Dim insertSQL, cmdInsert
insertSQL = "INSERT INTO usb_checkouts (machineid, sso, checkout_reason, checkout_time) VALUES (?, ?, ?, NOW())"
Set cmdInsert = Server.CreateObject("ADODB.Command")
cmdInsert.ActiveConnection = objConn
cmdInsert.CommandText = insertSQL
cmdInsert.CommandType = 1
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@sso", 200, 1, 20, sso)
If reason = "" Then
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@reason", 200, 1, 1000, Null)
Else
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@reason", 200, 1, 1000, reason)
End If
On Error Resume Next
cmdInsert.Execute
If Err.Number = 0 Then
Set cmdInsert = Nothing
objConn.Close
' Build display name
Dim displayName
If usbAlias <> "" And usbAlias <> serialnumber Then
displayName = serialnumber & " (" & usbAlias & ")"
Else
displayName = serialnumber
End If
ShowSuccess "USB '" & Server.HTMLEncode(displayName) & "' checked out to SSO " & Server.HTMLEncode(sso) & ".", "displayusb.asp", "USB Checkout"
Else
Dim insertErr
insertErr = Err.Description
Set cmdInsert = Nothing
objConn.Close
ShowError "Error checking out USB: " & Server.HTMLEncode(insertErr), "checkout_usb.asp"
End If
%>

View File

@@ -20,7 +20,7 @@
' Check if serial number already exists - PHASE 2: Use machines table ' Check if serial number already exists - PHASE 2: Use machines table
Dim checkSQL, rsCheck, existingMachineID Dim checkSQL, rsCheck, existingMachineID
checkSQL = "SELECT machineid FROM machines WHERE serialnumber = ? AND pctypeid IS NOT NULL" checkSQL = "SELECT machineid FROM machines WHERE serialnumber = ? AND machinetypeid IN (33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43)"
Set rsCheck = ExecuteParameterizedQuery(objConn, checkSQL, Array(serialnumber)) Set rsCheck = ExecuteParameterizedQuery(objConn, checkSQL, Array(serialnumber))
If Not rsCheck.EOF Then If Not rsCheck.EOF Then

View File

@@ -1,12 +1,13 @@
<% <%
'============================================================================= '=============================================================================
' FILE: savedevice_direct.asp ' FILE: savedevice_direct.asp
' PURPOSE: Create new PC/device with minimal required fields ' PURPOSE: Create new PC with minimal required fields (PC-only scanner)
' SECURITY: Parameterized queries, HTML encoding, input validation ' SECURITY: Parameterized queries, HTML encoding, input validation
' UPDATED: 2025-10-27 - Migrated to secure patterns ' UPDATED: 2025-12-04 - Changed to PC-only (machinetypeid 36 = PC - Standard)
'============================================================================= '=============================================================================
%> %>
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<% <%
' Get the serial number from the form ' Get the serial number from the form
Dim serialnumber Dim serialnumber
@@ -15,13 +16,14 @@
' Basic validation - serial number should not be empty and should be alphanumeric-ish ' Basic validation - serial number should not be empty and should be alphanumeric-ish
If serialnumber = "" Or Len(serialnumber) < 3 Or Len(serialnumber) > 100 Then If serialnumber = "" Or Len(serialnumber) < 3 Or Len(serialnumber) > 100 Then
objConn.Close objConn.Close
Response.Redirect("./adddevice.asp?error=INVALID_SERIAL") ShowError "Invalid serial number. Must be 3-100 characters.", "adddevice.asp"
Response.End Response.End
End If End If
' Check if serial number already exists - PHASE 2: Use machines table ' Check if serial number already exists - PHASE 2: Use machines table
Dim checkSQL, rsCheck, cmdCheck, existingMachineID ' Check ALL machines regardless of type to prevent duplicates
checkSQL = "SELECT machineid FROM machines WHERE serialnumber = ? AND pctypeid IS NOT NULL" Dim checkSQL, rsCheck, cmdCheck, existingMachineID, existingPCTypeID
checkSQL = "SELECT machineid, pctypeid FROM machines WHERE serialnumber = ? AND isactive = 1"
Set cmdCheck = Server.CreateObject("ADODB.Command") Set cmdCheck = Server.CreateObject("ADODB.Command")
cmdCheck.ActiveConnection = objConn cmdCheck.ActiveConnection = objConn
cmdCheck.CommandText = checkSQL cmdCheck.CommandText = checkSQL
@@ -31,13 +33,20 @@
Set rsCheck = cmdCheck.Execute Set rsCheck = cmdCheck.Execute
If Not rsCheck.EOF Then If Not rsCheck.EOF Then
' Serial number already exists - redirect to edit page ' Serial number already exists - redirect to appropriate edit page
existingMachineID = rsCheck("machineid") existingMachineID = rsCheck("machineid")
existingPCTypeID = rsCheck("pctypeid")
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
objConn.Close objConn.Close
Response.Redirect("./editdevice.asp?pcid=" & existingMachineID & "&scanned=1")
' Redirect to PC edit page if it's a PC (pctypeid IS NOT NULL), otherwise to machine edit page
If Not IsNull(existingPCTypeID) Then
Response.Redirect("./editpc.asp?machineid=" & existingMachineID & "&scanned=1")
Else
Response.Redirect("./editmachine.asp?machineid=" & existingMachineID & "&scanned=1")
End If
Response.End Response.End
End If End If
@@ -45,23 +54,22 @@
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
' Insert new device with minimal required fields - PHASE 2: Use machines table ' Insert new PC with minimal required fields - PHASE 2: Use machines table
' machinetypeid = 36 (PC - Standard)
' machinestatusid = 2 (Inventory) ' machinestatusid = 2 (Inventory)
' isactive = 1
' modelnumberid = 1 (default model) ' modelnumberid = 1 (default model)
' requires_manual_machine_config = 0 (no manual config needed) ' maptop = 1519, mapleft = 1896 (default map location)
' osid = 1 (default OS) ' hostname = serialnumber (default)
' machinetypeid = 33 (Standard PC) ' isactive = 1
' pctypeid = 1 (Standard PC type)
' machinenumber = 'IT Closet' (default location for new devices)
Dim insertSQL, cmdInsert Dim insertSQL, cmdInsert
insertSQL = "INSERT INTO machines (serialnumber, machinestatusid, isactive, modelnumberid, requires_manual_machine_config, osid, machinetypeid, pctypeid, machinenumber, lastupdated) " & _ insertSQL = "INSERT INTO machines (serialnumber, hostname, machinetypeid, machinestatusid, modelnumberid, maptop, mapleft, isactive, lastupdated) " & _
"VALUES (?, 2, 1, 1, 0, 1, 33, 1, 'IT Closet', NOW())" "VALUES (?, ?, 36, 2, 1, 1519, 1896, 1, NOW())"
Set cmdInsert = Server.CreateObject("ADODB.Command") Set cmdInsert = Server.CreateObject("ADODB.Command")
cmdInsert.ActiveConnection = objConn cmdInsert.ActiveConnection = objConn
cmdInsert.CommandText = insertSQL cmdInsert.CommandText = insertSQL
cmdInsert.CommandType = 1 cmdInsert.CommandType = 1
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@serialnumber", 200, 1, 100, serialnumber) cmdInsert.Parameters.Append cmdInsert.CreateParameter("@serialnumber", 200, 1, 100, serialnumber)
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@hostname", 200, 1, 255, serialnumber)
On Error Resume Next On Error Resume Next
cmdInsert.Execute cmdInsert.Execute
@@ -69,11 +77,13 @@
If Err.Number = 0 Then If Err.Number = 0 Then
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
' Success - redirect back with success message ' Success - show success message
Response.Redirect("./adddevice.asp?added=" & Server.URLEncode(Request.Form("serialnumber"))) ShowSuccess "PC with serial '" & Server.HTMLEncode(serialnumber) & "' added successfully.", "adddevice.asp", "scanner"
Else Else
Dim insertErr
insertErr = Err.Description
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
Response.Redirect("./adddevice.asp?error=db") ShowError "Error adding PC: " & Server.HTMLEncode(insertErr), "adddevice.asp"
End If End If
%> %>

View File

@@ -8,14 +8,8 @@
' NOTE: Machines now inherit machinetypeid from their model. Each model has one machine type. ' NOTE: Machines now inherit machinetypeid from their model. Each model has one machine type.
'============================================================================= '=============================================================================
%> %>
<html>
<head>
<link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
</head> <!--#include file="./includes/response.asp"-->
<body>
<div class="page">
<% <%
' Get and validate all inputs ' Get and validate all inputs
Dim machinenumber, modelid, businessunitid, alias, machinenotes, mapleft, maptop Dim machinenumber, modelid, businessunitid, alias, machinenotes, mapleft, maptop
@@ -55,31 +49,27 @@
' Validate required fields ' Validate required fields
If machinenumber = "" Then If machinenumber = "" Then
Response.Write("<div class='alert alert-danger'>Error: Machine number is required.</div>") ShowError "Machine number is required.", "addmachine.asp"
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
Response.End Response.End
End If End If
' Validate ID fields - allow "new" as a valid value ' Validate ID fields - allow "new" as a valid value
If modelid <> "new" And Not IsNumeric(modelid) Then If modelid <> "new" And Not IsNumeric(modelid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid model ID.</div>") ShowError "Invalid model ID.", "addmachine.asp"
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
Response.End Response.End
End If End If
If businessunitid <> "new" And Not IsNumeric(businessunitid) Then If businessunitid <> "new" And Not IsNumeric(businessunitid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid business unit ID.</div>") ShowError "Invalid business unit ID.", "addmachine.asp"
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
Response.End Response.End
End If End If
' Validate field lengths ' Validate field lengths
If Len(machinenumber) > 50 Or Len(alias) > 50 Then If Len(machinenumber) > 50 Or Len(alias) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: Field length exceeded.</div>") ShowError "Field length exceeded.", "addmachine.asp"
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
Response.End Response.End
End If End If
@@ -98,9 +88,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Machine number '" & Server.HTMLEncode(machinenumber) & "' already exists.</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine number '" & machinenumber & "' already exists.", "addmachine.asp"
Response.End Response.End
End If End If
End If End If
@@ -111,16 +100,14 @@
' Handle new business unit creation ' Handle new business unit creation
If businessunitid = "new" Then If businessunitid = "new" Then
If Len(newbusinessunit) = 0 Then If Len(newbusinessunit) = 0 Then
Response.Write("<div class='alert alert-danger'>New business unit name is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New business unit name is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newbusinessunit) > 50 Then If Len(newbusinessunit) > 50 Then
Response.Write("<div class='alert alert-danger'>Business unit name too long</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Business unit name too long", "addmachine.asp"
Response.End Response.End
End If End If
@@ -137,10 +124,9 @@
cmdNewBU.Execute cmdNewBU.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new business unit: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewBU = Nothing Set cmdNewBU = Nothing
objConn.Close objConn.Close
ShowError "Error creating new business unit: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -157,55 +143,48 @@
' Handle new model creation ' Handle new model creation
If modelid = "new" Then If modelid = "new" Then
If Len(newmodelnumber) = 0 Then If Len(newmodelnumber) = 0 Then
Response.Write("<div class='alert alert-danger'>New model number is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New model number is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newvendorid) = 0 Then If Len(newvendorid) = 0 Then
Response.Write("<div class='alert alert-danger'>Vendor is required for new model</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor is required for new model", "addmachine.asp"
Response.End Response.End
End If End If
' Handle new machine type creation (nested in new model) ' Handle new machine type creation (nested in new model)
If newmodelmachinetypeid = "new" Then If newmodelmachinetypeid = "new" Then
If Len(newmachinetype) = 0 Then If Len(newmachinetype) = 0 Then
Response.Write("<div class='alert alert-danger'>New machine type name is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New machine type name is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newfunctionalaccountid) = 0 Then If Len(newfunctionalaccountid) = 0 Then
Response.Write("<div class='alert alert-danger'>Functional account is required for new machine type</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Functional account is required for new machine type", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newmachinetype) > 50 Or Len(newmachinedescription) > 255 Then If Len(newmachinetype) > 50 Or Len(newmachinedescription) > 255 Then
Response.Write("<div class='alert alert-danger'>Machine type field length exceeded</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine type field length exceeded", "addmachine.asp"
Response.End Response.End
End If End If
' Handle new functional account creation (nested in new machine type) ' Handle new functional account creation (nested in new machine type)
If newfunctionalaccountid = "new" Then If newfunctionalaccountid = "new" Then
If Len(newfunctionalaccount) = 0 Then If Len(newfunctionalaccount) = 0 Then
Response.Write("<div class='alert alert-danger'>New functional account name is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New functional account name is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newfunctionalaccount) > 50 Or Len(newfunctionalaccountdescription) > 255 Then If Len(newfunctionalaccount) > 50 Or Len(newfunctionalaccountdescription) > 255 Then
Response.Write("<div class='alert alert-danger'>Functional account field length exceeded</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Functional account field length exceeded", "addmachine.asp"
Response.End Response.End
End If End If
@@ -229,10 +208,9 @@
cmdNewFA.Execute cmdNewFA.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new functional account: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewFA = Nothing Set cmdNewFA = Nothing
objConn.Close objConn.Close
ShowError "Error creating new functional account: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -268,10 +246,9 @@
cmdNewMT.Execute cmdNewMT.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new machine type: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewMT = Nothing Set cmdNewMT = Nothing
objConn.Close objConn.Close
ShowError "Error creating new machine type: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -285,33 +262,29 @@
On Error Goto 0 On Error Goto 0
End If End If
If Len(newmodelmachinetypeid) = 0 Or Not IsNumeric(newmodelmachinetypeid) Then If Len(newmodelmachinetypeid) = 0 Or (newmodelmachinetypeid <> "new" And Not IsNumeric(newmodelmachinetypeid)) Then
Response.Write("<div class='alert alert-danger'>Machine type is required for new model</div>") ShowError "Machine type is required for new model. Please select a machine type from the dropdown.", "addmachine.asp"
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
Response.End Response.End
End If End If
If Len(newmodelnumber) > 50 Or Len(newmodelimage) > 100 Then If Len(newmodelnumber) > 50 Or Len(newmodelimage) > 100 Then
Response.Write("<div class='alert alert-danger'>Model field length exceeded</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model field length exceeded", "addmachine.asp"
Response.End Response.End
End If End If
' Handle new vendor creation (nested) ' Handle new vendor creation (nested)
If newvendorid = "new" Then If newvendorid = "new" Then
If Len(newvendorname) = 0 Then If Len(newvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New vendor name is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New vendor name is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newvendorname) > 50 Then If Len(newvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Vendor name too long</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor name too long", "addmachine.asp"
Response.End Response.End
End If End If
@@ -328,10 +301,9 @@
cmdNewVendor.Execute cmdNewVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new vendor: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewVendor = Nothing Set cmdNewVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating new vendor: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -369,10 +341,9 @@
cmdNewModel.Execute cmdNewModel.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new model: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewModel = Nothing Set cmdNewModel = Nothing
objConn.Close objConn.Close
ShowError "Error creating new model: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -386,11 +357,23 @@
On Error Goto 0 On Error Goto 0
End If End If
' Get the machinetypeid from the selected model
Dim modelMachineTypeId, rsModelType
modelMachineTypeId = 1 ' Default fallback
Set rsModelType = objConn.Execute("SELECT machinetypeid FROM models WHERE modelnumberid = " & CLng(modelid))
If Not rsModelType.EOF Then
If Not IsNull(rsModelType("machinetypeid")) Then
modelMachineTypeId = CLng(rsModelType("machinetypeid"))
End If
End If
rsModelType.Close
Set rsModelType = Nothing
' Build INSERT statement with parameterized query ' Build INSERT statement with parameterized query
' NOTE: machinetypeid is now inherited from models table and doesn't need to be specified ' NOTE: machinetypeid is inherited from the model's machinetypeid
Dim strSQL, cmdMachine Dim strSQL, cmdMachine
strSQL = "INSERT INTO machines (machinenumber, modelnumberid, businessunitid, alias, machinenotes, mapleft, maptop, isactive, islocationonly) " & _ strSQL = "INSERT INTO machines (machinenumber, modelnumberid, machinetypeid, businessunitid, alias, machinenotes, mapleft, maptop, isactive, islocationonly) " & _
"VALUES (?, ?, ?, ?, ?, ?, ?, 1, 0)" "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, 0)"
Set cmdMachine = Server.CreateObject("ADODB.Command") Set cmdMachine = Server.CreateObject("ADODB.Command")
cmdMachine.ActiveConnection = objConn cmdMachine.ActiveConnection = objConn
@@ -398,6 +381,7 @@
cmdMachine.CommandType = 1 cmdMachine.CommandType = 1
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinenumber", 200, 1, 50, machinenumber) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinenumber", 200, 1, 50, machinenumber)
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@modelnumberid", 3, 1, , CLng(modelid)) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@modelnumberid", 3, 1, , CLng(modelid))
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinetypeid", 3, 1, , modelMachineTypeId)
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@businessunitid", 3, 1, , CLng(businessunitid)) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@businessunitid", 3, 1, , CLng(businessunitid))
' Handle optional alias ' Handle optional alias
@@ -427,10 +411,9 @@
cmdMachine.Execute cmdMachine.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdMachine = Nothing Set cmdMachine = Nothing
objConn.Close objConn.Close
ShowError Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
Set cmdMachine = Nothing Set cmdMachine = Nothing
@@ -636,16 +619,14 @@
newthirdpartyvendorname = Trim(Request.Form("newthirdpartyvendorname")) newthirdpartyvendorname = Trim(Request.Form("newthirdpartyvendorname"))
If Len(newthirdpartyvendorname) = 0 Then If Len(newthirdpartyvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New third party vendor name is required</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New third party vendor name is required", "addmachine.asp"
Response.End Response.End
End If End If
If Len(newthirdpartyvendorname) > 50 Then If Len(newthirdpartyvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Third party vendor name too long</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Third party vendor name too long", "addmachine.asp"
Response.End Response.End
End If End If
@@ -662,10 +643,9 @@
cmdNewTPVendor.Execute cmdNewTPVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new third party vendor: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmachine.asp'>Go back</a>")
Set cmdNewTPVendor = Nothing Set cmdNewTPVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating new third party vendor: " & Err.Description, "addmachine.asp"
Response.End Response.End
End If End If
@@ -714,13 +694,8 @@
objConn.Close objConn.Close
If CLng(newMachineId) > 0 Then If CLng(newMachineId) > 0 Then
%> ShowSuccess "Machine created successfully.", "displaymachine.asp?machineid=" & newMachineId, "machine details"
<meta http-equiv="refresh" content="0; url=./displaymachine.asp?machineid=<%=Server.HTMLEncode(newMachineId)%>">
<%
Else Else
Response.Write("Error: Machine was not added successfully.") ShowError "Machine was not added successfully.", "addmachine.asp"
End If End If
%> %>
</div>
</body>
</html>

View File

@@ -7,14 +7,8 @@
' NOTE: Machines now inherit machinetypeid from their model. Each model has one machine type. ' NOTE: Machines now inherit machinetypeid from their model. Each model has one machine type.
'============================================================================= '=============================================================================
%> %>
<html>
<head>
<link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
</head> <!--#include file="./includes/response.asp"-->
<body>
<div class="page">
<% <%
' Get and validate all inputs ' Get and validate all inputs
Dim machineid, modelid, businessunitid, alias, machinenotes, mapleft, maptop, fqdn Dim machineid, modelid, businessunitid, alias, machinenotes, mapleft, maptop, fqdn
@@ -55,9 +49,8 @@
' Validate required field - machineid ' Validate required field - machineid
If machineid = "" Or Not IsNumeric(machineid) Then If machineid = "" Or Not IsNumeric(machineid) Then
Response.Write("<div class='alert alert-danger'>Error: Machine ID is required and must be numeric.</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine ID is required and must be numeric.", "displaypcs.asp"
Response.End Response.End
End If End If
@@ -75,9 +68,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Machine ID " & Server.HTMLEncode(machineid) & " does not exist.</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine ID " & machineid & " does not exist.", "displaypcs.asp"
Response.End Response.End
End If End If
End If End If
@@ -87,40 +79,35 @@
' Validate ID fields - allow "new" as a valid value ' Validate ID fields - allow "new" as a valid value
If modelid <> "new" And Not IsNumeric(modelid) Then If modelid <> "new" And Not IsNumeric(modelid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid model ID.</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid model ID.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If businessunitid <> "new" And Not IsNumeric(businessunitid) Then If businessunitid <> "new" And Not IsNumeric(businessunitid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid business unit ID.</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid business unit ID.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
' Validate field lengths ' Validate field lengths
If Len(alias) > 50 Then If Len(alias) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: Field length exceeded.</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Field length exceeded.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
' Handle new business unit creation ' Handle new business unit creation
If businessunitid = "new" Then If businessunitid = "new" Then
If Len(newbusinessunit) = 0 Then If Len(newbusinessunit) = 0 Then
Response.Write("<div class='alert alert-danger'>New business unit name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New business unit name is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newbusinessunit) > 50 Then If Len(newbusinessunit) > 50 Then
Response.Write("<div class='alert alert-danger'>Business unit name too long</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Business unit name too long.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -137,10 +124,11 @@
cmdNewBU.Execute cmdNewBU.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new business unit: " & Server.HTMLEncode(Err.Description) & "</div>") Dim buErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") buErrMsg = Err.Description
Set cmdNewBU = Nothing Set cmdNewBU = Nothing
objConn.Close objConn.Close
ShowError "Error creating new business unit: " & buErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -157,55 +145,48 @@
' Handle new model creation ' Handle new model creation
If modelid = "new" Then If modelid = "new" Then
If Len(newmodelnumber) = 0 Then If Len(newmodelnumber) = 0 Then
Response.Write("<div class='alert alert-danger'>New model number is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New model number is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newvendorid) = 0 Then If Len(newvendorid) = 0 Then
Response.Write("<div class='alert alert-danger'>Vendor is required for new model</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor is required for new model.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
' Handle new machine type creation (nested in new model) ' Handle new machine type creation (nested in new model)
If newmodelmachinetypeid = "new" Then If newmodelmachinetypeid = "new" Then
If Len(newmachinetype) = 0 Then If Len(newmachinetype) = 0 Then
Response.Write("<div class='alert alert-danger'>New machine type name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New machine type name is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newfunctionalaccountid) = 0 Then If Len(newfunctionalaccountid) = 0 Then
Response.Write("<div class='alert alert-danger'>Functional account is required for new machine type</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Functional account is required for new machine type.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newmachinetype) > 50 Or Len(newmachinedescription) > 255 Then If Len(newmachinetype) > 50 Or Len(newmachinedescription) > 255 Then
Response.Write("<div class='alert alert-danger'>Machine type field length exceeded</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine type field length exceeded.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
' Handle new functional account creation (nested in new machine type) ' Handle new functional account creation (nested in new machine type)
If newfunctionalaccountid = "new" Then If newfunctionalaccountid = "new" Then
If Len(newfunctionalaccount) = 0 Then If Len(newfunctionalaccount) = 0 Then
Response.Write("<div class='alert alert-danger'>New functional account name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New functional account name is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newfunctionalaccount) > 50 Or Len(newfunctionalaccountdescription) > 255 Then If Len(newfunctionalaccount) > 50 Or Len(newfunctionalaccountdescription) > 255 Then
Response.Write("<div class='alert alert-danger'>Functional account field length exceeded</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Functional account field length exceeded.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -229,10 +210,11 @@
cmdNewFA.Execute cmdNewFA.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new functional account: " & Server.HTMLEncode(Err.Description) & "</div>") Dim faErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") faErrMsg = Err.Description
Set cmdNewFA = Nothing Set cmdNewFA = Nothing
objConn.Close objConn.Close
ShowError "Error creating new functional account: " & faErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -268,10 +250,11 @@
cmdNewMT.Execute cmdNewMT.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new machine type: " & Server.HTMLEncode(Err.Description) & "</div>") Dim mtErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") mtErrMsg = Err.Description
Set cmdNewMT = Nothing Set cmdNewMT = Nothing
objConn.Close objConn.Close
ShowError "Error creating new machine type: " & mtErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -286,32 +269,28 @@
End If End If
If Len(newmodelmachinetypeid) = 0 Or Not IsNumeric(newmodelmachinetypeid) Then If Len(newmodelmachinetypeid) = 0 Or Not IsNumeric(newmodelmachinetypeid) Then
Response.Write("<div class='alert alert-danger'>Machine type is required for new model</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Machine type is required for new model.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newmodelnumber) > 50 Or Len(newmodelimage) > 100 Then If Len(newmodelnumber) > 50 Or Len(newmodelimage) > 100 Then
Response.Write("<div class='alert alert-danger'>Model field length exceeded</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model field length exceeded.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
' Handle new vendor creation (nested) ' Handle new vendor creation (nested)
If newvendorid = "new" Then If newvendorid = "new" Then
If Len(newvendorname) = 0 Then If Len(newvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New vendor name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New vendor name is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newvendorname) > 50 Then If Len(newvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Vendor name too long</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor name too long.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -328,10 +307,11 @@
cmdNewVendor.Execute cmdNewVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new vendor: " & Server.HTMLEncode(Err.Description) & "</div>") Dim vendorErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") vendorErrMsg = Err.Description
Set cmdNewVendor = Nothing Set cmdNewVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating new vendor: " & vendorErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -369,10 +349,11 @@
cmdNewModel.Execute cmdNewModel.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new model: " & Server.HTMLEncode(Err.Description) & "</div>") Dim modelErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") modelErrMsg = Err.Description
Set cmdNewModel = Nothing Set cmdNewModel = Nothing
objConn.Close objConn.Close
ShowError "Error creating new model: " & modelErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -389,14 +370,16 @@
'============================================================================= '=============================================================================
' UPDATE MACHINES TABLE ' UPDATE MACHINES TABLE
'============================================================================= '=============================================================================
Dim strSQL, cmdMachine, serialnumberVal, hostnameVal, aliasVal, machinenotesVal, fqdnVal Dim strSQL, cmdMachine, serialnumberVal, hostnameVal, aliasVal, machinenotesVal, fqdnVal, machinestatusidVal
If Trim(Request.Form("serialnumber") & "") <> "" Then serialnumberVal = Trim(Request.Form("serialnumber") & "") Else serialnumberVal = Null If Trim(Request.Form("serialnumber") & "") <> "" Then serialnumberVal = Trim(Request.Form("serialnumber") & "") Else serialnumberVal = Null
If Trim(Request.Form("hostname") & "") <> "" Then hostnameVal = Trim(Request.Form("hostname") & "") Else hostnameVal = Null If Trim(Request.Form("hostname") & "") <> "" Then hostnameVal = Trim(Request.Form("hostname") & "") Else hostnameVal = Null
If alias <> "" Then aliasVal = alias Else aliasVal = Null If alias <> "" Then aliasVal = alias Else aliasVal = Null
If machinenotes <> "" Then machinenotesVal = machinenotes Else machinenotesVal = Null If machinenotes <> "" Then machinenotesVal = machinenotes Else machinenotesVal = Null
If fqdn <> "" Then fqdnVal = fqdn Else fqdnVal = Null If fqdn <> "" Then fqdnVal = fqdn Else fqdnVal = Null
machinestatusidVal = Trim(Request.Form("machinestatusid"))
If machinestatusidVal = "" Or Not IsNumeric(machinestatusidVal) Then machinestatusidVal = 1
strSQL = "UPDATE machines SET serialnumber = ?, hostname = ?, fqdn = ?, modelnumberid = ?, businessunitid = ?, alias = ?, machinenotes = ?, mapleft = ?, maptop = ? WHERE machineid = ?" strSQL = "UPDATE machines SET serialnumber = ?, hostname = ?, fqdn = ?, modelnumberid = ?, businessunitid = ?, alias = ?, machinenotes = ?, machinestatusid = ?, mapleft = ?, maptop = ? WHERE machineid = ?"
Set cmdMachine = Server.CreateObject("ADODB.Command") Set cmdMachine = Server.CreateObject("ADODB.Command")
cmdMachine.ActiveConnection = objConn cmdMachine.ActiveConnection = objConn
@@ -409,6 +392,7 @@
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@businessunitid", 3, 1, , CLng(businessunitid)) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@businessunitid", 3, 1, , CLng(businessunitid))
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@alias", 200, 1, 50, aliasVal) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@alias", 200, 1, 50, aliasVal)
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinenotes", 200, 1, 500, machinenotesVal) cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinenotes", 200, 1, 500, machinenotesVal)
cmdMachine.Parameters.Append cmdMachine.CreateParameter("@machinestatusid", 3, 1, , CLng(machinestatusidVal))
' Handle optional map coordinates ' Handle optional map coordinates
If mapleft <> "" And maptop <> "" And IsNumeric(mapleft) And IsNumeric(maptop) Then If mapleft <> "" And maptop <> "" And IsNumeric(mapleft) And IsNumeric(maptop) Then
@@ -425,10 +409,11 @@
cmdMachine.Execute cmdMachine.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error updating machine: " & Server.HTMLEncode(Err.Description) & "</div>") Dim machineErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") machineErrMsg = Err.Description
Set cmdMachine = Nothing Set cmdMachine = Nothing
objConn.Close objConn.Close
ShowError "Error updating machine: " & machineErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
Set cmdMachine = Nothing Set cmdMachine = Nothing
@@ -470,15 +455,18 @@
' Interface 1 (Primary) ' Interface 1 (Primary)
If ip1 <> "" Or mac1 <> "" Then If ip1 <> "" Or mac1 <> "" Then
Dim cmdComm1 Dim cmdComm1, ip1Val, mac1Val
If ip1 <> "" Then ip1Val = ip1 Else ip1Val = Null
If mac1 <> "" Then mac1Val = mac1 Else mac1Val = Null
Set cmdComm1 = Server.CreateObject("ADODB.Command") Set cmdComm1 = Server.CreateObject("ADODB.Command")
cmdComm1.ActiveConnection = objConn cmdComm1.ActiveConnection = objConn
cmdComm1.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 1, 1)" cmdComm1.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 1, 1)"
cmdComm1.CommandType = 1 cmdComm1.CommandType = 1
cmdComm1.Parameters.Append cmdComm1.CreateParameter("@machineid", 3, 1, , CLng(machineid)) cmdComm1.Parameters.Append cmdComm1.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdComm1.Parameters.Append cmdComm1.CreateParameter("@comstypeid", 3, 1, , comstypeid) cmdComm1.Parameters.Append cmdComm1.CreateParameter("@comstypeid", 3, 1, , comstypeid)
cmdComm1.Parameters.Append cmdComm1.CreateParameter("@address", 200, 1, 50, IIf(ip1 <> "", ip1, Null)) cmdComm1.Parameters.Append cmdComm1.CreateParameter("@address", 200, 1, 50, ip1Val)
cmdComm1.Parameters.Append cmdComm1.CreateParameter("@macaddress", 200, 1, 50, IIf(mac1 <> "", mac1, Null)) cmdComm1.Parameters.Append cmdComm1.CreateParameter("@macaddress", 200, 1, 50, mac1Val)
cmdComm1.Parameters.Append cmdComm1.CreateParameter("@interfacename", 200, 1, 50, "Interface 1") cmdComm1.Parameters.Append cmdComm1.CreateParameter("@interfacename", 200, 1, 50, "Interface 1")
On Error Resume Next On Error Resume Next
@@ -489,15 +477,18 @@
' Interface 2 (Optional) ' Interface 2 (Optional)
If ip2 <> "" Or mac2 <> "" Then If ip2 <> "" Or mac2 <> "" Then
Dim cmdComm2 Dim cmdComm2, ip2Val, mac2Val
If ip2 <> "" Then ip2Val = ip2 Else ip2Val = Null
If mac2 <> "" Then mac2Val = mac2 Else mac2Val = Null
Set cmdComm2 = Server.CreateObject("ADODB.Command") Set cmdComm2 = Server.CreateObject("ADODB.Command")
cmdComm2.ActiveConnection = objConn cmdComm2.ActiveConnection = objConn
cmdComm2.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 0, 1)" cmdComm2.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 0, 1)"
cmdComm2.CommandType = 1 cmdComm2.CommandType = 1
cmdComm2.Parameters.Append cmdComm2.CreateParameter("@machineid", 3, 1, , CLng(machineid)) cmdComm2.Parameters.Append cmdComm2.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdComm2.Parameters.Append cmdComm2.CreateParameter("@comstypeid", 3, 1, , comstypeid) cmdComm2.Parameters.Append cmdComm2.CreateParameter("@comstypeid", 3, 1, , comstypeid)
cmdComm2.Parameters.Append cmdComm2.CreateParameter("@address", 200, 1, 50, IIf(ip2 <> "", ip2, Null)) cmdComm2.Parameters.Append cmdComm2.CreateParameter("@address", 200, 1, 50, ip2Val)
cmdComm2.Parameters.Append cmdComm2.CreateParameter("@macaddress", 200, 1, 50, IIf(mac2 <> "", mac2, Null)) cmdComm2.Parameters.Append cmdComm2.CreateParameter("@macaddress", 200, 1, 50, mac2Val)
cmdComm2.Parameters.Append cmdComm2.CreateParameter("@interfacename", 200, 1, 50, "Interface 2") cmdComm2.Parameters.Append cmdComm2.CreateParameter("@interfacename", 200, 1, 50, "Interface 2")
On Error Resume Next On Error Resume Next
@@ -508,15 +499,18 @@
' Interface 3 (Optional) ' Interface 3 (Optional)
If ip3 <> "" Or mac3 <> "" Then If ip3 <> "" Or mac3 <> "" Then
Dim cmdComm3 Dim cmdComm3, ip3Val, mac3Val
If ip3 <> "" Then ip3Val = ip3 Else ip3Val = Null
If mac3 <> "" Then mac3Val = mac3 Else mac3Val = Null
Set cmdComm3 = Server.CreateObject("ADODB.Command") Set cmdComm3 = Server.CreateObject("ADODB.Command")
cmdComm3.ActiveConnection = objConn cmdComm3.ActiveConnection = objConn
cmdComm3.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 0, 1)" cmdComm3.CommandText = "INSERT INTO communications (machineid, comstypeid, address, macaddress, interfacename, isprimary, isactive) VALUES (?, ?, ?, ?, ?, 0, 1)"
cmdComm3.CommandType = 1 cmdComm3.CommandType = 1
cmdComm3.Parameters.Append cmdComm3.CreateParameter("@machineid", 3, 1, , CLng(machineid)) cmdComm3.Parameters.Append cmdComm3.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdComm3.Parameters.Append cmdComm3.CreateParameter("@comstypeid", 3, 1, , comstypeid) cmdComm3.Parameters.Append cmdComm3.CreateParameter("@comstypeid", 3, 1, , comstypeid)
cmdComm3.Parameters.Append cmdComm3.CreateParameter("@address", 200, 1, 50, IIf(ip3 <> "", ip3, Null)) cmdComm3.Parameters.Append cmdComm3.CreateParameter("@address", 200, 1, 50, ip3Val)
cmdComm3.Parameters.Append cmdComm3.CreateParameter("@macaddress", 200, 1, 50, IIf(mac3 <> "", mac3, Null)) cmdComm3.Parameters.Append cmdComm3.CreateParameter("@macaddress", 200, 1, 50, mac3Val)
cmdComm3.Parameters.Append cmdComm3.CreateParameter("@interfacename", 200, 1, 50, "Interface 3") cmdComm3.Parameters.Append cmdComm3.CreateParameter("@interfacename", 200, 1, 50, "Interface 3")
On Error Resume Next On Error Resume Next
@@ -559,7 +553,21 @@
If Not rsCheck.EOF Then dualpathTypeID = rsCheck("relationshiptypeid") If Not rsCheck.EOF Then dualpathTypeID = rsCheck("relationshiptypeid")
rsCheck.Close rsCheck.Close
' Create Controls relationship (PC controls this equipment) ' Check if this machine is a PC (machinetypeid >= 33) to determine relationship direction
Dim isPC, currentMachineTypeID
isPC = False
Set rsCheck = objConn.Execute("SELECT machinetypeid FROM machines WHERE machineid = " & CLng(machineid))
If Not rsCheck.EOF Then
currentMachineTypeID = rsCheck("machinetypeid")
If Not IsNull(currentMachineTypeID) And currentMachineTypeID >= 33 Then
isPC = True
End If
End If
rsCheck.Close
' Create Controls relationship
' For PCs: This PC (machineid) controls the selected equipment (controllingpc form value)
' For Equipment: The selected PC (controllingpc form value) controls this equipment (machineid)
On Error Resume Next On Error Resume Next
Dim tempControllingPC Dim tempControllingPC
tempControllingPC = 0 tempControllingPC = 0
@@ -576,8 +584,16 @@
cmdRelPC.ActiveConnection = objConn cmdRelPC.ActiveConnection = objConn
cmdRelPC.CommandText = "INSERT INTO machinerelationships (machineid, related_machineid, relationshiptypeid, isactive) VALUES (?, ?, ?, 1)" cmdRelPC.CommandText = "INSERT INTO machinerelationships (machineid, related_machineid, relationshiptypeid, isactive) VALUES (?, ?, ?, 1)"
cmdRelPC.CommandType = 1 cmdRelPC.CommandType = 1
If isPC Then
' PC page: This PC controls the equipment (PC is machineid, equipment is related_machineid)
cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@machineid", 3, 1, , CLng(machineid))
cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@related_machineid", 3, 1, , tempControllingPC)
Else
' Equipment page: The PC controls this equipment (PC is machineid, equipment is related_machineid)
cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@machineid", 3, 1, , tempControllingPC) cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@machineid", 3, 1, , tempControllingPC)
cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@related_machineid", 3, 1, , CLng(machineid)) cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@related_machineid", 3, 1, , CLng(machineid))
End If
cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@relationshiptypeid", 3, 1, , controlsTypeID) cmdRelPC.Parameters.Append cmdRelPC.CreateParameter("@relationshiptypeid", 3, 1, , controlsTypeID)
On Error Resume Next On Error Resume Next
@@ -641,16 +657,14 @@
newthirdpartyvendorname = Trim(Request.Form("newthirdpartyvendorname")) newthirdpartyvendorname = Trim(Request.Form("newthirdpartyvendorname"))
If Len(newthirdpartyvendorname) = 0 Then If Len(newthirdpartyvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New third party vendor name is required</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "New third party vendor name is required.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
If Len(newthirdpartyvendorname) > 50 Then If Len(newthirdpartyvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Third party vendor name too long</div>")
Response.Write("<a href='javascript:history.back()'>Go back</a>")
objConn.Close objConn.Close
ShowError "Third party vendor name too long.", "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -667,10 +681,11 @@
cmdNewTPVendor.Execute cmdNewTPVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new third party vendor: " & Server.HTMLEncode(Err.Description) & "</div>") Dim tpVendorErrMsg
Response.Write("<a href='javascript:history.back()'>Go back</a>") tpVendorErrMsg = Err.Description
Set cmdNewTPVendor = Nothing Set cmdNewTPVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating new third party vendor: " & tpVendorErrMsg, "editpc.asp?machineid=" & machineid
Response.End Response.End
End If End If
@@ -757,12 +772,16 @@
On Error Goto 0 On Error Goto 0
End If End If
objConn.Close ' Redirect to appropriate display page based on machine type
Dim redirectUrl, entityName
If isPC Then
redirectUrl = "displaypc.asp?machineid=" & machineid
entityName = "PC Details"
Else
redirectUrl = "displaymachine.asp?machineid=" & machineid
entityName = "Machine Details"
End If
' Redirect to displaymachine.asp with the machine ID objConn.Close
ShowSuccess "Machine updated successfully.", redirectUrl, entityName
%> %>
<meta http-equiv="refresh" content="0; url=./displaymachine.asp?machineid=<%=Server.HTMLEncode(machineid)%>">
<p>Machine updated successfully. Redirecting...</p>
</div>
</body>
</html>

View File

@@ -10,6 +10,7 @@
<head> <head>
<link rel="stylesheet" href="./style.css" type="text/css"> <link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
</head> </head>
<body> <body>
@@ -38,47 +39,41 @@
' Validate required fields ' Validate required fields
If modelnumber = "" Then If modelnumber = "" Then
Response.Write("<div class='alert alert-danger'>Error: Model number is required.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model number is required.", "addmodel.asp"
Response.End Response.End
End If End If
' Validate field lengths ' Validate field lengths
If Len(modelnumber) > 255 Then If Len(modelnumber) > 255 Then
Response.Write("<div class='alert alert-danger'>Error: Model number too long.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model number too long.", "addmodel.asp"
Response.End Response.End
End If End If
If Len(notes) > 255 Then If Len(notes) > 255 Then
Response.Write("<div class='alert alert-danger'>Error: Notes too long.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Notes too long.", "addmodel.asp"
Response.End Response.End
End If End If
If Len(documentationpath) > 255 Then If Len(documentationpath) > 255 Then
Response.Write("<div class='alert alert-danger'>Error: Documentation path too long.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Documentation path too long.", "addmodel.asp"
Response.End Response.End
End If End If
' Check if we need to create a new vendor first ' Check if we need to create a new vendor first
If vendorid = "new" Then If vendorid = "new" Then
If newvendorname = "" Then If newvendorname = "" Then
Response.Write("<div class='alert alert-danger'>Error: Manufacturer name is required when adding a new manufacturer.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Manufacturer name is required when adding a new manufacturer.", "addmodel.asp"
Response.End Response.End
End If End If
If Len(newvendorname) > 50 Then If Len(newvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: Manufacturer name too long.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Manufacturer name too long.", "addmodel.asp"
Response.End Response.End
End If End If
@@ -97,9 +92,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Manufacturer '" & Server.HTMLEncode(Request.Form("newvendorname")) & "' already exists.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Manufacturer '" & Server.HTMLEncode(Request.Form("newvendorname")) & "' already exists.", "addmodel.asp"
Response.End Response.End
End If End If
End If End If
@@ -130,10 +124,9 @@
cmdVendor.Execute cmdVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating manufacturer: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
Set cmdVendor = Nothing Set cmdVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating manufacturer: " & Server.HTMLEncode(Err.Description), "addmodel.asp"
Response.End Response.End
End If End If
@@ -152,9 +145,8 @@
Else Else
' Validate existing vendor ID ' Validate existing vendor ID
If Not IsNumeric(vendorid) Or CLng(vendorid) < 1 Then If Not IsNumeric(vendorid) Or CLng(vendorid) < 1 Then
Response.Write("<div class='alert alert-danger'>Error: Invalid manufacturer ID.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Invalid manufacturer ID.", "addmodel.asp"
Response.End Response.End
End If End If
End If End If
@@ -199,9 +191,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Model '" & Server.HTMLEncode(Request.Form("modelnumber")) & "' already exists for this manufacturer.</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model '" & Server.HTMLEncode(Request.Form("modelnumber")) & "' already exists for this manufacturer.", "addmodel.asp"
Response.End Response.End
End If End If
End If End If
@@ -226,10 +217,9 @@
cmdModel.Execute cmdModel.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addmodel.asp'>Go back</a>")
Set cmdModel = Nothing Set cmdModel = Nothing
objConn.Close objConn.Close
ShowError Server.HTMLEncode(Err.Description), "addmodel.asp"
Response.End Response.End
End If End If
@@ -250,14 +240,9 @@
objConn.Close objConn.Close
If newModelId > 0 Then If newModelId > 0 Then
Response.Write("<div class='alert alert-success'><i class='zmdi zmdi-check'></i> Model added successfully!</div>") ShowSuccess "Model '" & Server.HTMLEncode(Request.Form("modelnumber")) & "' added successfully.", "addmodel.asp", "add another"
Response.Write("<p>Model '" & Server.HTMLEncode(Request.Form("modelnumber")) & "' has been added.</p>")
Response.Write("<p><a href='addmodel.asp' class='btn btn-primary'>Add Another Model</a> ")
Response.Write("<a href='addprinter.asp' class='btn btn-secondary'>Add Printer</a> ")
Response.Write("<a href='addmachine.asp' class='btn btn-secondary'>Add Machine</a></p>")
Else Else
Response.Write("<div class='alert alert-danger'>Error: Model was not added successfully.</div>") ShowError "Model was not added successfully.", "addmodel.asp"
Response.Write("<a href='addmodel.asp'>Go back</a>")
End If End If
%> %>
</div> </div>

View File

@@ -7,15 +7,17 @@
'============================================================================= '=============================================================================
%> %>
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<% <%
' Get form inputs ' Get form inputs
Dim notification, ticketnumber, starttime, endtime, isactive, isshopfloor, notificationtypeid, businessunitid Dim notification, ticketnumber, starttime, endtime, isactive, isshopfloor, notificationtypeid, businessunitid, appid
notification = Trim(Request.Form("notification")) notification = Trim(Request.Form("notification"))
ticketnumber = Trim(Request.Form("ticketnumber")) ticketnumber = Trim(Request.Form("ticketnumber"))
starttime = Trim(Request.Form("starttime")) starttime = Trim(Request.Form("starttime"))
endtime = Trim(Request.Form("endtime")) endtime = Trim(Request.Form("endtime"))
notificationtypeid = Trim(Request.Form("notificationtypeid")) notificationtypeid = Trim(Request.Form("notificationtypeid"))
businessunitid = Trim(Request.Form("businessunitid")) businessunitid = Trim(Request.Form("businessunitid"))
appid = Trim(Request.Form("appid"))
' Checkboxes - ensure they are always integers 0 or 1 ' Checkboxes - ensure they are always integers 0 or 1
If Request.Form("isactive") = "1" Then If Request.Form("isactive") = "1" Then
@@ -37,14 +39,14 @@ End If
' Validate required fields (endtime is now optional) ' Validate required fields (endtime is now optional)
If Len(notification) = 0 Or Len(starttime) = 0 Then If Len(notification) = 0 Or Len(starttime) = 0 Then
Response.Write("Required fields missing")
objConn.Close objConn.Close
ShowError "Required fields missing.", "addnotification.asp"
Response.End Response.End
End If End If
If Len(notification) > 500 Or Len(ticketnumber) > 50 Then If Len(notification) > 500 Or Len(ticketnumber) > 50 Then
Response.Write("Field length exceeded")
objConn.Close objConn.Close
ShowError "Field length exceeded.", "addnotification.asp"
Response.End Response.End
End If End If
@@ -69,10 +71,18 @@ Else
businessunitValue = CLng(businessunitid) businessunitValue = CLng(businessunitid)
End If End If
' Handle optional appid - NULL means not linked to an application
Dim appidValue
If appid = "" Or Not IsNumeric(appid) Then
appidValue = Null
Else
appidValue = CLng(appid)
End If
' INSERT using parameterized query ' INSERT using parameterized query
Dim strSQL, cmdInsert Dim strSQL, cmdInsert
strSQL = "INSERT INTO notifications (notificationtypeid, businessunitid, notification, ticketnumber, starttime, endtime, isactive, isshopfloor) " & _ strSQL = "INSERT INTO notifications (notificationtypeid, businessunitid, appid, notification, ticketnumber, starttime, endtime, isactive, isshopfloor) " & _
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)" "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
Set cmdInsert = Server.CreateObject("ADODB.Command") Set cmdInsert = Server.CreateObject("ADODB.Command")
cmdInsert.ActiveConnection = objConn cmdInsert.ActiveConnection = objConn
cmdInsert.CommandText = strSQL cmdInsert.CommandText = strSQL
@@ -83,6 +93,11 @@ If IsNull(businessunitValue) Then
Else Else
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@businessunitid", 3, 1, , businessunitValue) cmdInsert.Parameters.Append cmdInsert.CreateParameter("@businessunitid", 3, 1, , businessunitValue)
End If End If
If IsNull(appidValue) Then
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@appid", 2, 1, , Null)
Else
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@appid", 2, 1, , appidValue)
End If
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@notification", 200, 1, 500, notification) cmdInsert.Parameters.Append cmdInsert.CreateParameter("@notification", 200, 1, 500, notification)
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@ticketnumber", 200, 1, 50, ticketnumber) cmdInsert.Parameters.Append cmdInsert.CreateParameter("@ticketnumber", 200, 1, 50, ticketnumber)
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@starttime", 135, 1, , starttime) cmdInsert.Parameters.Append cmdInsert.CreateParameter("@starttime", 135, 1, , starttime)
@@ -100,10 +115,12 @@ cmdInsert.Execute
If Err.Number = 0 Then If Err.Number = 0 Then
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
Response.Redirect("displaynotifications.asp") ShowSuccess "Notification created successfully.", "displaynotifications.asp", "notifications"
Else Else
Response.Write("Error: " & Server.HTMLEncode(Err.Description)) Dim insertErr
insertErr = Err.Description
Set cmdInsert = Nothing Set cmdInsert = Nothing
objConn.Close objConn.Close
ShowError "Error: " & Server.HTMLEncode(insertErr), "addnotification.asp"
End If End If
%> %>

View File

@@ -9,19 +9,21 @@
<head> <head>
<link rel="stylesheet" href="./style.css" type="text/css"> <link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
</head> </head>
<body> <body>
<div class="page"> <div class="page">
<% <%
' Get and validate all inputs ' Get and validate all inputs
Dim modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, machineid, maptop, mapleft Dim modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, printerpin, machineid, maptop, mapleft
modelid = Trim(Request.Form("modelid")) modelid = Trim(Request.Form("modelid"))
serialnumber = Trim(Request.Form("serialnumber")) serialnumber = Trim(Request.Form("serialnumber"))
ipaddress = Trim(Request.Form("ipaddress")) ipaddress = Trim(Request.Form("ipaddress"))
fqdn = Trim(Request.Form("fqdn")) fqdn = Trim(Request.Form("fqdn"))
printercsfname = Trim(Request.Form("printercsfname")) printercsfname = Trim(Request.Form("printercsfname"))
printerwindowsname = Trim(Request.Form("printerwindowsname")) printerwindowsname = Trim(Request.Form("printerwindowsname"))
printerpin = Trim(Request.Form("printerpin"))
machineid = Trim(Request.Form("machineid")) machineid = Trim(Request.Form("machineid"))
maptop = Trim(Request.Form("maptop")) maptop = Trim(Request.Form("maptop"))
mapleft = Trim(Request.Form("mapleft")) mapleft = Trim(Request.Form("mapleft"))
@@ -39,39 +41,34 @@
' Validate required fields ' Validate required fields
If modelid = "" Then If modelid = "" Then
Response.Write("<div class='alert alert-danger'>Error: Model is required.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Model is required.", "addprinter.asp"
Response.End Response.End
End If End If
If modelid <> "new" And Not IsNumeric(modelid) Then If modelid <> "new" And Not IsNumeric(modelid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid model ID.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Invalid model ID.", "addprinter.asp"
Response.End Response.End
End If End If
' Machine ID is now optional - only validate if provided ' Machine ID is now optional - only validate if provided
If machineid <> "" And Not IsNumeric(machineid) Then If machineid <> "" And Not IsNumeric(machineid) Then
Response.Write("<div class='alert alert-danger'>Error: Invalid machine ID.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Invalid machine ID.", "addprinter.asp"
Response.End Response.End
End If End If
If serialnumber = "" Or ipaddress = "" Or printerwindowsname = "" Then If serialnumber = "" Or ipaddress = "" Or printerwindowsname = "" Then
Response.Write("<div class='alert alert-danger'>Error: Required fields missing.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Required fields missing.", "addprinter.asp"
Response.End Response.End
End If End If
' Validate field lengths ' Validate field lengths
If Len(serialnumber) > 100 Or Len(fqdn) > 255 Or Len(printercsfname) > 50 Or Len(printerwindowsname) > 255 Then If Len(serialnumber) > 100 Or Len(fqdn) > 255 Or Len(printercsfname) > 50 Or Len(printerwindowsname) > 255 Then
Response.Write("<div class='alert alert-danger'>Error: Field length exceeded.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Field length exceeded.", "addprinter.asp"
Response.End Response.End
End If End If
@@ -91,9 +88,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: A printer with IP address '" & Server.HTMLEncode(ipaddress) & "' already exists.</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: A printer with IP address '" & Server.HTMLEncode(ipaddress) & "' already exists.", "addprinter.asp"
Response.End Response.End
End If End If
End If End If
@@ -105,39 +101,34 @@
' Handle new model creation ' Handle new model creation
If modelid = "new" Then If modelid = "new" Then
If Len(newmodelnumber) = 0 Then If Len(newmodelnumber) = 0 Then
Response.Write("<div class='alert alert-danger'>New model number is required</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New model number is required", "addprinter.asp"
Response.End Response.End
End If End If
If Len(newvendorid) = 0 Then If Len(newvendorid) = 0 Then
Response.Write("<div class='alert alert-danger'>Vendor is required for new model</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor is required for new model", "addprinter.asp"
Response.End Response.End
End If End If
If Len(newmodelnumber) > 255 Or Len(newmodelnotes) > 255 Or Len(newmodeldocpath) > 255 Then If Len(newmodelnumber) > 255 Or Len(newmodelnotes) > 255 Or Len(newmodeldocpath) > 255 Then
Response.Write("<div class='alert alert-danger'>Model field length exceeded</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Model field length exceeded", "addprinter.asp"
Response.End Response.End
End If End If
' Handle new vendor creation (nested) ' Handle new vendor creation (nested)
If newvendorid = "new" Then If newvendorid = "new" Then
If Len(newvendorname) = 0 Then If Len(newvendorname) = 0 Then
Response.Write("<div class='alert alert-danger'>New vendor name is required</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "New vendor name is required", "addprinter.asp"
Response.End Response.End
End If End If
If Len(newvendorname) > 50 Then If Len(newvendorname) > 50 Then
Response.Write("<div class='alert alert-danger'>Vendor name too long</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Vendor name too long", "addprinter.asp"
Response.End Response.End
End If End If
@@ -154,10 +145,9 @@
cmdNewVendor.Execute cmdNewVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new vendor: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
Set cmdNewVendor = Nothing Set cmdNewVendor = Nothing
objConn.Close objConn.Close
ShowError "Error creating new vendor: " & Server.HTMLEncode(Err.Description), "addprinter.asp"
Response.End Response.End
End If End If
Set cmdNewVendor = Nothing Set cmdNewVendor = Nothing
@@ -193,10 +183,9 @@
cmdNewModel.Execute cmdNewModel.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error creating new model: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
Set cmdNewModel = Nothing Set cmdNewModel = Nothing
objConn.Close objConn.Close
ShowError "Error creating new model: " & Server.HTMLEncode(Err.Description), "addprinter.asp"
Response.End Response.End
End If End If
Set cmdNewModel = Nothing Set cmdNewModel = Nothing
@@ -240,8 +229,16 @@
machineIdValue = Null machineIdValue = Null
End If End If
strSQL = "INSERT INTO printers (modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, machineid, maptop, mapleft, isactive) " & _ ' Handle optional PIN - use NULL if not provided
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1)" Dim printerpinValue
If printerpin <> "" Then
printerpinValue = printerpin
Else
printerpinValue = Null
End If
strSQL = "INSERT INTO printers (modelid, serialnumber, ipaddress, fqdn, printercsfname, printerwindowsname, printerpin, machineid, maptop, mapleft, isactive) " & _
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)"
On Error Resume Next On Error Resume Next
Set cmdPrinter = Server.CreateObject("ADODB.Command") Set cmdPrinter = Server.CreateObject("ADODB.Command")
@@ -254,16 +251,16 @@
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@fqdn", 200, 1, 255, fqdn) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@fqdn", 200, 1, 255, fqdn)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@printercsfname", 200, 1, 50, printercsfname) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@printercsfname", 200, 1, 50, printercsfname)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@printerwindowsname", 200, 1, 255, printerwindowsname) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@printerwindowsname", 200, 1, 255, printerwindowsname)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@printerpin", 200, 1, 10, printerpinValue)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@machineid", 3, 1, , machineIdValue) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@machineid", 3, 1, , machineIdValue)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@maptop", 3, 1, , maptopValue) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@maptop", 3, 1, , maptopValue)
cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@mapleft", 3, 1, , mapleftValue) cmdPrinter.Parameters.Append cmdPrinter.CreateParameter("@mapleft", 3, 1, , mapleftValue)
cmdPrinter.Execute cmdPrinter.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error inserting printer: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addprinter.asp'>Go back</a>")
Set cmdPrinter = Nothing Set cmdPrinter = Nothing
objConn.Close objConn.Close
ShowError "Error inserting printer: " & Server.HTMLEncode(Err.Description), "addprinter.asp"
Response.End Response.End
End If End If
Set cmdPrinter = Nothing Set cmdPrinter = Nothing
@@ -284,11 +281,9 @@
objConn.Close objConn.Close
If CLng(newPrinterId) > 0 Then If CLng(newPrinterId) > 0 Then
%> ShowSuccess "Printer added successfully.", "displayprinter.asp?printerid=" & newPrinterId, "printer details"
<meta http-equiv="refresh" content="0; url=./displayprinter.asp?printerid=<%=Server.HTMLEncode(newPrinterId)%>">
<%
Else Else
Response.Write("Error: Printer was not added successfully.") ShowError "Printer was not added successfully.", "addprinter.asp"
End If End If
%> %>
</div> </div>

108
saveusb_direct.asp Normal file
View File

@@ -0,0 +1,108 @@
<%
'=============================================================================
' FILE: saveusb_direct.asp
' PURPOSE: Create new USB device in machines table
' SECURITY: Parameterized queries, HTML encoding, input validation
' CREATED: 2025-12-07
'=============================================================================
%>
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
<%
' Get form values
Dim serialnumber, alias, businessunitid
serialnumber = Trim(Request.Form("serialnumber"))
alias = Trim(Request.Form("alias"))
businessunitid = Trim(Request.Form("businessunitid"))
' Basic validation - serial number required
If serialnumber = "" Or Len(serialnumber) < 3 Or Len(serialnumber) > 100 Then
objConn.Close
ShowError "Invalid serial number. Must be 3-100 characters.", "addusb.asp"
Response.End
End If
' Check if serial number already exists in machines table
Dim checkSQL, rsCheck, cmdCheck, existingMachineID, existingMachineType
checkSQL = "SELECT machineid, machinetypeid FROM machines WHERE serialnumber = ? AND isactive = 1"
Set cmdCheck = Server.CreateObject("ADODB.Command")
cmdCheck.ActiveConnection = objConn
cmdCheck.CommandText = checkSQL
cmdCheck.CommandType = 1
cmdCheck.Parameters.Append cmdCheck.CreateParameter("@serialnumber", 200, 1, 100, serialnumber)
Set rsCheck = cmdCheck.Execute
If Not rsCheck.EOF Then
' Serial number already exists
existingMachineID = rsCheck("machineid")
existingMachineType = rsCheck("machinetypeid")
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
objConn.Close
' If it's already a USB device, show error
If existingMachineType = 44 Then
ShowError "USB device with serial '" & Server.HTMLEncode(serialnumber) & "' already exists.", "addusb.asp"
Else
ShowError "A device with serial '" & Server.HTMLEncode(serialnumber) & "' already exists as a different machine type.", "addusb.asp"
End If
Response.End
End If
rsCheck.Close
Set rsCheck = Nothing
Set cmdCheck = Nothing
' Prepare businessunitid - convert to NULL if empty
Dim buValue
If businessunitid = "" Or Not IsNumeric(businessunitid) Then
buValue = Null
Else
buValue = CLng(businessunitid)
End If
' Prepare alias - use serial if empty
If alias = "" Then
alias = serialnumber
End If
' Insert new USB device
' machinetypeid = 44 (USB Device)
' machinestatusid = 2 (Inventory)
' isactive = 1
Dim insertSQL, cmdInsert
insertSQL = "INSERT INTO machines (serialnumber, machinenumber, alias, machinetypeid, businessunitid, machinestatusid, isactive, lastupdated) " & _
"VALUES (?, ?, ?, 44, ?, 2, 1, NOW())"
Set cmdInsert = Server.CreateObject("ADODB.Command")
cmdInsert.ActiveConnection = objConn
cmdInsert.CommandText = insertSQL
cmdInsert.CommandType = 1
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@serialnumber", 200, 1, 100, serialnumber)
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@machinenumber", 200, 1, 50, serialnumber)
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@alias", 200, 1, 50, alias)
' Handle nullable businessunitid
If IsNull(buValue) Then
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@businessunitid", 3, 1, , Null)
Else
cmdInsert.Parameters.Append cmdInsert.CreateParameter("@businessunitid", 3, 1, , buValue)
End If
On Error Resume Next
cmdInsert.Execute
If Err.Number = 0 Then
Set cmdInsert = Nothing
objConn.Close
' Success - redirect with success parameter
Response.Redirect("./addusb.asp?added=" & Server.URLEncode(serialnumber))
Else
Dim insertErr
insertErr = Err.Description
Set cmdInsert = Nothing
objConn.Close
ShowError "Error adding USB device: " & Server.HTMLEncode(insertErr), "addusb.asp"
End If
%>

View File

@@ -10,6 +10,7 @@
<head> <head>
<link rel="stylesheet" href="./style.css" type="text/css"> <link rel="stylesheet" href="./style.css" type="text/css">
<!--#include file="./includes/sql.asp"--> <!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/response.asp"-->
</head> </head>
<body> <body>
@@ -23,23 +24,20 @@
' Validate ' Validate
If vendor = "" Then If vendor = "" Then
Response.Write("<div class='alert alert-danger'>Error: Manufacturer name is required.</div>")
Response.Write("<a href='addvendor.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Manufacturer name is required.", "addvendor.asp"
Response.End Response.End
End If End If
If Len(vendor) > 50 Then If Len(vendor) > 50 Then
Response.Write("<div class='alert alert-danger'>Error: Manufacturer name too long.</div>")
Response.Write("<a href='addvendor.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Manufacturer name too long.", "addvendor.asp"
Response.End Response.End
End If End If
If isprinter <> "1" AND ispc <> "1" AND ismachine <> "1" Then If isprinter <> "1" AND ispc <> "1" AND ismachine <> "1" Then
Response.Write("<div class='alert alert-danger'>Error: Please select at least one category.</div>")
Response.Write("<a href='addvendor.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Please select at least one category.", "addvendor.asp"
Response.End Response.End
End If End If
@@ -59,9 +57,8 @@
rsCheck.Close rsCheck.Close
Set rsCheck = Nothing Set rsCheck = Nothing
Set cmdCheck = Nothing Set cmdCheck = Nothing
Response.Write("<div class='alert alert-danger'>Error: Manufacturer '" & Server.HTMLEncode(vendor) & "' already exists.</div>")
Response.Write("<a href='addvendor.asp'>Go back</a>")
objConn.Close objConn.Close
ShowError "Error: Manufacturer '" & Server.HTMLEncode(vendor) & "' already exists.", "addvendor.asp"
Response.End Response.End
End If End If
End If End If
@@ -92,10 +89,9 @@
cmdVendor.Execute cmdVendor.Execute
If Err.Number <> 0 Then If Err.Number <> 0 Then
Response.Write("<div class='alert alert-danger'>Error: " & Server.HTMLEncode(Err.Description) & "</div>")
Response.Write("<a href='addvendor.asp'>Go back</a>")
Set cmdVendor = Nothing Set cmdVendor = Nothing
objConn.Close objConn.Close
ShowError "Error: " & Server.HTMLEncode(Err.Description), "addvendor.asp"
Response.End Response.End
End If End If
@@ -117,13 +113,9 @@
objConn.Close objConn.Close
If newVendorId > 0 Then If newVendorId > 0 Then
Response.Write("<div class='alert alert-success'><i class='zmdi zmdi-check'></i> Manufacturer added successfully!</div>") ShowSuccess "Manufacturer '" & Server.HTMLEncode(Request.Form("vendor")) & "' added successfully.", "addvendor.asp", "add another"
Response.Write("<p>Manufacturer '" & Server.HTMLEncode(Request.Form("vendor")) & "' has been added.</p>")
Response.Write("<p><a href='addvendor.asp' class='btn btn-primary'>Add Another Manufacturer</a> ")
Response.Write("<a href='addmodel.asp' class='btn btn-secondary'>Add Model</a></p>")
Else Else
Response.Write("<div class='alert alert-danger'>Error: Manufacturer was not added.</div>") ShowError "Manufacturer was not added.", "addvendor.asp"
Response.Write("<a href='addvendor.asp'>Go back</a>")
End If End If
%> %>
</div> </div>

240
scripts/3122.reg Normal file
View File

@@ -0,0 +1,240 @@
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC]
"COMPUTERNAME"="G31N20R3ESF"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Btr]
"BTR Rate"="300"
"Seq Search"="NO"
"Auto Rewind"="YES"
"BCC"="NO"
"CMNT"="NO"
"CmntLag"=dword:00000000
"DisableScrnSvr"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\DatC]
"Debug"="NO"
"Multi"="NO"
"WorkStations"="0"
"WS1"=""
"WS2"=""
"WS3"=""
"WS4"=""
"WS5"=""
"WS6"=""
"Files Threshold"="200"
"Any"="NO"
"DaysOld"="7"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\General]
"Site"="WestJefferson"
"Cnc"="Fanuc 30"
"NcIF"="EFOCAS"
"MachineNo"="3122"
"Debug"="ON"
"Uploads"="NO"
"Scanner"="YES"
"HostType"="WILM"
"DvUpldDir"="..\\shared\\NC-DATA\\Okuma"
"Ncedt"="NO"
"Maint"="YES"
"Mode"="Small"
"Unit/Area"=""
"Dripfeed"="NO"
"ChangeWorkstation"="NO"
"CWRegPath"="C:\\Program Files\\Dnc"
"FtpFileSel"="Host"
"DvDnldDir"=""
"RemindEnable"="NO"
"RemindBkupHost"=""
"RemindBkupFolder"=""
"Print"="NO"
"FixTorque"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Hssb]
"KRelay1"=dword:0000000b
"ProgIdLimit"="8000"
"KeyCheck"="YES"
"DelHighIds"="NO"
"StdPmcG"="YES"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\MX]
"FtpPasswd"="qxOG8q1QnR"
"FtpHostPrimary"="tsgwp00525"
"FtpHostSecondary"="tsgwp00525"
"FtpAccount"="geaeevendale\\sfwj0ashp"
"FtpHostType"="Windows"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\QUAL]
"UserName"=""
"Password"=""
"Primary"=""
"Secondary"=""
"SocketNo"=""
"Timeout"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Serial]
"Port Id"="COM1"
"Baud"="9600"
"Parity"="None"
"Data Bits"="8"
"Stop Bits"="1"
"CRLF"="NO"
"EOL Delay"="NO"
"MC2000Dels"="NO"
"EOT"="NO"
"EOL Delay msec"="0"
"DeleteLT9000"=""
"SwapSize"=""
"2Saddle"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Mark]
"Port Id"="COM4"
"Baud"="9600"
"Parity"="None"
"Data Bits"="8"
"Stop Bits"="1"
"Message Type"="V"
"Debug"="ON"
"MarkerType"="Mark2D"
"DncPatterns"="YES"
"CageCode"=""
"DataHost"=""
"DataPath"=""
"MarkMasterPath"=""
"Port Id2"=""
"Baud2"=""
"Parity2"=""
"Data Bits2"=""
"Stop Bits2"=""
"DisableWeight"="NO"
"DisableBarcode"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\NTSHR]
"ShrHost"=""
"ShrFolder"=""
"ShrExt"=""
"ShrFolder2"=""
"ShrFolder3"=""
"ProgIdLimit"=""
"Deletes"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\FtpDnld]
"Target"=""
"Username"=""
"Password"=""
"DirectoryPath"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\DNC2]
"MPRelay"=""
"ProgIdLimit"=""
"PMC-NB"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\FMS]
"FMSHostPrimary"="WJFMS3"
"FMSHostSecondary"="WJFMS3"
"FMSSocketBase"="5003"
"FMSTimeOut"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\PPDCS]
"Port Id"="COM4"
"Baud"="9600"
"Data Bits"="8"
"Parity"="None"
"Stop Bits"="1"
"Start Char"="DC2"
"Wait Time"="250"
"UserName"="DCP_SHOPWJ"
"Password"="QSy1Go"
"Primary"="wjfms3.ae.ge.com"
"Secondary"="wjfms3.ae.ge.com"
"Timeout"="10"
"Files Threshold"="5"
"FrontEnd"="PPMON"
"TQM9030"="NO"
"TextMode Menu"="NO"
"TreeDisplay"="YES"
"CLMShare"=""
"ShareFile"=""
"SharePoll"=""
"MDMacroVar"=""
"TQMCaron"="NO"
"CycleStart Inhibits"="YES"
"EnableSharePoll"="NO"
"WaitForCncFile"=""
"HostType"="VMS"
"HostPath"=""
"Port Id2"="COM1"
"ShareHost"=""
"SharePollUnits"="msec"
"FileAge"=""
"HostPath2"=""
"SearchSubfolders"=""
"ManualDataBadge"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\TncRemo]
"TncFolder"=""
"TncExt"=""
"TncIpAddr"=""
"Port"=""
"Medium"=""
"MjtLaser"=""
"HFolder"=""
"IFolder"=""
"DFolder"=""
"TABFolder"=""
"TFolder"=""
"TCHFolder"=""
"PFolder"=""
"PNTFolder"=""
"CDTFolder"=""
"AFolder"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\eFocas]
"IpAddr"="192.168.1.1"
"SocketNo"="8192"
"DualPath"="NO"
"Path1Name"=""
"Path2Name"=""
"Danobat"="NO"
"DataServer"="NO"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\TQM9030]
"Port Id"=""
"Baud"=""
"Parity"=""
"Data Bits"=""
"Stop Bits"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\HeatTreat]
"FtpHost"=""
"FtpAccount"=""
"9030IpAddr"=""
"9030Register"=""
"CycleFilePath"=""
"FtpPasswd"=""
"9030Register2"=""
"9030Register3"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Plant3]
"Host"=""
"Path"=""
"Account"=""
"Password"=""
"EnableAutomation"="NO"
"MachineType"="Lathe"
"HostType"="Windows"
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\TQMCaron]
"Port Id"=""
"Baud"=""
"Parity"=""
"Data Bits"=""
"Stop Bits"=""
[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\PaintBooth]
"DataHost"=""
"DataFolder"=""
"PlcIpAddress"=""
"PollRate"=""

View File

@@ -0,0 +1,6 @@
@echo off
powershell -ExecutionPolicy Bypass -File "%~dp0Update-PC-Minimal.ps1"
echo.
echo Log saved to: %TEMP%\shopdb-update.log
echo.
pause

View File

@@ -0,0 +1,262 @@
=====================================
Complete PC Asset Collection - Fri 12/05/2025 10:08:27.70
Computer: G1CXL1V3ESF
User Context: lg672650sd
Script Directory: S:\DT\cameron\scan
Proxy: http://10.48.130.158/vendor-api-proxy.php
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Network Load Balancing: Disabled
=====================================
Checking for GE Aircraft Engines registry...
Backup-GERegistry.ps1 not found - skipping registry backup
=== Running PowerShell script ===
========================================
Complete PC Asset Collection & Storage
========================================
Computer: G1CXL1V3ESF
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
Using provided URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Note: Warranty lookups disabled (handled by dashboard)
=== STEP 1: COLLECT SYSTEM INFO ===
Collecting comprehensive system information...
Domain detected: logon.ds.ge.com
[OK] Shopfloor domain detected
[OK] PC-DMIS detected - CMM PC
Skipping application detection (PC Type: CMM)
Collecting installed applications...
Found 123 installed applications:
- 64 Bit HP CIO Components Installer (v22.2.1)
- Adobe Acrobat Reader DC (v15.017.20050)
- Adobe AcrobatReaderDC-Shopfloor XI V01 (vadobe_acrobatreaderdc-shopfloor_xi_v01 Build 0.0.0.0)
- BIG-IP Edge Client (v71.2019.0119.0331)
- BIG-IP Edge Client Components (All Users) (v71.2019.0119.0331)
- Cisco PEAP Module (v1.1.6)
- Classic Shell (v4.3.1)
- CLM 1.7 64-bit (v1.7.25.0)
- Compatibility Pack for the 2007 Office system (v12.0.6021.5000)
- GE NOMSAgentServiceInstaller 1.0 V01 (vge_nomsagentserviceinstaller_1.0_v01 Build 0.0.0.0)
- GE SFLD GPOUpdate 1.0 V01 (vge_sfld-gpoupdate_1.0_v01 Build 0.0.0.0)
- GE Tanium Health Check (v1.07)
- goCMM (v1.1.6718.31289)
- Google Chrome (v142.0.7444.176)
- Google Chrome 50 V01 (vgoogle_chrome_50_v01 Build 0.0.0.0)
- Google Endpoint Verification (v2.11.28)
- Google Legacy Browser Support (v8.1.0.0)
- Herramientas de correcci¢n de Microsoft Office 2016: espa¤ol (v16.0.4266.1001)
- InternetExplorer-SF8 (v1.0.0)
- IvoSoft ClassicShell 4.3.1 V01 (vivosoft_classicshell_4.3.1_v01 Build 0.0.0.0)
- Japan Fonts (v2.2)
- Java 8 Update 101 (v8.0.1010.13)
- Maxx Audio Installer (x64) (v2.7.13058.0)
- Microsoft Access MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Access Runtime 2016 (v16.0.4288.1001)
- Microsoft Access Runtime MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Access Setup Metadata MUI (English) 2016 (v16.0.4266.1001)
- Microsoft ASP.NET MVC 2 (v2.0.60926.0)
- Microsoft DCF MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Edge (v143.0.3650.66)
- Microsoft Edge WebView2 Runtime (v142.0.3595.94)
- Microsoft Excel MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Groove MUI (English) 2016 (v16.0.4266.1001)
- Microsoft InfoPath MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Office 2007-2010 Compatibility Pack
- Microsoft Office 2010 Viewers (vmicrosoft_office_2010_viewers_v5 Build 1.1.0.9)
- Microsoft Office 2016 x86 MSI 16.0.4266.1001 V04 (vmicrosoft_office2016x86-msi_16.0.4266.1001_v04 Build 0.0.0.0)
- Microsoft Office 64-bit Components 2016 (v16.0.4288.1001)
- Microsoft Office Excel Viewer (v12.0.6219.1000)
- Microsoft Office OSM MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Office OSM UX MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Office Professional Plus 2016 (v16.0.4266.1001)
- Microsoft Office Proofing (English) 2016 (v16.0.4266.1001)
- Microsoft Office Proofing Tools 2016 - English (v16.0.4266.1001)
- Microsoft Office Shared 64-bit MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared 64-bit Setup Metadata MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared Setup Metadata MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Word Viewer 2003 (v11.0.8173.0)
- Microsoft OneNote MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Outlook MUI (English) 2016 (v16.0.4266.1001)
- Microsoft PowerPoint MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Publisher MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Skype for Business MUI (English) 2016 (v16.0.4266.1001)
- Microsoft Visual C++ 2005 Redistributable (v8.0.56336)
- Microsoft Visual C++ 2010 x64 Redistributable - 10.0.40219 (v10.0.40219)
- Microsoft Visual C++ 2012 Redistributable (x64) - 11.0.51106 (v11.0.51106.1)
- Microsoft Visual C++ 2012 x64 Additional Runtime - 11.0.51106 (v11.0.51106)
- Microsoft Visual C++ 2012 x64 Minimum Runtime - 11.0.51106 (v11.0.51106)
- Microsoft Visual C++ 2015-2019 Redistributable (x64) - 14.22.27821 (v14.22.27821.0)
- Microsoft Visual C++ 2015-2019 Redistributable (x86) - 14.22.27821 (v14.22.27821.0)
- Microsoft Visual C++ 2019 X64 Additional Runtime - 14.22.27821 (v14.22.27821)
- Microsoft Visual C++ 2019 X64 Minimum Runtime - 14.22.27821 (v14.22.27821)
- Microsoft Visual C++ 2019 X86 Additional Runtime - 14.22.27821 (v14.22.27821)
- Microsoft Visual C++ 2019 X86 Minimum Runtime - 14.22.27821 (v14.22.27821)
- Microsoft Word MUI (English) 2016 (v16.0.4266.1001)
- MyTech Assistant 6.0.7 (v6.0.7)
- NOMS (v1.0.0)
- NVIDIA Graphics Driver 528.95 (v528.95)
- NVIDIA HD Audio Driver 1.3.39.16 (v1.3.39.16)
- NVIDIA Install Application (v2.1002.382.0)
- NVIDIA RTX Desktop Manager 204.26 (v204.26)
- OpenText Host Explorer - ShopFloor 15 SP1 V01 (vopentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0)
- OpenText HostExplorer 15 x64 (v15.0.1)
- Oracle JavaRuntimeEnvironment 8u101 V01 (voracle_javaruntimeenvironment_8u101_v01 Build 0.0.0.0)
- Oracle OracleDatabase 11r2 V03 (voracle_oracledatabase_11r2_v03 Build 0.0.0.0)
- Outils de vrification linguistique 2016 de Microsoft Officeÿ- Fran‡ais (v16.0.4266.1001)
- PC-DMIS 2019 R2 64-bit (v14.2.728.0)
- Realtek Audio COM Components (v1.0.2)
- Realtek High Definition Audio Driver (v6.0.9175.1)
- RealVNC Connect 6.0.1 V03 (vrealvnc_connect_6.0.1_v03 Build 0.0.0.0)
- Security Update for Microsoft Access 2016 (KB5002720) 32-Bit Edition
- Security Update for Microsoft Excel 2016 (KB5002794) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB2920704) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB2920727) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3085538) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3114690) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3191869) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3213551) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4011574) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4462148) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4464583) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4475581) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4475587) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4484103) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4484432) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5001941) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002058) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002112) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002341) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002573) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002575) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002576) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002616) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002719) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002757) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002762) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002766) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002792) 32-Bit Edition
- Security Update for Microsoft OneNote 2016 (KB5002622) 32-Bit Edition
- Security Update for Microsoft Outlook 2016 (KB5002683) 32-Bit Edition
- Security Update for Microsoft PowerPoint 2016 (KB5002790) 32-Bit Edition
- Security Update for Microsoft Project 2016 (KB5002561) 32-Bit Edition
- Security Update for Microsoft Publisher 2016 (KB5002566) 32-Bit Edition
- Security Update for Microsoft Visio 2016 (KB5002634) 32-Bit Edition
- Security Update for Microsoft Word 2016 (KB5002789) 32-Bit Edition
- Security Update for Skype for Business 2016 (KB5002181) 32-Bit Edition
- Setup (v1.1.6710.18601)
- Tanium Client 7.4.7.1179 (v7.4.7.1179)
- Universal Updater 1.4 64-bit (v1.4.669.0)
- Update for Microsoft Visio Viewer 2016 (KB2920709) 32-Bit Edition
- VNC Server 6.0.1 (v6.0.1.23971)
- VNC Viewer 6.0.1 (v6.0.1.23971)
Loaded 9 enabled applications from CSV
Matched: OpenText (ID:22) = OpenText Host Explorer - ShopFloor 15 SP1 V01 vopentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0
Skipping duplicate: OpenText (ID:22) = OpenText HostExplorer 15 x64
Matched: Oracle (ID:7) = Oracle OracleDatabase 11r2 V03 voracle_oracledatabase_11r2_v03 Build 0.0.0.0
Matched: PC-DMIS (ID:6) = PC-DMIS 2019 R2 64-bit v14.2.728.0
Matched: Tanium (ID:30) = Tanium Client 7.4.7.1179 v7.4.7.1179
Found 4 tracked applications for database
Running processes:
AggregatorHost, armsvc, backgroundTaskHost, ClassicStartMenu, cmd, conhost, cscript, csrss, ctfmon, dllhost, dwm, explorer, F5CredMgrSrv, F5FltSrv, F5InstallerService, F5TrafficSrv, FNPLicensingService64, fontdrvhost, Idle, IntelAudioService, lsass, Memory Compression, mobsync, MpDefenderCoreService, msdtc, MsMpEng, MTA.Controller, NetworkAdapterManager, NisSrv, noms_agent, NVDisplay.Container, nvWmi64, pacjsworker, powershell, RAVBg64, Registry, RtkAudioService64, RtkNGUI64, rundll32, RuntimeBroker, SchTasks, SearchApp, SearchFilterHost, SearchIndexer, SearchProtocolHost, SecurityHealthService, SecurityHealthSystray, services, sihost, smartscreen, smss, spoolsv, sppsvc, StartMenuExperienceHost, svchost, System, TaniumClient, TaniumCX, TaniumDriverSvc, taskhostw, TbtP2pShortcutService, TextInputHost, unsecapp, userinit, UserOOBEBroker, vncagent, vncserver, vncserverui, WavesSysSvc64, wininit, winlogon, WmiPrvSE, WUDFHost
System Details:
Hostname: G1CXL1V3ESF
Manufacturer: Dell Inc.
Model: Precision 5820 Tower
Serial: 1CXL1V3
PC Type: CMM
User: lg672650sd
Memory: 63.69 GB
OS: Microsoft Windows 10 Enterprise LTSC
=== STEP 2: COLLECT SHOPFLOOR INFO ===
=== STEP 3: WARRANTY DATA ===
Warranty lookups disabled - Dashboard will handle warranty updates
PCs cannot reach proxy server from this network
=== STEP 4: STORE IN DATABASE ===
Sending complete asset data to dashboard...
Dashboard URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
No ShopfloorInfo available
No installed applications to send
[OK] Complete asset data stored in database!
PCID: Unknown
Updated/Created: Unknown
Records affected: Unknown
=== STEP 5: PRINTER MAPPING ===
Collecting default printer information...
Default Printer: \\tsgwp00525.rd.ds.ge.com\4250@CSF02
Port Name: 10.80.92.65
[OK] Network printer detected - will send to database
Sending printer mapping to dashboard...
Hostname: G1CXL1V3ESF
Printer FQDN: 10.80.92.65
DEBUG Response: {"success":true,"message":"Printer mapping updated","printerId":22,"machinesUpdated":1,"matchMethod":"ip"}
[OK] Printer mapping updated successfully!
Printer ID:
Machines Updated:
Match Method:
=== STEP 6: APPLICATION MAPPING ===
Sending tracked applications to dashboard...
Hostname: G1CXL1V3ESF
Tracked Apps: 4
-> appid=22, appname='OpenText', version='opentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0'
-> appid=7, appname='Oracle', version='oracle_oracledatabase_11r2_v03 Build 0.0.0.0'
-> appid=6, appname='PC-DMIS', version='14.2.728.0'
-> appid=30, appname='Tanium', version='7.4.7.1179'
DEBUG JSON: [{"appid":22,"appname":"OpenText","version":"opentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0","displayname":"OpenText Host Explorer - ShopFloor 15 SP1 V01"},{"appid":7,"appname":"Oracle","version":"oracle_oracledatabase_11r2_v03 Build 0.0.0.0","displayname":"Oracle OracleDatabase 11r2 V03"},{"appid":6,"appname":"PC-DMIS","version":"14.2.728.0","displayname":"PC-DMIS 2019 R2 64-bit"},{"appid":30,"appname":"Tanium","version":"7.4.7.1179","displayname":"Tanium Client 7.4.7.1179"}]
[OK] Installed applications updated successfully!
Apps Processed: 4
Machine ID: 5792
=== STEP 7: WINRM CONFIGURATION ===
Resetting WinRM configuration...
Checking network profile...
Interface 'logon.ds.ge.com': DomainAuthenticated
Interface 'Unidentified network': Public
Checking for machine network interfaces...
Checking domain trust relationship...
[OK] Domain trust relationship is healthy
Found Public network profile(s), attempting to fix...
Restarting NLA service to detect domain...
[FAIL] Error configuring WinRM: Time out has expired and the operation has not been completed.
=== STEP 8: WINRM ADMIN GROUP ===
Configuring WinRM access groups...
Target group: logon\g03078610
Checking local Administrators group...
Current Administrators members: W9_Root, Domain Admins, S-1-5-21-3672398596-3227583511-885490141-3021858, W10_ShopAdmin, 212788513, 212718962, 210050215, 210050230, 212732582, lg044513sd, g03078399, g01127734, g01127722, DEL_GE000000000_GE001000000_WKS_ADMINS_US
Adding logon\g03078610 to Administrators...
[OK] Added logon\g03078610 to Administrators
Checking Remote Management Users group...
Current Remote Management Users members:
Adding logon\g03078610 to Remote Management Users...
[OK] Added logon\g03078610 to Remote Management Users
=== COMPLETE ASSET UPDATE SUCCESS ===
Computer: G1CXL1V3ESF
Type: CMM
Serial: 1CXL1V3
Data Collected & Stored:
[OK] Basic system information
[OK] Default printer mapping (10.80.92.65)
[OK] Application mapping (4 tracked apps)
[WARN] WinRM configuration (may need manual setup)
[OK] WinRM admin group (logon\g03078610)
[OK] Complete PC asset collection finished!
All data stored in database via dashboard API.
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
=== Script completed ===
Exit code: 0
End time: Fri 12/05/2025 10:09:49.55

View File

@@ -0,0 +1,238 @@
=====================================
Complete PC Asset Collection - Fri 12/05/2025 12:20:52.90
Computer: G1ZTNCX3ESF
User Context: lg672650sd
Script Directory: S:\DT\cameron\scan
Proxy: http://10.48.130.158/vendor-api-proxy.php
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Network Load Balancing: Disabled
=====================================
Checking for GE Aircraft Engines registry...
Backup-GERegistry.ps1 not found - skipping registry backup
=== Running PowerShell script ===
========================================
Complete PC Asset Collection & Storage
========================================
Computer: G1ZTNCX3ESF
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
Using provided URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Note: Warranty lookups disabled (handled by dashboard)
=== STEP 1: COLLECT SYSTEM INFO ===
Collecting comprehensive system information...
Domain detected: logon.ds.ge.com
[OK] Shopfloor domain detected
[OK] Keyence/Genspect software detected - Keyence PC
Skipping application detection (PC Type: Keyence)
Collecting installed applications...
Found 77 installed applications:
- Adobe Acrobat Reader DC (v15.017.20050)
- Adobe AcrobatReaderDC-Shopfloor XI V01 (vadobe_acrobatreaderdc-shopfloor_xi_v01 Build 0.0.0.0)
- Cisco PEAP Module (v1.1.6)
- Classic Shell (v4.3.1)
- Compatibility Pack for the 2007 Office system (v12.0.6021.5000)
- GE NOMSAgentServiceInstaller 1.0 V01 (vge_nomsagentserviceinstaller_1.0_v01 Build 0.0.0.0)
- GE SFLD GPOUpdate 1.0 V01 (vge_sfld-gpoupdate_1.0_v01 Build 0.0.0.0)
- GE Tanium Health Check (v1.07)
- Google Chrome (v142.0.7444.176)
- Google Chrome 50 V01 (vgoogle_chrome_50_v01 Build 0.0.0.0)
- Google Endpoint Verification (v2.11.28)
- Google Legacy Browser Support (v8.1.0.0)
- InternetExplorer-SF8 (v1.0.0)
- IvoSoft ClassicShell 4.3.1 V01 (vivosoft_classicshell_4.3.1_v01 Build 0.0.0.0)
- Japan Fonts (v2.2)
- Java 8 Update 101 (v8.0.1010.13)
- Microsoft Access Runtime 2016 (v16.0.4288.1001)
- Microsoft Access Runtime MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Edge (v142.0.3595.94)
- Microsoft Edge WebView2 Runtime (v142.0.3595.94)
- Microsoft Office 2007-2010 Compatibility Pack
- Microsoft Office 2010 Viewers (vmicrosoft_office_2010_viewers_v5 Build 1.1.0.9)
- Microsoft Office 64-bit Components 2016 (v16.0.4288.1001)
- Microsoft Office Excel Viewer (v12.0.6219.1000)
- Microsoft Office Shared 64-bit MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared 64-bit Setup Metadata MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Shared Setup Metadata MUI (English) 2016 (v16.0.4288.1001)
- Microsoft Office Word Viewer 2003 (v11.0.8173.0)
- Microsoft PowerPoint Viewer (v14.0.4763.1000)
- Microsoft Visual C++ 2010 x64 Redistributable - 10.0.40219 (v10.0.40219)
- Microsoft Visual C++ 2010 x86 Redistributable - 10.0.40219 (v10.0.40219)
- Microsoft Visual C++ 2013 Redistributable (x64) - 12.0.30501 (v12.0.30501.0)
- Microsoft Visual C++ 2013 Redistributable (x86) - 12.0.30501 (v12.0.30501.0)
- Microsoft Visual C++ 2013 x64 Additional Runtime - 12.0.21005 (v12.0.21005)
- Microsoft Visual C++ 2013 x64 Minimum Runtime - 12.0.21005 (v12.0.21005)
- Microsoft Visual C++ 2013 x86 Additional Runtime - 12.0.21005 (v12.0.21005)
- Microsoft Visual C++ 2013 x86 Minimum Runtime - 12.0.21005 (v12.0.21005)
- Microsoft Visual C++ 2017 Redistributable (x64) - 14.16.27024 (v14.16.27024.1)
- Microsoft Visual C++ 2017 Redistributable (x86) - 14.16.27033 (v14.16.27033.0)
- Microsoft Visual C++ 2017 X64 Additional Runtime - 14.16.27024 (v14.16.27024)
- Microsoft Visual C++ 2017 X64 Minimum Runtime - 14.16.27024 (v14.16.27024)
- Microsoft Visual C++ 2017 X86 Additional Runtime - 14.16.27033 (v14.16.27033)
- Microsoft Visual C++ 2017 X86 Minimum Runtime - 14.16.27033 (v14.16.27033)
- NOMS (v1.0.0)
- OpenText HostExplorer 15 x64 (v15.0.0)
- OpenText HostExplorer SP1 15.0 V01 (vopentext_hostexplorer_sp1_15.0_v01 Build 0.0.0.0)
- Oracle JavaRuntimeEnvironment 8u101 V01 (voracle_javaruntimeenvironment_8u101_v01 Build 0.0.0.0)
- RealVNC Connect 6.0.1 V03 (vrealvnc_connect_6.0.1_v03 Build 0.0.0.0)
- Security Update for Microsoft Access 2016 (KB5002720) 32-Bit Edition
- Security Update for Microsoft Excel 2016 (KB5002794) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3191869) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB3213551) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4011574) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4462148) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4475587) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4484103) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB4484432) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002058) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002112) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002341) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002573) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002575) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002576) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002616) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002719) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002757) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002766) 32-Bit Edition
- Security Update for Microsoft Office 2016 (KB5002792) 32-Bit Edition
- Security Update for Microsoft OneNote 2016 (KB5002622) 32-Bit Edition
- Security Update for Microsoft Outlook 2016 (KB5002683) 32-Bit Edition
- Security Update for Skype for Business 2016 (KB5002181) 32-Bit Edition
- Tanium Client 7.4.7.1179 (v7.4.7.1179)
- VNC Server 6.0.1 (v6.0.1.23971)
- VNC Viewer 6.0.1 (v6.0.1.23971)
- VR-6000 Series Software (v4.3.7)
- Windows Driver Package - KEYENCE VR Series USB-Driver (03/26/2020 1.0.0.0) (v03/26/2020 1.0.0.0)
Loaded 9 enabled applications from CSV
Matched: OpenText (ID:22) = OpenText HostExplorer 15 x64 v15.0.0
Skipping duplicate: OpenText (ID:22) = OpenText HostExplorer SP1 15.0 V01
Matched: Tanium (ID:30) = Tanium Client 7.4.7.1179 v7.4.7.1179
Found 2 tracked applications for database
Running processes:
AggregatorHost, amdfendrsr, armsvc, atieclxx, atiesrxx, chrome, ClassicStartMenu, cmd, conhost, cscript, csrss, ctfmon, dllhost, dwm, explorer, fontdrvhost, Idle, IntelCpHDCPSvc, ipf_helper, ipf_uf, jhi_service, LMS, lsass, Memory Compression, MpDefenderCoreService, msdtc, msedge, MsMpEng, MTA.Controller, mytechassistant, NetworkAdapterManager, NisSrv, noms_agent, OneApp.IGCC.WinService, pacjsworker, powershell, Registry, RtkAudUService64, RuntimeBroker, SearchApp, SearchIndexer, SecurityHealthService, SecurityHealthSystray, services, sihost, smartscreen, smss, spoolsv, StartMenuExperienceHost, svchost, System, TaniumClient, TaniumCX, TaniumDriverSvc, taskhostw, TbtP2pShortcutService, TextInputHost, unsecapp, vncagent, vncserver, vncserverui, WavesAudioService, WavesSvc64, WavesSysSvc64, WDTRpcServer, wininit, winlogon, wlanext, WmiPrvSE, WMIRegistrationService, WUDFHost
System Details:
Hostname: G1ZTNCX3ESF
Manufacturer: Dell Inc.
Model: OptiPlex 7000
Serial: 1ZTNCX3
PC Type: Keyence
User: lg672650sd
Memory: 15.7 GB
OS: Microsoft Windows 10 Enterprise LTSC
=== STEP 2: COLLECT SHOPFLOOR INFO ===
=== STEP 3: WARRANTY DATA ===
Warranty lookups disabled - Dashboard will handle warranty updates
PCs cannot reach proxy server from this network
=== STEP 4: STORE IN DATABASE ===
Sending complete asset data to dashboard...
Dashboard URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
No ShopfloorInfo available
No installed applications to send
[OK] Complete asset data stored in database!
PCID: Unknown
Updated/Created: Unknown
Records affected: Unknown
=== STEP 5: PRINTER MAPPING ===
Collecting default printer information...
Default Printer: WJWT05-HP-Laserjet
Port Name: 10.80.92.67
[OK] Network printer detected - will send to database
Sending printer mapping to dashboard...
Hostname: G1ZTNCX3ESF
Printer FQDN: 10.80.92.67
DEBUG Response: {"success":true,"message":"Printer mapping updated","printerId":9,"machinesUpdated":1,"matchMethod":"ip"}
[OK] Printer mapping updated successfully!
Printer ID:
Machines Updated:
Match Method:
=== STEP 6: APPLICATION MAPPING ===
Sending tracked applications to dashboard...
Hostname: G1ZTNCX3ESF
Tracked Apps: 2
-> appid=22, appname='OpenText', version='15.0.0'
-> appid=30, appname='Tanium', version='7.4.7.1179'
DEBUG JSON: [{"appid":22,"appname":"OpenText","version":"15.0.0","displayname":"OpenText HostExplorer 15 x64"},{"appid":30,"appname":"Tanium","version":"7.4.7.1179","displayname":"Tanium Client 7.4.7.1179"}]
[OK] Installed applications updated successfully!
Apps Processed: 2
Machine ID: 5807
=== STEP 7: WINRM CONFIGURATION ===
Resetting WinRM configuration...
Checking network profile...
Interface 'logon.ds.ge.com': DomainAuthenticated
Checking for machine network interfaces...
Checking domain trust relationship...
[OK] Domain trust relationship is healthy
[OK] All network profiles are Private/Domain
Stopping WinRM service...
WinRM service stopped
Removing existing WinRM listeners...
Existing listeners removed
Starting WinRM service...
WinRM service started and set to Automatic
Running WinRM quickconfig...
WinRM quickconfig completed
Creating HTTP listener on port 5985...
HTTP listener already exists
Configuring WinRM authentication settings...
Auth: Basic=false, Negotiate=true, Kerberos=true, CredSSP=false
WARNING: The updated configuration might affect the operation of the plugins having a per plugin quota value greater
than 1024. Verify the configuration of all the registered plugins and change the per plugin quota values for the
affected plugins.
MaxMemoryPerShellMB set to 1024
Enabling LocalAccountTokenFilterPolicy...
LocalAccountTokenFilterPolicy enabled
Configuring WinRM security descriptor...
Current SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
PSRemoting enabled
Restarting WinRM service to apply changes...
WinRM service restarted
Configuring firewall rule...
Firewall rule 'Windows Remote Management (HTTP-In)' enabled
Verifying WinRM listener...
[OK] WinRM HTTP listener configured on port 5985
[OK] Port 5985 is listening
=== STEP 8: WINRM ADMIN GROUP ===
Configuring WinRM access groups...
Target group: logon\g03078610
Checking local Administrators group...
Current Administrators members: W9_Root, Domain Admins, 503432774, g01127734, g01127722, DEL_GE000000000_GE001000000_WKS_ADMINS_US, W10_ShopAdmin
Adding logon\g03078610 to Administrators...
[OK] Added logon\g03078610 to Administrators
Checking Remote Management Users group...
Current Remote Management Users members:
Adding logon\g03078610 to Remote Management Users...
[OK] Added logon\g03078610 to Remote Management Users
=== COMPLETE ASSET UPDATE SUCCESS ===
Computer: G1ZTNCX3ESF
Type: Keyence
Serial: 1ZTNCX3
Data Collected & Stored:
[OK] Basic system information
[OK] Default printer mapping (10.80.92.67)
[OK] Application mapping (2 tracked apps)
[OK] WinRM HTTP listener (port 5985)
Note: If remote access still fails, a reboot may be required
[OK] WinRM admin group (logon\g03078610)
[OK] Complete PC asset collection finished!
All data stored in database via dashboard API.
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
=== Script completed ===
Exit code: 0
End time: Fri 12/05/2025 12:21:17.60

View File

@@ -0,0 +1,360 @@
=====================================
Complete PC Asset Collection - Fri 12/05/2025 13:29:36.45
Computer: G3ZL4SZ2ESF
User Context: lg672650sd
Script Directory: S:\DT\cameron\scan
Proxy: http://10.48.130.158/vendor-api-proxy.php
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Network Load Balancing: Disabled
=====================================
Checking for GE Aircraft Engines registry...
Backup-GERegistry.ps1 not found - skipping registry backup
=== Running PowerShell script ===
========================================
Complete PC Asset Collection & Storage
========================================
Computer: G3ZL4SZ2ESF
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
Using provided URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Dashboard: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
Note: Warranty lookups disabled (handled by dashboard)
=== STEP 1: COLLECT SYSTEM INFO ===
Collecting comprehensive system information...
Domain detected: logon.ds.ge.com
[OK] Shopfloor domain detected
[OK] Keyence/Genspect software detected - Keyence PC
Skipping application detection (PC Type: Keyence)
Collecting installed applications...
Found 194 installed applications:
- 64 Bit HP CIO Components Installer (v13.2.1)
- Adobe Acrobat Reader DC (v15.017.20050)
- Adobe AcrobatReaderDC-Shopfloor XI V01 (vadobe_acrobatreaderdc-shopfloor_xi_v01 Build 0.0.0.0)
- Adobe Flash Player 32 PPAPI (v32.0.0.387)
- BIG-IP Edge Client (v71.2019.0119.0331)
- BIG-IP Edge Client Components (All Users) (v71.2019.0119.0331)
- Cisco PEAP Module (v1.1.6)
- Classic Shell (v4.3.1)
- Compatibility Pack for the 2007 Office system (v12.0.6021.5000)
- CrowdStrike Device Control (v7.29.20167.0)
- CrowdStrike Firmware Analysis (v7.14.18456.0)
- CrowdStrike Sensor Platform (v7.29.20108.0)
- CrowdStrike Windows Sensor (v7.29.20108.0)
- DynaComware JapanFonts 2.20 V01 (vdynacomware_japanfonts_2.20_v01 Build 0.0.0.0)
- eDNC 6.1.4 (v6.1.4)
- GageCal
- GE InspiraFonts2017 April 1.0 V02 (vge_inspirafonts2017_april_1.0_v02 Build 0.0.0.0)
- GE NOMSAgentServiceInstaller 1.0 V01 (vge_nomsagentserviceinstaller_1.0_v01 Build 0.0.0.0)
- GE SFLD GPOUpdate 1.0 V01 (vge_sfld-gpoupdate_1.0_v01 Build 0.0.0.0)
- GE Tanium Health Check (v1.07)
- Genspect 2.5.31
- Genspect 2.5.31 (C:\Program Files (x86)\Genspect\)
- Genspect 2.5.31 (C:\Program Files (x86)\Genspect\) #3
- Google Chrome (v142.0.7444.176)
- Google Chrome 50 V01 (vgoogle_chrome_50_v01 Build 0.0.0.0)
- Google Chrome 73 V01 (vgoogle_chrome_73_v01 Build 0.0.0.0)
- InternetExplorer-SF8 (v1.0.0)
- IvoSoft ClassicShell 4.3.1 V01 (vivosoft_classicshell_4.3.1_v01 Build 0.0.0.0)
- Japan Fonts (v2.2)
- Java 8 Update 101 (v8.0.1010.13)
- MarkDNC 6.0.0 (v6.0.0)
- MarkEdit (v3.00.01)
- Microsoft Access Runtime 2010 (v14.0.7015.1000)
- Microsoft Office 2007-2010 Compatibility Pack
- Microsoft Office 2010 Viewers (vmicrosoft_office_2010_viewers_v5 Build 1.1.0.9)
- Microsoft Office Access Runtime 2010 (v14.0.7015.1000)
- Microsoft Office Access Runtime MUI (English) 2010 (v14.0.7015.1000)
- Microsoft Office Excel Viewer (v12.0.6612.1000)
- Microsoft Office Office 64-bit Components 2010 (v14.0.7015.1000)
- Microsoft Office Shared 64-bit MUI (English) 2010 (v14.0.7015.1000)
- Microsoft Office Shared 64-bit Setup Metadata MUI (English) 2010 (v14.0.7015.1000)
- Microsoft Office Shared MUI (English) 2010 (v14.0.7015.1000)
- Microsoft Office Shared Setup Metadata MUI (English) 2010 (v14.0.7015.1000)
- Microsoft Office Word Viewer 2003 (v11.0.8173.0)
- Microsoft PowerPoint Viewer (v14.0.7015.1000)
- Microsoft Visual C++ 2005 Redistributable (v8.0.61001)
- Microsoft Visual C++ 2010 x64 Redistributable - 10.0.40219 (v10.0.40219)
- Microsoft Visual C++ 2010 x86 Redistributable - 10.0.40219 (v10.0.40219)
- Microsoft Visual C++ 2015 Redistributable (x64) - 14.0.23506 (v14.0.23506.0)
- Microsoft Visual C++ 2015 Redistributable (x86) - 14.0.23506 (v14.0.23506.0)
- Microsoft Visual C++ 2015 Run-Time (v14.0.23509)
- Microsoft Visual C++ 2015 x64 Additional Runtime - 14.0.23506 (v14.0.23506)
- Microsoft Visual C++ 2015 x64 Minimum Runtime - 14.0.23506 (v14.0.23506)
- Microsoft Visual C++ 2015 x86 Additional Runtime - 14.0.23506 (v14.0.23506)
- Microsoft Visual C++ 2015 x86 Minimum Runtime - 14.0.23506 (v14.0.23506)
- National Instruments Software
- NI Atomic PXIe Peripheral Module Driver 16.0.0 (v16.00.49152)
- NI Certificates 1.0.7 (v1.07.49153)
- NI Controller Driver 16.0 (v16.00.49152)
- NI Controller Driver 16.0 64-bit (v16.00.49152)
- NI Curl 16.0.0 (64-bit) (v16.0.100)
- NI Curl 2016 (v16.0.100)
- NI Error Reporting Interface 16.0 (v16.0.203)
- NI Error Reporting Interface 16.0 for Windows (64-bit) (v16.0.203)
- NI Ethernet Device Enumerator (v1.01.49152)
- NI Ethernet Device Enumerator 64-Bit (v1.01.49152)
- NI EulaDepot (v16.0.30)
- NI LabVIEW C Interface (v1.0.1)
- NI MDF Support (v16.0.180)
- NI mDNS Responder 16.0 for Windows 64-bit (v16.00.49152)
- NI mDNS Responder 16.0.0 (v16.00.49152)
- NI MXI Manager 16.0 (v16.00.49152)
- NI MXI Manager 16.0 64-bit (v16.00.49152)
- NI MXS 16.0.0 (v16.00.49152)
- NI MXS 16.0.0 for 64 Bit Windows (v16.00.49152)
- NI Physical Interface Extension Installer 15.0.0 (v15.00.49152)
- NI Physical Interface Extension Installer for 64-bit 15.0.0 (v15.00.49152)
- NI Portable Configuration 16.0.0 (v16.00.49152)
- NI Portable Configuration for 64 Bit Windows 16.0.0 (v16.00.49152)
- NI PXI Platform Framework 16.0.0 (v16.00.49152)
- NI PXI Platform Framework 16.0.0 64-bit (v16.00.49152)
- NI PXI Platform Services 16.0 Expert (v16.00.49152)
- NI PXI Platform Services Runtime 16.0 (v16.00.49152)
- NI PXI Platform Services Runtime 16.0 64-bit (v16.00.49152)
- NI RTSI Cable Core Installer 15.5.0 (v15.50.49152)
- NI RTSI Cable Core Installer for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI RTSI PAL Device Library Installer 15.5.0 (v15.50.49152)
- NI RTSI PAL Device Library Installer for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI Security Update (KB 67L8LCQW) (v1.0.29.0)
- NI Security Update (KB 67L8LCQW) (64-bit) (v1.0.29.0)
- NI Service Locator 2016 (v16.0.150)
- NI SSL Support (v16.0.181)
- NI SSL Support (64-bit) (v16.0.181)
- NI System API Windows 32-bit 16.0.0 (v16.0.183)
- NI System API Windows 64-bit 16.0.0 (v16.0.183)
- NI System Monitor 16.0 (v16.00.49152)
- NI System Monitor 16.0 64-bit (v16.00.49152)
- NI Uninstaller (v16.0.180)
- NI VC2008MSMs x64 (v9.0.401)
- NI VC2008MSMs x86 (v9.0.401)
- NI Xerces Delay Load 2.7.7 (v2.7.237)
- NI Xerces Delay Load 2.7.7 64-bit (v2.7.247)
- NI-APAL 15.1 64-Bit Error Files (v15.10.49152)
- NI-APAL 15.1 Error Files (v15.10.49152)
- NI-DAQmx 16.0.1 (v16.01.49152)
- NI-DAQmx 653x Installer 14.5.0 (v14.50.49152)
- NI-DAQmx 653x Installer for 64 Bit Windows 14.5.0 (v14.50.49152)
- NI-DAQmx Common Digital 15.5.0 (v15.50.49152)
- NI-DAQmx Common Digital for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx Dynamic Signal Acquisition for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx Dynamic Signal Acquisition Installer 15.5.0 (v15.50.49152)
- NI-DAQmx FSL Installer 15.5.0 (v15.50.49152)
- NI-DAQmx FSL Installer for 64-Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx MIO Device Drivers 16.0.1 (v16.01.49153)
- NI-DAQmx MIO Device Drivers for 64 Bit Windows 16.0.1 (v16.01.49153)
- NI-DAQmx MX Expert Framework 16.0.0 (v16.00.49152)
- NI-DAQmx MX Expert Framework for 64 Bit Windows 16.0.0 (v16.00.49152)
- NI-DAQmx Remote Service 16.0.0 (v16.00.49152)
- NI-DAQmx Remote Service 64-bit 16.0.0 64-bit (v16.00.49152)
- NI-DAQmx SCXI 15.5.0 (v15.50.49152)
- NI-DAQmx SCXI for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx STC 15.5.0 (v15.50.49152)
- NI-DAQmx STC for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx Switch Core 15.1.0 (v15.10.49152)
- NI-DAQmx Switch Core for 64 Bit Windows 15.1.0 (v15.10.49152)
- NI-DAQmx Timing for 64 Bit Windows 15.5.0 (v15.50.49152)
- NI-DAQmx Timing Installer 15.5.0 (v15.50.49152)
- NI-DIM 16.0.0 (v16.00.49152)
- NI-DIM 16.0.0 for 64-bit Windows (v16.00.49152)
- NI-MDBG 16.0.0f0 (v16.00.49152)
- NI-MDBG 16.0.0f0 for 64 Bit Windows (v16.00.49152)
- NI-MRU 16.0.0 (v16.00.49152)
- NI-MRU 16.0.0 for 64-bit Windows (v16.00.49152)
- NI-MXDF 16.0.0f0 (v16.00.49152)
- NI-MXDF 16.0.0f0 for 64 Bit Windows (v16.00.49152)
- NI-MXLC Core (32-bit) (v16.0.34)
- NI-MXLC Core (64-bit) (v16.0.34)
- NI-ORB 16.0 (v16.00.49152)
- NI-ORB 16.0 for 64-bit Windows (v16.00.49152)
- NI-PAL 16.0 64-Bit Error Files (v16.00.49153)
- NI-PAL 16.0 Error Files (v16.00.49153)
- NI-PAL 16.0.0f1 (v16.00.49153)
- NI-PAL 16.0.0f1 for 64 Bit Windows (v16.00.49153)
- NI-PCI Bridge Driver 16.0 (v16.00.49152)
- NI-PCI Bridge Driver 16.0 64-bit (v16.00.49152)
- NI-PXIPF Error 15.0.5 (v15.05.49152)
- NI-PXIPF Error 15.0.5 for 64-bit Windows (v15.05.49152)
- NI-QPXI 16.0.0 (v16.00.49152)
- NI-QPXI 16.0.0 for 64-bit Windows (v16.00.49152)
- NI-RIO USBLAN 16.0 (v16.00.49152)
- NI-RIO USBLAN 16.0 (64-bit) (v16.00.49152)
- NI-RoCo Error Files 16.0.0 (v16.00.49152)
- NI-ROCO Error Files 16.0.0 for 64-bit Windows (v16.00.49152)
- NI-RPC 16.0.0f0 (v16.00.49152)
- NI-RPC 16.0.0f0 for 64 Bit Windows (v16.00.49152)
- NI-RPC 16.0.0f0 for Phar Lap ETS (v16.00.49152)
- NI-Xlator 16.0.0f0 (v16.00.49152)
- NI-Xlator 16.0.0f0 for 64 Bit Windows (v16.00.49152)
- NOMS (v1.0.0)
- OpenText Host Explorer - ShopFloor 15 SP1 V01 (vopentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0)
- OpenText HostExplorer 15 x64 (v15.0.1)
- OpenText HostExplorer SP1 15.0 V01 (vopentext_hostexplorer_sp1_15.0_v01 Build 0.0.0.0)
- Oracle JavaRuntimeEnvironment 8u101 V01 (voracle_javaruntimeenvironment_8u101_v01 Build 0.0.0.0)
- Oracle OracleDatabase 11r2 V03 (voracle_oracledatabase_11r2_v03 Build 0.0.0.0)
- PCIe to Peripheral Adaptor (v3.0.0.0)
- RealVNC Connect 6.0.1 V03 (vrealvnc_connect_6.0.1_v03 Build 0.0.0.0)
- Security Update for Microsoft Access 2010 (KB4484385) 32-Bit Edition
- Security Update for Microsoft Excel 2010 (KB3017810) 32-Bit Edition
- Security Update for Microsoft InfoPath 2010 (KB3114414) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2553154) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2553313) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2553332) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2850016) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2880971) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2881029) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB2956076) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB3114565) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB3213626) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB3213631) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB3213636) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB4011610) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB4484455) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB4493143) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB4504738) 32-Bit Edition
- Security Update for Microsoft Office 2010 (KB4504739) 32-Bit Edition
- Security Update for Microsoft OneNote 2010 (KB3114885) 32-Bit Edition
- Service Pack 2 for Microsoft Office 2010 (KB2687455) 32-Bit Edition
- Splunk UniversalForwarder-Vault 6.3.5-x64 V01 (vsplunk_universalforwarder-vault_6.3.5-x64_v01 Build 0.0.0.0)
- Tanium Client 7.4.7.1179 (v7.4.7.1179)
- UniversalForwarder (v6.3.5.0)
- Update for Microsoft Office 2010 (KB2553347) 32-Bit Edition
- VNC Server 6.0.1 (v6.0.1.23971)
- VNC Viewer 6.0.1 (v6.0.1.23971)
- Vulkan Run Time Libraries 1.0.65.1 (v1.0.65.1)
Loaded 9 enabled applications from CSV
Matched: eDNC (ID:8) = eDNC 6.1.4 v6.1.4
Matched: OpenText (ID:22) = OpenText Host Explorer - ShopFloor 15 SP1 V01 vopentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0
Skipping duplicate: OpenText (ID:22) = OpenText HostExplorer 15 x64
Skipping duplicate: OpenText (ID:22) = OpenText HostExplorer SP1 15.0 V01
Matched: Oracle (ID:7) = Oracle OracleDatabase 11r2 V03 voracle_oracledatabase_11r2_v03 Build 0.0.0.0
Matched: Tanium (ID:30) = Tanium Client 7.4.7.1179 v7.4.7.1179
Found 4 tracked applications for database
Running processes:
armsvc, backgroundTaskHost, chrome, ClassicStartMenu, cmd, conhost, cscript, CSFalconContainer, CSFalconService, csrss, dllhost, dwm, explorer, F5CredMgrSrv, F5FltSrv, F5InstallerService, F5TrafficSrv, Idle, igfxCUIService, igfxEM, IntelCpHDCPSvc, IntelCpHeciSvc, lsass, Memory Compression, MpCmdRun, MSASCuiL, msdtc, MsMpEng, MyTech.AssetAgent, NetworkAdapterManager, niDAQmxRemoteService, nidevldu, nimdnsResponder, nimxs, nipxism, NisSrv, nisvcloc, noms_agent, powershell, PresentationFontCache, proxyhelper, RemindersServer, RuntimeBroker, SchTasks, SearchFilterHost, SearchIndexer, SearchProtocolHost, SearchUI, services, sfc, ShellExperienceHost, sihost, smartscreen, smss, splunkd, splunk-winevtlog, spoolsv, svchost, System, TaniumClient, TaniumCX, TaniumDriverSvc, taskhostw, TiWorker, TrustedInstaller, vncagent, vncserver, vncserverui, WavesSysSvc64, wermgr, wininit, winlogon, wlanext, WmiPrvSE, WUDFHost
System Details:
Hostname: G3ZL4SZ2ESF
Manufacturer: Dell Inc.
Model: OptiPlex 5060
Serial: 3ZL4SZ2
PC Type: Keyence
User: lg672650sd
Machine No: 0600
Memory: 7.8 GB
OS: Microsoft Windows 10 Enterprise 2016 LTSB
=== STEP 2: COLLECT SHOPFLOOR INFO ===
=== STEP 3: WARRANTY DATA ===
Warranty lookups disabled - Dashboard will handle warranty updates
PCs cannot reach proxy server from this network
=== STEP 4: STORE IN DATABASE ===
Sending complete asset data to dashboard...
Dashboard URL: https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp
No ShopfloorInfo available
No installed applications to send
[OK] Complete asset data stored in database!
PCID: Unknown
Updated/Created: Unknown
Records affected: Unknown
=== STEP 5: PRINTER MAPPING ===
Collecting default printer information...
No default printer found or no port available
No printer FQDN to send - skipping printer mapping
=== STEP 6: APPLICATION MAPPING ===
Sending tracked applications to dashboard...
Hostname: G3ZL4SZ2ESF
Tracked Apps: 4
-> appid=8, appname='eDNC', version='6.1.4'
-> appid=22, appname='OpenText', version='opentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0'
-> appid=7, appname='Oracle', version='oracle_oracledatabase_11r2_v03 Build 0.0.0.0'
-> appid=30, appname='Tanium', version='7.4.7.1179'
DEBUG JSON: [{"appid":8,"appname":"eDNC","version":"6.1.4","displayname":"eDNC 6.1.4"},{"appid":22,"appname":"OpenText","version":"opentext_hostexplorer-shopfloor_15sp1_v01 Build 0.0.0.0","displayname":"OpenText Host Explorer - ShopFloor 15 SP1 V01"},{"appid":7,"appname":"Oracle","version":"oracle_oracledatabase_11r2_v03 Build 0.0.0.0","displayname":"Oracle OracleDatabase 11r2 V03"},{"appid":30,"appname":"Tanium","version":"7.4.7.1179","displayname":"Tanium Client 7.4.7.1179"}]
[OK] Installed applications updated successfully!
Apps Processed: 4
Machine ID: 5781
=== STEP 7: WINRM CONFIGURATION ===
Resetting WinRM configuration...
Checking network profile...
Interface 'logon.ds.ge.com': DomainAuthenticated
Checking for machine network interfaces...
Checking domain trust relationship...
[OK] Domain trust relationship is healthy
[OK] All network profiles are Private/Domain
Stopping WinRM service...
WinRM service stopped
Removing existing WinRM listeners...
Existing listeners removed
Starting WinRM service...
WinRM service started and set to Automatic
Running WinRM quickconfig...
WinRM quickconfig completed
Creating HTTP listener on port 5985...
HTTP listener already exists
Configuring WinRM authentication settings...
Auth: Basic=false, Negotiate=true, Kerberos=true, CredSSP=false
WARNING: The updated configuration might affect the operation of the plugins having a per plugin quota value greater
than 1024. Verify the configuration of all the registered plugins and change the per plugin quota values for the
affected plugins.
MaxMemoryPerShellMB set to 1024
Enabling LocalAccountTokenFilterPolicy...
LocalAccountTokenFilterPolicy enabled
Configuring WinRM security descriptor...
Current SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
WARNING: Waiting for service 'Windows Remote Management (WS-Management) (winrm)' to stop...
PSRemoting enabled
Restarting WinRM service to apply changes...
WinRM service restarted
Configuring firewall rule...
Firewall rule 'Windows Remote Management (HTTP-In)' enabled
Verifying WinRM listener...
[OK] WinRM HTTP listener configured on port 5985
[OK] Port 5985 is listening
=== STEP 8: WINRM ADMIN GROUP ===
Configuring WinRM access groups...
Target group: logon\g03078610
Checking local Administrators group...
Current Administrators members: W9_Root, Domain Admins, 212788513, g01127734, g01127722, DEL_GE000000000_GE001000000_WKS_ADMINS_US, W10_ShopAdmin, DEL_GE000000000_GE006000000_WKS_ADMINS_US, g01127752, g01127746
Adding logon\g03078610 to Administrators...
[OK] Added logon\g03078610 to Administrators
Checking Remote Management Users group...
Current Remote Management Users members:
Adding logon\g03078610 to Remote Management Users...
[OK] Added logon\g03078610 to Remote Management Users
=== COMPLETE ASSET UPDATE SUCCESS ===
Computer: G3ZL4SZ2ESF
Type: Keyence
Serial: 3ZL4SZ2
Machine: 0600
Data Collected & Stored:
[OK] Basic system information
[--] Default printer mapping (no printer found)
[OK] Application mapping (4 tracked apps)
[OK] WinRM HTTP listener (port 5985)
Note: If remote access still fails, a reboot may be required
[OK] WinRM admin group (logon\g03078610)
[OK] Complete PC asset collection finished!
All data stored in database via dashboard API.
Log file: S:\DT\cameron\scan\logs\Update-PC-CompleteAsset-2025-12-05.log
=== Script completed ===
Exit code: 0
End time: Fri 12/05/2025 13:37:02.06

Some files were not shown because too many files have changed in this diff Show More