Enhance payment processing by adding VAT number handling and updating transaction retrieval logic. Refactor user role migration script for improved role assignments and streamline software tool functionality with maintenance mode checks and UI updates.

This commit is contained in:
“VeLiTi”
2026-01-29 19:25:13 +01:00
parent 0723df4516
commit 90472e3673
10 changed files with 154 additions and 150 deletions

BIN
.DS_Store vendored

Binary file not shown.

1
.gitignore vendored
View File

@@ -27,3 +27,4 @@ api/.DS_Store
assets/.DS_Store
assets/images/.DS_Store
assets/database/ManualUpdates.sql
assets/database/migration_users_to_rbac.sql

View File

@@ -49,7 +49,7 @@ if (!$transaction) {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
$sql = 'SELECT * FROM transactions_items WHERE txn_id = ? LIMIT 1';
$stmt = $pdo->prepare($sql);
$stmt->execute([$payment_id]);
$stmt->execute([$transaction['id']]);
$item = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$item) {

View File

@@ -29,6 +29,7 @@ $payment_provider = $post_content['payment_provider'] ?? $user_data['payment_pro
$item_price = $user_data['item_price'] ?? null; // Price without VAT
$tax_amount = $user_data['tax_amount'] ?? 0; // VAT amount
$payment_amount = $user_data['payment_amount'] ?? null; // Total including VAT
$vat_number = $user_data['vat_number'] ?? null; // VAT number
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
// STEP 1: Get equipment data from serial_number
@@ -328,8 +329,8 @@ try {
$partner_product = json_encode(array("salesid"=>$partner->salesid,"soldto"=>$partner->soldto), JSON_UNESCAPED_UNICODE);
$sql = 'INSERT INTO transactions (txn_id, payment_amount, tax_amount, payment_status, payer_email, first_name, last_name,
address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, accounthierarchy, created)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, accounthierarchy, created, vat_number)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
$txn_id,
@@ -347,7 +348,8 @@ try {
$serial_number,
$payment_method_id, // 0 = Mollie, 1 = PayPal
$partner_product,
date('Y-m-d H:i:s')
date('Y-m-d H:i:s'),
$vat_number
]);
// Get the database ID

BIN
assets/.DS_Store vendored

Binary file not shown.

View File

