diff --git a/agent/ajax.php b/agent/ajax.php
index ba6962307..8cd109b15 100644
--- a/agent/ajax.php
+++ b/agent/ajax.php
@@ -181,8 +181,8 @@ if (isset($_POST['tag_picker_set']) || isset($_POST['tag_picker_create'])) {
/*
* Quick pickers (js/quick_pick.js) - a ticket's status, priority, assignee
- * and billable, a project's manager and a recurring ticket's assignee,
- * changed in place instead of through a modal. GET lists the choices; POST makes the change through the same
+ * and billable, a project's manager, a recurring ticket's assignee and an
+ * asset's status, location and contact, changed in place instead of through a modal. GET lists the choices; POST makes the change through the same
* functions the post.php handlers use (functions/ticket_fields.php) and sends
* back the redrawn values.
*/
@@ -210,6 +210,14 @@ if (isset($_GET['quick_pick_options'])) {
$options = quickPickAgents();
} elseif ($field === 'project_manager') {
$options = quickPickAgents('No manager');
+ } elseif (in_array($field, ASSET_QUICK_FIELDS, true)) {
+ // Locations and contacts are the asset's client's own - functions/asset.php
+ $options = assetQuickOptions($field, intval($_GET['scope'] ?? 0));
+ if ($options === null) {
+ http_response_code(403);
+ echo json_encode(['error' => 'You cannot see that client.']);
+ exit();
+ }
} else {
http_response_code(400);
echo json_encode(['error' => 'Unknown field']);
@@ -230,6 +238,40 @@ if (isset($_POST['quick_pick_set'])) {
$value = (string) ($_POST['value'] ?? '');
$ticket_ids = array_values(array_unique(array_filter(array_map('intval', (array) ($_POST['ids'] ?? [])))));
+ // An asset's status, location or contact - assets of clients this agent
+ // can reach, with the same permission as Edit Asset (functions/asset.php)
+ if (in_array($field, ASSET_QUICK_FIELDS, true)) {
+ $asset_ids = $ticket_ids;
+ $allowed = lookupUserPermission('module_support') >= 2 && $asset_ids;
+ foreach ($allowed ? $asset_ids : [] as $id) {
+ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT asset_client_id FROM assets WHERE asset_id = $id"));
+ if (!$row || !hasClientAccess($row['asset_client_id'])) {
+ $allowed = false;
+ break;
+ }
+ }
+ if (!$allowed) {
+ http_response_code(403);
+ echo json_encode(['error' => 'You cannot change that on these assets.']);
+ exit();
+ }
+
+ $message = '';
+ $response = ['records' => []];
+ foreach ($asset_ids as $id) {
+ [$ok, $message] = assetQuickSet($id, $field, $value);
+ if (!$ok) {
+ http_response_code(422);
+ echo json_encode(['error' => $message]);
+ exit();
+ }
+ $response['records'][$id] = assetQuickRecord($id, $field);
+ }
+ $response['message'] = count($asset_ids) === 1 ? $message : 'Updated ' . count($asset_ids) . ' assets';
+ echo json_encode($response);
+ exit();
+ }
+
// A project's manager or a recurring ticket's assignee - open projects
// and recurring tickets of clients this agent can reach, like their edit modals
if ($field === 'project_manager' || $field === 'recurring_assignee') {
diff --git a/agent/asset.php b/agent/asset.php
index 4a68bc74c..a698d806e 100644
--- a/agent/asset.php
+++ b/agent/asset.php
@@ -29,13 +29,13 @@ enforceUserPermission('module_support');
$asset_id = intval($_GET['asset_id'] ?? 0);
-$sql = mysqli_query($mysqli, "SELECT asset_archived_at, asset_contact_id, asset_created_at, asset_description, asset_favorite, asset_id,
+$sql = mysqli_query($mysqli, "SELECT asset_archived_at, asset_client_id, asset_contact_id, asset_created_at, asset_description, asset_favorite, asset_id,
asset_install_date, asset_location_id, asset_make, asset_model, asset_name, asset_notes,
asset_os, asset_photo, asset_physical_location, asset_purchase_date,
asset_purchase_reference, asset_serial, asset_status, asset_type, asset_uri, asset_uri_2,
asset_uri_client, asset_vendor_id, asset_warranty_expire, client_id, client_name,
contact_archived_at, contact_email, contact_extension, contact_mobile,
- contact_mobile_country_code, contact_name, contact_phone, contact_phone_country_code,
+ contact_mobile_country_code, contact_name, contact_phone, contact_phone_country_code, contact_photo,
interface_ip, interface_ipv6, interface_mac, interface_nat_ip, interface_network_id,
location_archived_at, location_name, network_name, vendor_name FROM assets
LEFT JOIN clients ON client_id = asset_client_id
@@ -57,6 +57,7 @@ if (mysqli_num_rows($sql) == 0) {
} else {
$row = mysqli_fetch_assoc($sql);
+ $asset_row = $row; // raw, for the quick pickers - $row gets reused below
$client_id = intval($row['client_id']);
$client_name = escapeHtml($row['client_name']);
$asset_id = intval($row['asset_id']);
@@ -95,10 +96,6 @@ if (mysqli_num_rows($sql) == 0) {
$vendor_name = escapeHtml($row['vendor_name']);
$contact_name = escapeHtml($row['contact_name']);
- $contact_email = escapeHtml($row['contact_email']);
- $contact_phone = escapeHtml(formatPhoneNumber($row['contact_phone'], $row['contact_phone_country_code']));
- $contact_extension = escapeHtml($row['contact_extension']);
- $contact_mobile = escapeHtml(formatPhoneNumber($row['contact_mobile'], $row['contact_mobile_country_code']));
$contact_archived = !empty($row['contact_archived_at']);
$location_name = escapeHtml($row['location_name']);
$location_archived = !empty($row['location_archived_at']);
@@ -312,7 +309,11 @@ if (mysqli_num_rows($sql) == 0) {
= $asset_name ?>
Archived
- = $asset_status_pill ?>
+
+ = quickPick('asset_status', $asset_id, (string) $asset_row['asset_status'], assetQuickHtml('asset_status', $asset_row), 'list', 0, $client_id) ?>
+
+ = $asset_status_pill ?>
+
= $asset_type ?>
@@ -511,7 +512,9 @@ if (mysqli_num_rows($sql) == 0) {
- Location
-
-
+
+ = quickPick('asset_location', $asset_id, (string) intval($asset_row['asset_location_id']), assetQuickHtml('asset_location', $asset_row, 'detail'), 'detail', 0, $client_id) ?>
+
>= $location_name ?>
-
@@ -526,20 +529,15 @@ if (mysqli_num_rows($sql) == 0) {
- Assigned
-
-
+
+ = quickPick('asset_contact', $asset_id, (string) $asset_contact_id, assetQuickHtml('asset_contact', $asset_row, 'detail'), 'detail', 0, $client_id) ?>
+
>= $contact_name ?>
-
-
-
-
-
= $contact_phone ?>= $contact_extension ? " x$contact_extension" : '' ?>
-
-
- = $contact_mobile ?>
-
Nobody
+
+ = assetContactDetails($asset_row) ?>
diff --git a/agent/assets.php b/agent/assets.php
index fc3e4ea56..2ea142fda 100644
--- a/agent/assets.php
+++ b/agent/assets.php
@@ -51,7 +51,8 @@ $asset_type_tabs = [
'server' => ['label' => 'Servers', 'icon' => 'fa-server', 'query' => "asset_type = 'Server'"],
'virtual' => ['label' => 'Virtual', 'icon' => 'fa-cloud', 'query' => "asset_type = 'Virtual Machine'"],
'network' => ['label' => 'Network', 'icon' => 'fa-network-wired', 'query' => "asset_type IN ('Firewall/Router', 'Switch', 'Access Point')"],
- 'other' => ['label' => 'Other', 'icon' => 'fa-tag', 'query' => "asset_type NOT IN ('Desktop', 'Laptop', 'Server', 'Virtual Machine', 'Firewall/Router', 'Switch', 'Access Point')"],
+ 'printer' => ['label' => 'Printers', 'icon' => 'fa-print', 'query' => "asset_type = 'Printer'"],
+ 'other' => ['label' => 'Other', 'icon' => 'fa-tag', 'query' => "asset_type NOT IN ('Desktop', 'Laptop', 'Server', 'Virtual Machine', 'Firewall/Router', 'Switch', 'Access Point', 'Printer')"],
];
$type_filter = (isset($_GET['type']) && isset($asset_type_tabs[$_GET['type']])) ? $_GET['type'] : '';
$_GET['type'] = $type_filter;
@@ -113,8 +114,8 @@ $show_purchase = in_array('Purchase_Date', $extra_columns, true);
$show_install = in_array('Install_Date', $extra_columns, true);
$show_warranty = in_array('Warranty_Expire', $extra_columns, true);
-// Assigned To only means something for workstations and the like
-$show_contact = !in_array($type_filter, ['network', 'server', 'other'], true);
+// Assigned To only means something for workstations and the like - printers are shared
+$show_contact = !in_array($type_filter, ['network', 'server', 'printer', 'other'], true);
$show_model = $type_filter !== 'virtual';
// Only these sort - filter_header.php will hand through any lowercase word, and
@@ -138,7 +139,8 @@ $row = mysqli_fetch_assoc(mysqli_query($mysqli, "
SUM(asset_type = 'Server') AS server_count,
SUM(asset_type = 'Virtual Machine') AS virtual_count,
SUM(asset_type IN ('Firewall/Router', 'Switch', 'Access Point')) AS network_count,
- SUM(asset_type NOT IN ('Laptop', 'Desktop', 'Server', 'Virtual Machine', 'Firewall/Router', 'Switch', 'Access Point')) AS other_count
+ SUM(asset_type = 'Printer') AS printer_count,
+ SUM(asset_type NOT IN ('Laptop', 'Desktop', 'Server', 'Virtual Machine', 'Firewall/Router', 'Switch', 'Access Point', 'Printer')) AS other_count
FROM assets
LEFT JOIN clients ON client_id = asset_client_id
WHERE $archive_query
@@ -152,16 +154,17 @@ $tab_counts = [
'server' => intval($row['server_count']),
'virtual' => intval($row['virtual_count']),
'network' => intval($row['network_count']),
+ 'printer' => intval($row['printer_count']),
'other' => intval($row['other_count']),
];
$sql = mysqli_query(
$mysqli,
- "SELECT SQL_CALC_FOUND_ROWS asset_archived_at, asset_contact_id, asset_description, asset_favorite,
- asset_id, asset_install_date, asset_make, asset_model, asset_name, asset_os, asset_physical_location,
+ "SELECT SQL_CALC_FOUND_ROWS asset_archived_at, asset_client_id, asset_contact_id, asset_description, asset_favorite,
+ asset_id, asset_install_date, asset_location_id, asset_make, asset_model, asset_name, asset_os, asset_physical_location,
asset_purchase_date, asset_serial, asset_status, asset_type, asset_uri, asset_uri_2,
asset_uri_client, asset_warranty_expire, client_id, client_name,
- contact_archived_at, contact_name, interface_ip, interface_ipv6, interface_mac,
+ contact_archived_at, contact_name, contact_photo, interface_ip, interface_ipv6, interface_mac,
location_archived_at, location_name FROM assets
LEFT JOIN clients ON asset_client_id = client_id
LEFT JOIN contacts ON asset_contact_id = contact_id
@@ -653,7 +656,9 @@ $search_noun = $type_filter ? $asset_type_tabs[$type_filter]['label'] : 'assets'
-
+
+ = quickPick('asset_contact', $asset_id, (string) $asset_contact_id, assetQuickHtml('asset_contact', $row), 'list', 0, $client_id) ?>
+
>= $contact_name ?>
-
@@ -661,21 +666,29 @@ $search_noun = $type_filter ? $asset_type_tabs[$type_filter]['label'] : 'assets'
|
-
+
+ = quickPick('asset_location', $asset_id, (string) intval($row['asset_location_id']), assetQuickHtml('asset_location', $row), 'list', 0, $client_id) ?>
+
>= $location_name ?>
-
- = $asset_physical_location ?>
+ = $asset_physical_location ?>
-
+
= escapeHtml($asset_rack['rack_name']) ?> · = rackPositionLabel($asset_rack['unit_start_number'], $asset_rack['unit_end_number']) ?>
|
- = $asset_status_pill ?: '-' ?> |
+
+
+ = quickPick('asset_status', $asset_id, (string) $row['asset_status'], assetQuickHtml('asset_status', $row), 'list', 0, $client_id) ?>
+
+ = $asset_status_pill ?: '-' ?>
+
+ |
= $client_name ?> |
diff --git a/agent/modals/asset/asset.php b/agent/modals/asset/asset.php
index 2684fa00d..0d0f6a661 100644
--- a/agent/modals/asset/asset.php
+++ b/agent/modals/asset/asset.php
@@ -1,21 +1,29 @@
'That asset no longer exists.']);
+ exit;
+}
-$client_id = intval($row['client_id']);
+$client_id = intval($asset_row['asset_client_id']);
enforceClientAccess();
-$client_name = escapeHtml($row['client_name']);
-$asset_id = intval($row['asset_id']);
-$asset_type = escapeHtml($row['asset_type']);
-$asset_name = escapeHtml($row['asset_name']);
-$asset_description = escapeHtml($row['asset_description']);
-$asset_make = escapeHtml($row['asset_make']);
-$asset_model = escapeHtml($row['asset_model']);
-$asset_serial = escapeHtml($row['asset_serial']);
-$asset_os = escapeHtml($row['asset_os']);
-$asset_uri = escapeUrl($row['asset_uri']);
-$asset_uri_2 = escapeUrl($row['asset_uri_2']);
-$asset_uri_client = escapeUrl($row['asset_uri_client']);
-$asset_status = escapeHtml($row['asset_status']);
-$asset_purchase_reference = escapeHtml($row['asset_purchase_reference']);
-$asset_purchase_date = escapeHtml($row['asset_purchase_date']);
-$asset_warranty_expire = escapeHtml($row['asset_warranty_expire']);
-$asset_install_date = escapeHtml($row['asset_install_date']);
-$asset_photo = escapeHtml($row['asset_photo']);
-$asset_physical_location = escapeHtml($row['asset_physical_location']);
-$asset_notes = escapeHtml($row['asset_notes']);
-$asset_favorite = intval($row['asset_favorite']);
-$asset_created_at = escapeHtml($row['asset_created_at']);
-$asset_vendor_id = intval($row['asset_vendor_id']);
-$asset_location_id = intval($row['asset_location_id']);
-$asset_contact_id = intval($row['asset_contact_id']);
+$can_edit = lookupUserPermission('module_support') >= 2;
+$can_credentials = lookupUserPermission('module_credential') >= 1;
-$asset_ip = escapeHtml($row['interface_ip']);
-$asset_ipv6 = escapeHtml($row['interface_ipv6']);
-$asset_nat_ip = escapeHtml($row['interface_nat_ip']);
-$asset_mac = escapeHtml($row['interface_mac']);
-$asset_network_id = intval($row['interface_network_id']);
-
-$device_icon = getAssetIcon($asset_type);
-
-$contact_name = escapeHtml($row['contact_name']);
-$contact_email = escapeHtml($row['contact_email']);
-$contact_phone_country_code = escapeHtml($row['contact_phone_country_code']);
-$contact_phone = escapeHtml(formatPhoneNumber($row['contact_phone'], $contact_phone_country_code));
-$contact_extension = escapeHtml($row['contact_extension']);
-$contact_mobile_country_code = escapeHtml($row['contact_mobile_country_code']);
-$contact_mobile = escapeHtml(formatPhoneNumber($row['contact_mobile'], $contact_mobile_country_code));
-$contact_archived_at = escapeHtml($row['contact_archived_at']);
-if ($contact_archived_at) {
- $contact_name_display = "$contact_name";
-} else {
- $contact_name_display = $contact_name;
-}
-$location_name = escapeHtml($row['location_name']);
-if (empty($location_name)) {
- $location_name = "-";
-}
-$location_archived_at = escapeHtml($row['location_archived_at']);
-if ($location_archived_at) {
- $location_name_display = "$location_name";
-} else {
- $location_name_display = $location_name;
-}
+$asset_name = escapeHtml($asset_row['asset_name']);
+$asset_type = escapeHtml($asset_row['asset_type']);
+$asset_description = escapeHtml($asset_row['asset_description']);
+$asset_make_model = escapeHtml(trim($asset_row['asset_make'] . ' ' . $asset_row['asset_model']));
+$asset_os = escapeHtml($asset_row['asset_os']);
+$asset_os_icon = assetOsIcon($asset_row['asset_os']);
+$asset_serial = escapeHtml($asset_row['asset_serial']);
+$asset_ip = escapeHtml($asset_row['interface_ip']);
+$asset_mac = escapeHtml($asset_row['interface_mac']);
+$asset_links = assetLinks($asset_row['asset_uri'], $asset_row['asset_uri_2'], $asset_row['asset_uri_client']);
+$asset_warranty = assetWarranty($asset_row['asset_warranty_expire']);
+$asset_photo = escapeHtml($asset_row['asset_photo']);
+$asset_physical_location = escapeHtml($asset_row['asset_physical_location']);
+$asset_notes = escapeHtml($asset_row['asset_notes']);
+$asset_favorite = intval($asset_row['asset_favorite']);
+$asset_archived = !empty($asset_row['asset_archived_at']);
+$asset_contact_id = intval($asset_row['asset_contact_id']);
+$asset_tone = assetTypeTone($asset_row['asset_type']);
+$device_icon = getAssetIcon($asset_row['asset_type']);
+$asset_tags_display = tagPills('asset', $asset_id, tagsForRecord('asset', $asset_id), "assets.php?client_id=$client_id&");
// The rack it sits in, if any
$asset_rack = rackPositionForAsset($asset_id);
-if ($asset_rack) {
- $asset_rack_id = intval($asset_rack['rack_id']);
- $asset_rack_name = escapeHtml($asset_rack['rack_name']);
- $asset_rack_position = rackPositionLabel($asset_rack['unit_start_number'], $asset_rack['unit_end_number']) . ', ' . ($asset_rack['unit_face'] === 'rear' ? 'rear' : 'front');
-}
-// Tags - many to many relationship
-// Tags - functions/tags.php
-$asset_tags_display = tagPills('asset', $asset_id, tagsForRecord('asset', $asset_id), "assets.php?client_id=$client_id&");
-
-// Network Interfaces
+// Interfaces, primary first, and what each one is plugged into
$sql_related_interfaces = mysqli_query($mysqli, "
- SELECT
- ai.interface_id,
- ai.interface_name,
- ai.interface_description,
- ai.interface_type,
- ai.interface_mac,
- ai.interface_ip,
- ai.interface_nat_ip,
- ai.interface_ipv6,
- ai.interface_primary,
- ai.interface_notes,
- n.network_name,
- n.network_id,
- connected_interfaces.interface_id AS connected_interface_id,
+ SELECT ai.interface_id, ai.interface_name, ai.interface_mac, ai.interface_ip, ai.interface_primary,
connected_interfaces.interface_name AS connected_interface_name,
connected_assets.asset_name AS connected_asset_name,
connected_assets.asset_id AS connected_asset_id,
connected_assets.asset_type AS connected_asset_type
FROM asset_interfaces AS ai
- LEFT JOIN networks AS n
- ON n.network_id = ai.interface_network_id
LEFT JOIN asset_interface_links AS ail
ON (ail.interface_a_id = ai.interface_id OR ail.interface_b_id = ai.interface_id)
LEFT JOIN asset_interfaces AS connected_interfaces
@@ -132,849 +86,494 @@ $sql_related_interfaces = mysqli_query($mysqli, "
)
LEFT JOIN assets AS connected_assets
ON connected_assets.asset_id = connected_interfaces.interface_asset_id
- WHERE
- ai.interface_asset_id = $asset_id
- AND ai.interface_archived_at IS NULL
- ORDER BY ai.interface_name ASC
+ WHERE ai.interface_asset_id = $asset_id
+ AND ai.interface_archived_at IS NULL
+ ORDER BY ai.interface_primary DESC, ai.interface_name ASC
");
$interface_count = mysqli_num_rows($sql_related_interfaces);
-// Related Credentials Query
-$sql_related_credentials = mysqli_query($mysqli, "
- SELECT
- credentials.credential_id AS credential_id,
- credentials.credential_name,
- credentials.credential_description,
- credentials.credential_uri,
- credentials.credential_username,
- credentials.credential_password,
- credentials.credential_otp_secret,
- credentials.credential_note,
- credentials.credential_favorite,
- credentials.credential_contact_id,
- credentials.credential_asset_id
- FROM credentials
- WHERE credential_asset_id = $asset_id
- AND credential_archived_at IS NULL
- GROUP BY credentials.credential_id
- ORDER BY credential_name DESC
-");
-// No module_credential, no Credentials tab - the pane below was already gated, the tab wasn't
-$credential_count = lookupUserPermission('module_credential') ? mysqli_num_rows($sql_related_credentials) : 0;
+// Credentials - only for agents who may see them
+$credential_count = 0;
+if ($can_credentials) {
+ $sql_related_credentials = mysqli_query($mysqli, "
+ SELECT credential_id, credential_name, credential_uri, credential_username, credential_otp_secret
+ FROM credentials
+ WHERE credential_asset_id = $asset_id
+ AND credential_archived_at IS NULL
+ ORDER BY credential_name ASC
+ ");
+ $credential_count = mysqli_num_rows($sql_related_credentials);
+}
-// Related Tickets Query
+// Tickets - open ones first; the most recent few here, the rest on the asset page
+$quick_ticket_limit = 8;
$sql_related_tickets = mysqli_query($mysqli, "
- SELECT tickets.ticket_id, ticket_prefix, ticket_number, ticket_subject, ticket_priority, ticket_created_at,
- ticket_updated_at, ticket_closed_at, ticket_assigned_to, user_name, user_avatar,
- ticket_status_id, ticket_status_name, ticket_status_color
+ SELECT tickets.ticket_id, ticket_prefix, ticket_number, ticket_subject, ticket_updated_at, ticket_created_at,
+ ticket_resolved_at, ticket_closed_at, ticket_assigned_to, user_name, user_avatar,
+ ticket_status_name, ticket_status_color
FROM tickets
LEFT JOIN users ON ticket_assigned_to = user_id
LEFT JOIN ticket_statuses ON ticket_status_id = ticket_status
LEFT JOIN ticket_assets ON tickets.ticket_id = ticket_assets.ticket_id
WHERE ticket_asset_id = $asset_id OR ticket_assets.asset_id = $asset_id
GROUP BY tickets.ticket_id
- ORDER BY ticket_number DESC
+ ORDER BY (ticket_resolved_at IS NULL AND ticket_closed_at IS NULL) DESC, ticket_number DESC
");
$ticket_count = mysqli_num_rows($sql_related_tickets);
+$ticket_open_count = 0;
+$related_tickets = [];
+while ($row = mysqli_fetch_assoc($sql_related_tickets)) {
+ $is_open = empty($row['ticket_resolved_at']) && empty($row['ticket_closed_at']);
+ $ticket_open_count += $is_open ? 1 : 0;
+ if (count($related_tickets) < $quick_ticket_limit) {
+ $related_tickets[] = $row + ['is_open' => $is_open];
+ }
+}
-// Related Recurring Tickets Query
-$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT recurring_ticket_frequency, recurring_ticket_assets.recurring_ticket_id,
- recurring_ticket_next_run, recurring_ticket_priority, recurring_ticket_subject FROM recurring_tickets
+// Recurring tickets
+$sql_related_recurring_tickets = mysqli_query($mysqli, "SELECT recurring_tickets.recurring_ticket_id, recurring_ticket_subject,
+ recurring_ticket_frequency, recurring_ticket_next_run
+ FROM recurring_tickets
LEFT JOIN recurring_ticket_assets ON recurring_tickets.recurring_ticket_id = recurring_ticket_assets.recurring_ticket_id
WHERE recurring_ticket_asset_id = $asset_id OR recurring_ticket_assets.asset_id = $asset_id
GROUP BY recurring_tickets.recurring_ticket_id
- ORDER BY recurring_ticket_next_run DESC"
+ ORDER BY recurring_ticket_next_run ASC"
);
$recurring_ticket_count = mysqli_num_rows($sql_related_recurring_tickets);
-// Related Documents
-$sql_related_documents = mysqli_query($mysqli, "SELECT document_created_at, document_description, documents.document_id, document_name,
- document_updated_at, user_name FROM asset_documents
- LEFT JOIN documents ON asset_documents.document_id = documents.document_id
- LEFT JOIN users ON user_id = document_created_by
+// Licenses, with seats in use counted in the same query
+$sql_related_software = mysqli_query($mysqli, "SELECT software_assets.software_id, software_name, software_version, software_seats,
+ (SELECT COUNT(*) FROM software_assets AS sa WHERE sa.software_id = software.software_id)
+ + (SELECT COUNT(*) FROM software_contacts AS sc WHERE sc.software_id = software.software_id) AS seats_used
+ FROM software_assets
+ LEFT JOIN software ON software_assets.software_id = software.software_id
+ WHERE software_assets.asset_id = $asset_id
+ AND software_archived_at IS NULL
+ ORDER BY software_name ASC"
+);
+$software_count = mysqli_num_rows($sql_related_software);
+
+// Documents
+$sql_related_documents = mysqli_query($mysqli, "SELECT documents.document_id, document_name, document_created_at, document_updated_at
+ FROM asset_documents
+ JOIN documents ON asset_documents.document_id = documents.document_id
WHERE asset_documents.asset_id = $asset_id
- AND document_archived_at IS NULL
- ORDER BY document_name DESC"
+ AND document_archived_at IS NULL
+ ORDER BY document_name ASC"
);
$document_count = mysqli_num_rows($sql_related_documents);
-// Related Files
-$sql_related_files = mysqli_query($mysqli, "SELECT file_created_at, file_description, file_ext, files.file_id, file_mime_type, file_name FROM asset_files
- LEFT JOIN files ON asset_files.file_id = files.file_id
+// Files
+$sql_related_files = mysqli_query($mysqli, "SELECT files.file_id, file_name, file_ext, file_created_at
+ FROM asset_files
+ JOIN files ON asset_files.file_id = files.file_id
WHERE asset_files.asset_id = $asset_id
- AND file_archived_at IS NULL
- ORDER BY file_name DESC"
+ AND file_archived_at IS NULL
+ ORDER BY file_name ASC"
);
$file_count = mysqli_num_rows($sql_related_files);
-// Related Software Query
-$sql_related_software = mysqli_query(
- $mysqli,
- "SELECT software_expire, software_assets.software_id, software_key, software_license_type,
- software_name, software_notes, software_purchase, software_seats, software_type,
- software_version FROM software_assets
- LEFT JOIN software ON software_assets.software_id = software.software_id
- WHERE software_assets.asset_id = $asset_id
- AND software_archived_at IS NULL
- ORDER BY software_name DESC"
-);
-
-$software_count = mysqli_num_rows($sql_related_software);
-
-// Related Notes
+// Notes
$sql_related_notes = mysqli_query($mysqli, "SELECT asset_note, asset_note_created_at, asset_note_type, user_name FROM asset_notes
LEFT JOIN users ON asset_note_created_by = user_id
WHERE asset_note_asset_id = $asset_id
- AND asset_note_archived_at IS NULL
+ AND asset_note_archived_at IS NULL
ORDER BY asset_note_created_at DESC"
);
$note_count = mysqli_num_rows($sql_related_notes);
-
-// Note type icons, read from the categories list
-$note_type_icons = array();
+$note_type_icons = [];
$sql_note_type_icons = mysqli_query($mysqli, "SELECT category_name, category_icon FROM categories WHERE category_type = 'asset_note_type'");
while ($row = mysqli_fetch_assoc($sql_note_type_icons)) {
- $note_type_icons[escapeHtml($row['category_name'])] = escapeHtml($row['category_icon']);
+ $note_type_icons[$row['category_name']] = escapeHtml($row['category_icon']);
}
-if (isset($_GET['client_id'])) {
- $client_url = "client_id=$client_id&";
-} else {
- $client_url = '';
-}
+// Only the tabs with something in them - same order as the asset page
+$quick_tabs = array_filter([
+ 'interfaces' => ['label' => 'Interfaces', 'count' => $interface_count],
+ 'credentials' => ['label' => 'Credentials', 'count' => $credential_count],
+ 'tickets' => ['label' => 'Tickets', 'count' => $ticket_count, 'badge' => $ticket_open_count],
+ 'recurring' => ['label' => 'Recurring', 'count' => $recurring_ticket_count],
+ 'licenses' => ['label' => 'Licenses', 'count' => $software_count],
+ 'documents' => ['label' => 'Documents', 'count' => $document_count],
+ 'files' => ['label' => 'Files', 'count' => $file_count],
+ 'notes' => ['label' => 'Notes', 'count' => $note_count],
+], function ($tab) {
+ return $tab['count'] > 0;
+});
+$first_tab = array_key_first($quick_tabs);
+
+$has_left = $asset_ip || $asset_mac || $asset_serial || $asset_warranty;
+$has_right = $can_edit || $asset_row['location_name'] || $asset_row['contact_name'] || $asset_rack;
ob_start();
?>
-