Merge branch 'development'
@@ -23,17 +23,37 @@ document.querySelector('.responsive-toggle').onclick = event => {
|
||||
document.querySelectorAll('.tabs a').forEach((element, index) => {
|
||||
element.onclick = event => {
|
||||
event.preventDefault();
|
||||
document.querySelectorAll('.tabs a').forEach(element => element.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-content').forEach((element2, index2) => {
|
||||
if (index == index2) {
|
||||
element.classList.add('active');
|
||||
element2.style.display = 'block';
|
||||
} else {
|
||||
element2.style.display = 'none';
|
||||
}
|
||||
|
||||
// Toggle the clicked tab
|
||||
const isActive = element.classList.contains('active');
|
||||
const tabContent = document.querySelectorAll('.tab-content')[index];
|
||||
|
||||
// Remove active class from all tabs and contents
|
||||
document.querySelectorAll('.tabs a').forEach(el => el.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-content').forEach(content => {
|
||||
content.classList.remove('active');
|
||||
content.style.display = 'none';
|
||||
});
|
||||
|
||||
// If it wasn't active, make it active (collapsible behavior)
|
||||
if (!isActive && tabContent) {
|
||||
element.classList.add('active');
|
||||
tabContent.classList.add('active');
|
||||
tabContent.style.display = 'block';
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Initialize first tab as open by default
|
||||
if (document.querySelectorAll('.tabs a').length > 0) {
|
||||
const firstTab = document.querySelectorAll('.tabs a')[0];
|
||||
const firstContent = document.querySelectorAll('.tab-content')[0];
|
||||
if (firstTab && firstContent) {
|
||||
firstTab.classList.add('active');
|
||||
firstContent.classList.add('active');
|
||||
firstContent.style.display = 'block';
|
||||
}
|
||||
}
|
||||
if (document.querySelector('.filters a')) {
|
||||
let filtersList = document.querySelector('.filters .list');
|
||||
let filtersListStyle = window.getComputedStyle(filtersList);
|
||||
|
||||
@@ -1490,6 +1490,7 @@ function getProfile($profile, $permission){
|
||||
'com_log' => 'U',
|
||||
'software_update' => 'R',
|
||||
'software_download' => 'R',
|
||||
'software_available' => 'R'
|
||||
];
|
||||
|
||||
// Group permissions: [granting_page => [collection => allowed_actions_string]]
|
||||
@@ -5110,4 +5111,84 @@ function checkAndInsertIdentityDealer($pdo, $identityUserkey) {
|
||||
error_log('Database error in checkAndInsertIdentityDealer: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
// Update software version status for equipment
|
||||
// Parameters:
|
||||
// $pdo - PDO database connection
|
||||
// $serialnumber - Optional serial number. If null, updates all equipment
|
||||
// Returns: boolean - true on success, false on error
|
||||
//------------------------------------------
|
||||
function updateSoftwareVersionStatus($pdo, $serialnumber = null) {
|
||||
try {
|
||||
// Build WHERE clause for serial number filtering if provided
|
||||
$sn_clause = '';
|
||||
$bind_params = [];
|
||||
|
||||
if ($serialnumber !== null) {
|
||||
$sn_clause = ' AND e.serialnumber = ?';
|
||||
$bind_params = [$serialnumber];
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
// STEP 1: Set sw_version_latest = 2 for equipment with NO software assignments
|
||||
//------------------------------------------
|
||||
$sql = 'UPDATE equipment e
|
||||
LEFT JOIN products_software_assignment psa ON e.productrowid = psa.product_id AND psa.status = 1
|
||||
SET e.sw_version_latest = 2
|
||||
WHERE psa.product_id IS NULL' . $sn_clause;
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($bind_params);
|
||||
|
||||
//------------------------------------------
|
||||
// STEP 2: Set sw_version_latest = 0 for equipment WITH software assignments (from previous 2)
|
||||
//------------------------------------------
|
||||
$sql = 'UPDATE equipment e
|
||||
JOIN products_software_assignment psa ON e.productrowid = psa.product_id AND psa.status = 1
|
||||
SET e.sw_version_latest = 0
|
||||
WHERE e.sw_version_latest = 2' . $sn_clause;
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($bind_params);
|
||||
|
||||
//------------------------------------------
|
||||
// STEP 3: Set sw_version_latest = 0 for equipment NOT matching latest version
|
||||
//------------------------------------------
|
||||
$sql = 'UPDATE equipment e
|
||||
JOIN products_software_assignment psa ON e.productrowid = psa.product_id AND psa.status = 1
|
||||
JOIN products_software_versions psv ON psa.software_version_id = psv.rowID
|
||||
SET e.sw_version_latest = 0
|
||||
WHERE psv.latest = 1
|
||||
AND psv.status = 1
|
||||
AND lower(e.sw_version) <> lower(psv.version)
|
||||
AND (psv.hw_version = e.hw_version OR psv.hw_version IS NULL OR psv.hw_version = "")
|
||||
AND e.sw_version_latest = 1' . $sn_clause;
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($bind_params);
|
||||
|
||||
//------------------------------------------
|
||||
// STEP 4: Set sw_version_latest = 1 for equipment matching latest version
|
||||
//------------------------------------------
|
||||
$sql = 'UPDATE equipment e
|
||||
JOIN products_software_assignment psa ON e.productrowid = psa.product_id AND psa.status = 1
|
||||
JOIN products_software_versions psv ON psa.software_version_id = psv.rowID
|
||||
SET e.sw_version_latest = 1
|
||||
WHERE psv.latest = 1
|
||||
AND psv.status = 1
|
||||
AND lower(e.sw_version) = lower(psv.version)
|
||||
AND (psv.hw_version = e.hw_version OR psv.hw_version IS NULL OR psv.hw_version = "")
|
||||
AND e.sw_version_latest = 0' . $sn_clause;
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($bind_params);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log('Database error in updateSoftwareVersionStatus: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 204 KiB |
BIN
assets/images/media/67fbcc9ac57a5_Swim-Spas-Image-1.jpg
Normal file
|
After Width: | Height: | Size: 250 KiB |
BIN
assets/images/media/67fbcda135a98_hotspringworld-42.webp
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
assets/images/media/Band_0000_Layer-1-copy normaal.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
assets/images/media/Band_0001_Layer-2-copy normaal.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
assets/images/media/Band_0002_Layer-3-copy normaal.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
assets/images/media/Band_0003_Layer-4-copy normaal.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
assets/images/media/Band_0004_Layer-1 normaal.png
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
assets/images/media/Band_0005_Layer-2 normaal.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
assets/images/media/Band_0006_Layer-4 normaal.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
assets/images/media/Band_0007_Layer-3 normaal.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
assets/images/media/EPH2NA1.png
Normal file
|
After Width: | Height: | Size: 672 KiB |
BIN
assets/images/media/EPSK01.jpg
Normal file
|
After Width: | Height: | Size: 913 KiB |
BIN
assets/images/media/Morval-Watches2024-V1-Blue-Black normaal.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 203 KiB |
BIN
assets/images/media/Morval-Watches2024-V1-Blue-Brown normaal.png
Normal file
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 212 KiB |
BIN
assets/images/media/Morval-Watches2024-V1-Blue-Calf normaal.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 214 KiB |
BIN
assets/images/media/Morval-Watches2024-V1-Blue-Steel normaal.png
Normal file
|
After Width: | Height: | Size: 189 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 187 KiB |
BIN
assets/images/media/Morval-Watches2024-V1-Grey-Black normaal.png
Normal file
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 209 KiB |
|
After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 211 KiB |
BIN
assets/images/media/Morval_achterkant.png
Normal file
|
After Width: | Height: | Size: 25 MiB |
BIN
assets/images/media/SP1.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/images/media/band_black.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/images/media/band_black_croc.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
assets/images/media/band_blue.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
assets/images/media/band_dark_brown.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/images/media/band_light_brown.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/images/media/band_steel.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
assets/images/media/morval-crown.jpg
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
assets/images/media/morval_band_connect1.jpg
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
assets/images/media/morval_band_connect2.jpg
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
assets/images/media/morval_box.jpg
Normal file
|
After Width: | Height: | Size: 300 KiB |
BIN
assets/images/media/morval_closure.jpg
Normal file
|
After Width: | Height: | Size: 270 KiB |