@@ -11,127 +11,70 @@ START TRANSACTION;
-- MAPPING REFERENCE:
--
-- users.settings field values -> role names:
-- 'standard_profile' or empty with view 0-2 -> Standard
-- 'superuser_profile' or view=2 -> Superuser
-- 'admin_profile' or view=4 -> Admin
-- 'adminplus_profile' or view=5 -> AdminPlus
-- 'build' -> Build
-- 'commerce' -> Commerce
-- 'admin_profile' or view=4 -> TSS_Admin
-- 'distribution' -> Distribution
-- 'firmware' -> Firmware
-- 'garage' -> Garage
-- 'interface' -> Interface
-- 'service' -> Service
-- 'other' -> Other
-- 'firmware' -> Software_Tool
-- 'interface' -> Interface
-- 'superuser_profile' or view=1 -> Service
-- All others (including empty/NULL) -> Service
--
-- users.view field (legacy permission level):
-- 1 = SuperUser
-- 2 = Create & Update
-- 3 = Read-only
-- 4 = Admin
-- 5 = Admin+
-- IGNORED/REMOVED PROFILES:
-- 'standard_profile', 'adminplus_profile', 'build', 'commerce',
-- 'garage', 'other'
-- ===================================================
-- Get role IDs
SET @role_standard = (SELECT rowID FROM user_roles WHERE name = 'Standard' LIMIT 1);
SET @role_superuser = (SELECT rowID FROM user_roles WHERE name = 'Superuser' LIMIT 1);
SET @role_admin = (SELECT rowID FROM user_roles WHERE name = 'Admin' LIMIT 1);
SET @role_adminplus = (SELECT rowID FROM user_roles WHERE name = 'AdminPlus' LIMIT 1);
SET @role_build = (SELECT rowID FROM user_roles WHERE name = 'Build' LIMIT 1);
SET @role_commerce = (SELECT rowID FROM user_roles WHERE name = 'Commerce' LIMIT 1);
SET @role_tss_admin = (SELECT rowID FROM user_roles WHERE name = 'TSS_Admin' LIMIT 1);
SET @role_distribution = (SELECT rowID FROM user_roles WHERE name = 'Distribution' LIMIT 1);
SET @role_firmware = (SELECT rowID FROM user_roles WHERE name = 'Firmware' LIMIT 1);
SET @role_garage = (SELECT rowID FROM user_roles WHERE name = 'Garage' LIMIT 1);
SET @role_interface = (SELECT rowID FROM user_roles WHERE name = 'Interface' LIMIT 1);
SET @role_service = (SELECT rowID FROM user_roles WHERE name = 'Service' LIMIT 1);
SET @role_other = (SELECT rowID FROM user_roles WHERE name = 'Other' LIMIT 1);
SET @role_software_tool = (SELECT rowID FROM user_roles WHERE name = 'Software_Tool' LIMIT 1);
SET @role_interface = (SELECT rowID FROM user_roles WHERE name = 'Interface' LIMIT 1);
-- ===================================================
-- PHASE 1: MIGRATE USERS BY SETTINGS FIELD (profile name)
-- ===================================================
-- Users with 'standard_profile' setting
-- Users with 'admin_profile' setting -> TSS_Admin
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_standard, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'standard_profile'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'superuser_profile' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_superuser, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'superuser_profile'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'admin_profile' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_admin, 1, 'migration_script', NOW(), NOW(), 1
SELECT id, @role_tss_admin, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'admin_profile'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'adminplus_profile' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_adminplus, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'adminplus_profile'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'build' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_build, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'build'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'commerce' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_commerce, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'commerce'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'distribution' setting
-- Users with 'distribution' setting -> Distribution
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_distribution, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'distribution'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'firmware' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_firmware, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'firmware'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'garage' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_garage, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'garage'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'interface' setting
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_interface, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'interface'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'service' setting
-- Users with 'service' setting -> Service
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_service, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'service'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'other' setting
-- Users with 'firmware' setting -> Software_Tool
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_other, 1, 'migration_script', NOW(), NOW(), 1
SELECT id, @role_software_tool, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'other'
WHERE settings = 'firmware'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'interface' setting -> Interface
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_interface, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'interface'
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with 'superuser_profile' setting -> Service
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT id, @role_service, 1, 'migration_script', NOW(), NOW(), 1
FROM users
WHERE settings = 'superuser_profile'
ON DUPLICATE KEY UPDATE updated = NOW();
-- ===================================================
@@ -139,19 +82,9 @@ ON DUPLICATE KEY UPDATE updated = NOW();
-- Only for users not already assigned a role
-- ===================================================
-- Users with view=5 (Admin+) and no settings
-- Users with view=4 (Admin) and no settings -> TSS_Admin
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT u.id, @role_adminplus, 1, 'migration_script', NOW(), NOW(), 1
FROM users u
LEFT JOIN user_role_assignments ura ON u.id = ura.user_id AND ura.is_active = 1
WHERE (u.settings IS NULL OR u.settings = '')
AND u.view = '5'
AND ura.rowID IS NULL
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with view=4 (Admin) and no settings
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT u.id, @role_admin, 1, 'migration_script', NOW(), NOW(), 1
SELECT u.id, @role_tss_admin, 1, 'migration_script', NOW(), NOW(), 1
FROM users u
LEFT JOIN user_role_assignments ura ON u.id = ura.user_id AND ura.is_active = 1
WHERE (u.settings IS NULL OR u.settings = '')
@@ -159,32 +92,12 @@ WHERE (u.settings IS NULL OR u.settings = '')
AND ura.rowID IS NULL
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with view=1 (SuperUser) and no settings
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT u.id, @role_superuser, 1, 'migration_script', NOW(), NOW(), 1
FROM users u
LEFT JOIN user_role_assignments ura ON u.id = ura.user_id AND ura.is_active = 1
WHERE (u.settings IS NULL OR u.settings = '')
AND u.view = '1'
AND ura.rowID IS NULL
ON DUPLICATE KEY UPDATE updated = NOW();
-- Users with view=2 or view=3 (Create/Update or Read-only) and no settings -> Standard
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT u.id, @role_standard, 1, 'migration_script', NOW(), NOW(), 1
FROM users u
LEFT JOIN user_role_assignments ura ON u.id = ura.user_id AND ura.is_active = 1
WHERE (u.settings IS NULL OR u.settings = '')
AND u.view IN ('2', '3')
AND ura.rowID IS NULL
ON DUPLICATE KEY UPDATE updated = NOW();
-- ===================================================
-- PHASE 3: CATCH-ALL - Any remaining users without role -> Standard
-- PHASE 3: CATCH-ALL - Any remaining users without role -> Service
-- ===================================================
INSERT INTO `user_role_assignments` (`user_id`, `role_id`, `is_active`, `assigned_by`, `assigned_at`, `created`, `createdby`)
SELECT u.id, @role_standard, 1, 'migration_script', NOW(), NOW(), 1
SELECT u.id, @role_service, 1, 'migration_script', NOW(), NOW(), 1
FROM users u
LEFT JOIN user_role_assignments ura ON u.id = ura.user_id AND ura.is_active = 1
WHERE ura.rowID IS NULL

