From ee426cf5ea87db1e7db8503e4b3dcbd46fa8d052 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9CVeLiTi=E2=80=9D?= <“info@veliti.nl”>
Date: Thu, 5 Feb 2026 10:10:26 +0100
Subject: [PATCH] Enhance partner dropdowns to include authorization
permissions across various management pages. Implement hardware version
checks with warning modals for restricted versions. Update translations for
hardware compatibility notices in multiple languages. Refactor SQL and PHP
files to improve code clarity and maintainability.
---
account_manage.php | 2 +-
api/v2/get/products.php | 2 +
api/v2/get/products_software_assignment.php | 2 +-
api/v2/get/user_roles.php | 2 +-
assets/database/STEP 1.sql | 1 +
assets/softwaretool.js | 175 +++++++++++++++++---
contract_manage.php | 8 +-
equipment_manage.php | 8 +-
equipments.php | 10 +-
equipments_mass_update.php | 8 +-
partner.php | 4 +-
settings/translations/translations_DE.php | 4 +
settings/translations/translations_ES.php | 4 +
settings/translations/translations_NL.php | 4 +
settings/translations/translations_PL.php | 4 +
settings/translations/translations_PT.php | 4 +
settings/translations/translations_US.php | 4 +
softwaretool.php | 4 +
style/admin.css | 10 +-
user.php | 8 +-
user_role.php | 18 +-
21 files changed, 235 insertions(+), 51 deletions(-)
diff --git a/account_manage.php b/account_manage.php
index eb225fa..a2c3161 100644
--- a/account_manage.php
+++ b/account_manage.php
@@ -272,7 +272,7 @@ $view .= '
//Dropdown
$partner_data = json_decode($_SESSION['authorization']['partnerhierarchy']);
-$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$accounthierarchy->soldto,'');
+$soldto_dropdown = listPartner('soldto',$accounthierarchy->soldto,'',$_SESSION['authorization']['permission']);
$view .= '
'.$tab3.'
diff --git a/api/v2/get/products.php b/api/v2/get/products.php
index bf846a6..86806d5 100644
--- a/api/v2/get/products.php
+++ b/api/v2/get/products.php
@@ -13,6 +13,8 @@ if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} el
//default whereclause
$whereclause = '';
+$whereclause_alt = '';
+$whereclause_alt2 = '';
list($whereclause,$condition) = getWhereclause('products',$permission,$partner,'get');
diff --git a/api/v2/get/products_software_assignment.php b/api/v2/get/products_software_assignment.php
index fd29ca2..0c0a041 100644
--- a/api/v2/get/products_software_assignment.php
+++ b/api/v2/get/products_software_assignment.php
@@ -12,7 +12,7 @@ $pdo = dbConnect($dbname);
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//default whereclause
-list($whereclause,$condition) = getWhereclauselvl2("software_assignment",$permission,$partner,'get');
+list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'get');
//NEW ARRAY
$criterias = [];
diff --git a/api/v2/get/user_roles.php b/api/v2/get/user_roles.php
index cb07b3f..f1a31a8 100644
--- a/api/v2/get/user_roles.php
+++ b/api/v2/get/user_roles.php
@@ -52,7 +52,7 @@ if(isset($get_content) && $get_content!=''){
//Filter system roles for users without delete permission on user_roles
if (isAllowed('user_roles', $profile, $permission, 'D') !== 1) {
- $clause .= ' AND r.is_system != 1';
+ $clause .= ' AND r.is_system != 1 AND r.role_hierarchy >= '.$permission;
}
//Build WHERE clause
diff --git a/assets/database/STEP 1.sql b/assets/database/STEP 1.sql
index 0733532..a0845be 100644
--- a/assets/database/STEP 1.sql
+++ b/assets/database/STEP 1.sql
@@ -357,6 +357,7 @@ CREATE TABLE `user_roles` (
`updated` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`updatedby` varchar(255) DEFAULT NULL,
`is_system` tinyint(1) DEFAULT NULL,
+ `role_hierarchy` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`rowID`),
UNIQUE KEY `unique_role_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
diff --git a/assets/softwaretool.js b/assets/softwaretool.js
index 4e5e8f4..5d3c688 100644
--- a/assets/softwaretool.js
+++ b/assets/softwaretool.js
@@ -10,6 +10,51 @@ let deviceVersion = "";
let deviceHwVersion = "";
let selectedSoftwareUrl = "";
+// Restricted hardware versions that require warning
+const RESTRICTED_HW_VERSIONS = ['r06', 'r06a', 'r07', 'r07a', 'r07b'];
+
+// Helper function to normalize hardware version for comparison
+function normalizeHwVersion(hwVersion) {
+ if (!hwVersion) return '';
+
+ // Convert to lowercase and trim
+ let normalized = hwVersion.toLowerCase().trim();
+
+ // Remove leading zeros (e.g., "0000070" -> "70", "0000060" -> "60")
+ normalized = normalized.replace(/^0+/, '');
+
+ // If it starts with 'r', keep it as is (e.g., "r06a")
+ if (normalized.startsWith('r')) {
+ return normalized;
+ }
+
+ // Extract numeric part and suffix (e.g., "7a" -> "7" + "a", "70" -> "70" + "")
+ const match = normalized.match(/^(\d+)([a-z]*)$/);
+ if (!match) return 'r' + normalized; // Fallback
+
+ let numPart = match[1];
+ const suffix = match[2];
+
+ // Pad single digit to 2 digits (e.g., "7" -> "07", "6" -> "06")
+ if (numPart.length === 1) {
+ numPart = '0' + numPart;
+ } else if (numPart.length === 2 && numPart.endsWith('0') && numPart[0] !== '0') {
+ // "70" -> "07", "60" -> "06" (swap if needed)
+ numPart = '0' + numPart[0];
+ }
+
+ // Add 'r' prefix (e.g., "07" -> "r07", "07a" -> "r07a", "07b" -> "r07b")
+ return 'r' + numPart + suffix;
+}
+
+// Check if hardware version is restricted
+function isRestrictedHardware(hwVersion) {
+ const normalized = normalizeHwVersion(hwVersion);
+ const isRestricted = RESTRICTED_HW_VERSIONS.includes(normalized);
+ console.log(`[HW Check] Original: "${hwVersion}" -> Normalized: "${normalized}" -> Restricted: ${isRestricted}`);
+ return isRestricted;
+}
+
// Helper function to generate country select options
function generateCountryOptions(selectedCountry = '') {
if (typeof COUNTRIES === 'undefined' || !COUNTRIES) {
@@ -242,7 +287,7 @@ async function connectDeviceForSoftware() {
// TEST MODE: Use mock device data
deviceSerialNumber = "22110095";
deviceVersion = "03e615af";
- deviceHwVersion = "0000080";
+ deviceHwVersion = "0000070";
document.getElementById("Device_output").style.display = "block";
serialResultsDiv.innerHTML = `
DEBUG MODE - Simulated Device Data: SN=${deviceSerialNumber}
FW=${deviceVersion}
HW=${deviceHwVersion}`;
@@ -624,20 +669,30 @@ async function fetchSoftwareOptions() {
const customerDataShownThisSession = sessionStorage.getItem('customerDataShownThisSession');
// Show user info modal unless:
- // 1. We're in debug mode
- // 2. We're returning from payment
- // 3. We already showed the modal in this session
- if ((typeof DEBUG === 'undefined' || !DEBUG || typeof DEBUG_ID === 'undefined' || !DEBUG_ID)
- && !isReturningFromPayment
- && !customerDataShownThisSession) {
+ // 1. We're returning from payment
+ // 2. We already showed the modal in this session
+ if (!isReturningFromPayment && !customerDataShownThisSession) {
+ // Always show userInfoModal (even in debug mode)
showUserInfoModal();
} else {
- // Debug mode, returning from payment, or already shown this session - reveal software options immediately
- const softwareOptions = document.getElementById("softwareOptions");
- if (softwareOptions) {
- softwareOptions.style.filter = "none";
- softwareOptions.style.opacity = "1";
- softwareOptions.style.pointerEvents = "auto";
+ // Returning from payment or already shown this session
+ console.log('[HW Check] Skipping userInfoModal - checking hardware version...');
+ console.log('[HW Check] deviceHwVersion:', deviceHwVersion);
+
+ // Check if hardware version is restricted
+ if (isRestrictedHardware(deviceHwVersion)) {
+ // Show hardware warning modal
+ console.log('[HW Check] Hardware is restricted - showing warning modal');
+ showHwWarningModal();
+ } else {
+ // Reveal software options immediately
+ console.log('[HW Check] Hardware is not restricted - revealing options');
+ const softwareOptions = document.getElementById("softwareOptions");
+ if (softwareOptions) {
+ softwareOptions.style.filter = "none";
+ softwareOptions.style.opacity = "1";
+ softwareOptions.style.pointerEvents = "auto";
+ }
}
}
@@ -1014,12 +1069,18 @@ function showUserInfoModal() {
// Close modal
document.body.removeChild(modal);
- // Reveal software options by removing blur
- const softwareOptions = document.getElementById("softwareOptions");
- if (softwareOptions) {
- softwareOptions.style.filter = "none";
- softwareOptions.style.opacity = "1";
- softwareOptions.style.pointerEvents = "auto";
+ // Check if hardware version is restricted
+ if (isRestrictedHardware(deviceHwVersion)) {
+ // Show hardware warning modal
+ showHwWarningModal();
+ } else {
+ // Reveal software options by removing blur
+ const softwareOptions = document.getElementById("softwareOptions");
+ if (softwareOptions) {
+ softwareOptions.style.filter = "none";
+ softwareOptions.style.opacity = "1";
+ softwareOptions.style.pointerEvents = "auto";
+ }
}
};
}
@@ -1064,6 +1125,82 @@ async function sendUserInfoToAPI(customerData) {
}
}
+function showHwWarningModal() {
+ console.log(`[HW Check] Showing hardware warning modal for HW version: ${deviceHwVersion}`);
+
+ // Create modal overlay - matching userInfoModal
+ const modal = document.createElement("div");
+ modal.id = "hwWarningModal";
+ modal.style.cssText = `
+ display: flex;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.7);
+ z-index: 2000;
+ align-items: center;
+ justify-content: center;
+ `;
+
+ // Create modal content - matching userInfoModal
+ const modalContent = document.createElement("div");
+ modalContent.style.cssText = `
+ background: white;
+ border-radius: 12px;
+ max-width: 500px;
+ width: 90%;
+ max-height: 90vh;
+ overflow-y: auto;
+ margin: 20px;
+ box-shadow: 0 20px 60px rgba(0,0,0,0.4);
+ `;
+
+ modalContent.innerHTML = `
+
+
${typeof TRANS_HW_WARNING_TITLE !== 'undefined' ? TRANS_HW_WARNING_TITLE : 'Hardware Compatibility Notice'}
+
${typeof TRANS_HW_WARNING_SUBTITLE !== 'undefined' ? TRANS_HW_WARNING_SUBTITLE : 'Please read the following information carefully'}
+
+
+
+
+
+
+
+ ${typeof TRANS_HW_WARNING_DETECTED !== 'undefined' ? TRANS_HW_WARNING_DETECTED.replace('{hw_version}', deviceHwVersion) : `Hardware version ${deviceHwVersion} detected`}
+
+
+ ${typeof TRANS_HW_WARNING_TEXT !== 'undefined' ? TRANS_HW_WARNING_TEXT : 'This hardware version requires special attention. Please ensure you select the correct software version for your device.'}
+
+
+
+
+
+
+ ${typeof TRANS_CONTINUE !== 'undefined' ? TRANS_CONTINUE : 'Continue'}
+
+
+ `;
+
+ modal.appendChild(modalContent);
+ document.body.appendChild(modal);
+
+ // Handle continue button click
+ document.getElementById("hwWarningContinue").onclick = () => {
+ // Close modal
+ document.body.removeChild(modal);
+
+ // Reveal software options by removing blur
+ const softwareOptions = document.getElementById("softwareOptions");
+ if (softwareOptions) {
+ softwareOptions.style.filter = "none";
+ softwareOptions.style.opacity = "1";
+ softwareOptions.style.pointerEvents = "auto";
+ }
+ };
+}
+
async function selectUpgrade(option) {
const price = parseFloat(option.price || 0);
const isFree = price === 0;
diff --git a/contract_manage.php b/contract_manage.php
index 7c46e33..9d7b602 100644
--- a/contract_manage.php
+++ b/contract_manage.php
@@ -248,10 +248,10 @@ $view .='
$partner_data = json_decode($contract['accounthierarchy']);
//BUID UP DROPDOWNS
-$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner_data->salesid,'');
-$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$partner_data->soldto,'');
-$shipto_dropdown = listPartner('shipto',$_SESSION['authorization']['permission'],$partner_data->shipto,'');
-$location_dropdown = listPartner('location',$_SESSION['authorization']['permission'],$partner_data->location,'');
+$salesid_dropdown = listPartner('salesid',$partner_data->salesid,'',$_SESSION['authorization']['permission']);
+$soldto_dropdown = listPartner('soldto',$partner_data->soldto,'',$_SESSION['authorization']['permission']);
+$shipto_dropdown = listPartner('shipto',$partner_data->shipto,'',$_SESSION['authorization']['permission']);
+$location_dropdown = listPartner('location',$partner_data->location,'',$_SESSION['authorization']['permission']);
//DISPLAY
$view .= '
diff --git a/equipment_manage.php b/equipment_manage.php
index 8e8f031..e72fa6e 100644
--- a/equipment_manage.php
+++ b/equipment_manage.php
@@ -216,10 +216,10 @@ $view .= '
//GET PARTNERDATA
$partner_data = json_decode($equipment['accounthierarchy']);
//BUID UP DROPDOWNS
-$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner_data->salesid,'');
-$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$partner_data->soldto,'');
-$shipto_dropdown = listPartner('shipto',$_SESSION['authorization']['permission'],$partner_data->shipto,'');
-$location_dropdown = listPartner('location',$_SESSION['authorization']['permission'],$partner_data->location,'');
+$salesid_dropdown = listPartner('salesid',$partner_data->salesid,'',$_SESSION['authorization']['permission']);
+$soldto_dropdown = listPartner('soldto',$partner_data->soldto,'',$_SESSION['authorization']['permission']);
+$shipto_dropdown = listPartner('shipto',$partner_data->shipto,'',$_SESSION['authorization']['permission']);
+$location_dropdown = listPartner('location',$partner_data->location,'',$_SESSION['authorization']['permission']);
if (isset($partner_data->section)){$section = getPartnerName($partner_data->section) ?? 'Not specified';} else {$section = 'Not specified';}
diff --git a/equipments.php b/equipments.php
index cc999d6..55b04ac 100644
--- a/equipments.php
+++ b/equipments.php
@@ -247,10 +247,12 @@ if (isset($partner_data->section)){$section = getPartnerName($partner_data->sect
//GET PATH OF ASSIGNED MEDIA
$full_path = '';
-
-foreach ($media_responses as $media){
- if($response->product_media == $media['rowID']){
- $full_path = $media['full_path'];
+
+if (!empty($media_responses) && is_array($media_responses)){
+ foreach ($media_responses as $media){
+ if($response->product_media == $media['rowID']){
+ $full_path = $media['full_path'];
+ }
}
}
diff --git a/equipments_mass_update.php b/equipments_mass_update.php
index 565043e..b0e44f1 100644
--- a/equipments_mass_update.php
+++ b/equipments_mass_update.php
@@ -200,10 +200,10 @@ $view .= '