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 .= '