View File

@@ -1728,11 +1728,12 @@ function getProfile($profile, $permission){
'application' => 'CRU',
'user_role_assignments' => 'R',
'user_permissions' => 'R',
'products_software' => 'R',
'software_update' => 'R',
'software_download' => 'R',
'software_available' => 'R',
'history' => 'RU',
'payment' => 'U'
'payment' => 'RU'
];
// 1. Check if basic_permission_level is 4 (System-admin+) - always allow

View File

@@ -203,11 +203,27 @@ async function connectDeviceForSoftware() {
//clear input
readBar.innerHTML = '';
serialResultsDiv.innerHTML = '';
// Clear installation status if it exists
const installStatus = document.getElementById("installationStatus");
if (installStatus) {
installStatus.remove();
}
document.getElementById("softwareCheckStatus").style.display = "none";
document.getElementById("softwareOptionsContainer").style.display = "none";
document.getElementById("noUpdatesMessage").style.display = "none";
document.getElementById("uploadSection").style.display = "none";
// Reset softwareOptions visibility and blur state
const softwareOptions = document.getElementById("softwareOptions");
if (softwareOptions) {
softwareOptions.style.display = "block";
softwareOptions.style.filter = "blur(8px)";
softwareOptions.style.opacity = "0.3";
softwareOptions.style.pointerEvents = "none";
}
// Reset data
receivedDataBuffer = '';
deviceSerialNumber = "";
@@ -596,11 +612,14 @@ async function fetchSoftwareOptions() {
document.getElementById("softwareOptionsContainer").style.display = "block";
progressBar("100", "Software options loaded", "#04AA6D");
// Show user info modal immediately (skip in debug mode)
if (typeof DEBUG === 'undefined' || !DEBUG || typeof DEBUG_ID === 'undefined' || !DEBUG_ID) {
// Check if customer data already exists in sessionStorage
const savedCustomerData = sessionStorage.getItem('customerData');
// Show user info modal only if no saved data and not in debug mode
if ((typeof DEBUG === 'undefined' || !DEBUG || typeof DEBUG_ID === 'undefined' || !DEBUG_ID) && !savedCustomerData) {
showUserInfoModal();
} else {
// In debug mode, reveal software options immediately
// Customer data already exists or debug mode - reveal software options immediately
const softwareOptions = document.getElementById("softwareOptions");
if (softwareOptions) {
softwareOptions.style.filter = "none";

View File

@@ -56,6 +56,11 @@ $retry = 0;
// Process submitted form data
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Check maintenance mode exception
if (maintenance_mode && trim($_POST['username']) != maintenance_mode_user) {
$username_err = maintenance_mode_text ?? 'System in maintenance';
} else {
// Check if username is empty
if(empty(trim($_POST['username']))){
$username_err = $username_enter ?? 'Please enter username' ;
@@ -106,6 +111,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Display an error for passord mismatch
$password_err = $password_err_3 ?? 'Not authorized';
}
} // Close maintenance mode check
}
echo'
<!DOCTYPE html>
@@ -115,6 +121,63 @@ echo'
<title>'.site_title.'</title>
<link rel="shortcut icon" href="'.icon_image.'" type="image/x-icon" />
<link href="'.$custom_css.'" rel="stylesheet" type="text/css">
<style>
.maintenance-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
box-sizing: border-box;
}
.maintenance-modal.hidden {
display: none !important;
}
.maintenance-modal-content {
background: white;
padding: 30px;
border-radius: 4px;
text-align: center;
max-width: 500px;
width: 100%;
margin: auto;
position: relative;
}
.maintenance-modal-content p {
margin-bottom: 20px;
font-size: 16px;
color: #333;
line-height: 1.5;
}
.modal-close {
position: absolute;
top: 10px;
right: 15px;
font-size: 28px;
font-weight: bold;
color: #999;
cursor: pointer;
transition: color 0.3s;
}
.modal-close:hover {
color: #333;
}
@media (max-width: 768px) {
.maintenance-modal-content {
padding: 20px;
max-width: 90%;
}
.maintenance-modal-content p {
font-size: 14px;
}
}
</style>
</head>
<body>
';
@@ -126,17 +189,19 @@ echo'
<div class="logo"></div>
<a href="register.php" class="register-link">'.strtolower($account_create ?? 'create account').'</a>';
if (maintenance_mode)
{
//Maintenance mode is on => Show maintenance mode text
if (maintenance_mode) {
echo '
<div class="message">
<div id="maintenanceModal" class="maintenance-modal">
<div class="maintenance-modal-content">
<span class="modal-close" onclick="dismissMaintenanceModal()">&times;</span>
<p>'.maintenance_mode_text.'</p>
<p style="text-align: center;">
<small>'.maintenance_mode_notification.'</small>
</p>
</div>
';
</div>';
}
} else {
//Maintenance mode is off => Show login
echo '
<div class="header">
<h1>'.($login_h1 ?? 'Login to your account').'</h1>
@@ -158,7 +223,6 @@ echo'
<button type="submit" class="login-btn">'.($button1 ?? 'Login').'</button>
</form>';
}
if($password_err !='' || $username_err != ''){
echo'
@@ -194,13 +258,17 @@ echo'
</div>
</body>
<script>
document.getElementById(\'language-selector\').addEventListener(\'change\', function() {
if (this.value) {
// Get the current URL
let currentUrl = window.location.pathname;
function dismissMaintenanceModal() {
var modal = document.getElementById("maintenanceModal");
if (modal) {
modal.classList.add("hidden");
}
}
// Append the selected value as a query parameter
window.location.href = `${currentUrl}?language=${this.value}`;
document.getElementById("language-selector").addEventListener("change", function() {
if (this.value) {
var currentUrl = window.location.pathname;
window.location.href = currentUrl + "?language=" + this.value;
}
});
</script>

View File

@@ -393,7 +393,7 @@ echo '
console.log("Step 2: Fetching payment details...");
const serviceToken = document.getElementById("servicetoken")?.innerHTML || \'\';
const paymentResponse = await fetch(link + `/v2/payment?payment_id=${orderId}`, {
const paymentResponse = await fetch(link + `/v2/payment/payment_id=${orderId}`, {
method: "GET",
headers: {
"Authorization": "Bearer " + serviceToken