Refactor permission checks across multiple files to utilize isAllowed function for better access control management. Updated hierarchy level checks in account, contracts, equipments, partners, users, and API endpoints to streamline permission validation. Enhanced download options visibility based on user permissions in various reports and management pages. Improved modal behavior and auto-installation process in software tool after payment success. Added new helper functions for building dynamic where clauses based on user hierarchy levels.
This commit is contained in:
139
softwaretool.php
139
softwaretool.php
@@ -124,16 +124,19 @@ if ($payment_return && $payment_return_status) {
|
||||
$payment_modal = '
|
||||
<div id="paymentModal" class="modal" style="display: flex; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center;">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; max-width: 500px; margin: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); position: relative;">
|
||||
<span class="close" onclick="closePaymentModal()" style="position: absolute; top: 15px; right: 20px; font-size: 28px; font-weight: bold; color: #999; cursor: pointer;">×</span>
|
||||
<div style="text-align: center; padding: 40px 30px;">
|
||||
<i class="fa-solid fa-check-circle" style="font-size: 64px; color: #28a745; margin-bottom: 20px;"></i>
|
||||
<i class="fa-solid fa-spinner fa-spin" style="font-size: 64px; color: #28a745; margin-bottom: 20px;"></i>
|
||||
<h2 style="color: #155724; margin-bottom: 15px;">Payment Successful!</h2>
|
||||
<p style="margin-bottom: 10px; color: #333;">Your payment has been processed. Please reconnect your device to apply the software upgrade.</p>
|
||||
<p style="margin-bottom: 10px; color: #333;">Preparing your software installation...</p>
|
||||
<p style="font-size: 12px; color: #666; margin-bottom: 25px;">Order ID: '.htmlspecialchars($payment_return).'</p>
|
||||
<button onclick="closePaymentModal()" class="btn" style="padding: 12px 30px;">Continue</button>
|
||||
<p style="font-size: 14px; color: #666;">Please keep your device connected</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
</div>
|
||||
<script>
|
||||
// Trigger automatic installation after payment success
|
||||
window.PAYMENT_SUCCESS_ORDER_ID = "'.htmlspecialchars($payment_return).'";
|
||||
</script>';
|
||||
} else if ($transaction['payment_status'] == 0 || $transaction['payment_status'] == 101) {
|
||||
// Payment pending
|
||||
$payment_modal = '
|
||||
@@ -362,6 +365,132 @@ echo '
|
||||
}
|
||||
};
|
||||
|
||||
// Automatically trigger installation after successful payment
|
||||
window.triggerAutoInstallAfterPayment = async function() {
|
||||
if (typeof window.PAYMENT_SUCCESS_ORDER_ID === \'undefined\') {
|
||||
return; // Not a payment success return
|
||||
}
|
||||
|
||||
const orderId = window.PAYMENT_SUCCESS_ORDER_ID;
|
||||
console.log("Payment success detected for order:", orderId);
|
||||
|
||||
try {
|
||||
// Step 1: Connect to device and read serial number, version, hardware
|
||||
console.log("Step 1: Connecting to device and reading information...");
|
||||
await connectDeviceForSoftware();
|
||||
|
||||
// Wait for device reading to complete
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
// Step 2: Verify device is connected and serial number is read
|
||||
if (!deviceSerialNumber) {
|
||||
throw new Error("Device not connected or serial number not read. Please ensure your device is connected.");
|
||||
}
|
||||
|
||||
console.log("Device connected - SN:", deviceSerialNumber, "Version:", deviceVersion, "HW:", deviceHwVersion);
|
||||
|
||||
// Step 3: Fetch payment details to get the purchased version_id
|
||||
console.log("Step 2: Fetching payment details...");
|
||||
const serviceToken = document.getElementById("servicetoken")?.innerHTML || \'\';
|
||||
|
||||
const paymentResponse = await fetch(link + `/v2/payment?payment_id=${orderId}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": "Bearer " + serviceToken
|
||||
}
|
||||
});
|
||||
|
||||
if (!paymentResponse.ok) {
|
||||
throw new Error("Could not verify payment details");
|
||||
}
|
||||
|
||||
const paymentData = await paymentResponse.json();
|
||||
console.log("Payment data:", paymentData);
|
||||
|
||||
const purchasedVersionId = paymentData.version_id;
|
||||
if (!purchasedVersionId) {
|
||||
throw new Error("No version_id found in payment data");
|
||||
}
|
||||
|
||||
console.log("Purchased version_id:", purchasedVersionId);
|
||||
|
||||
// Step 4: Call software_update API to get available options
|
||||
// After payment, the purchased version should now be free (price = 0)
|
||||
console.log("Step 3: Fetching software options from software_update...");
|
||||
const updateUrl = link + "/v2/software_update/sn=" + deviceSerialNumber +
|
||||
(deviceVersion ? "&version=" + deviceVersion : "") +
|
||||
(deviceHwVersion ? "&hw_version=" + deviceHwVersion : "");
|
||||
|
||||
const updateResponse = await fetch(updateUrl, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": "Bearer " + serviceToken,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
const options = await updateResponse.json();
|
||||
console.log("Software options received:", options);
|
||||
|
||||
if (options.error || !options || options.length === 0) {
|
||||
throw new Error("No software updates available for this device");
|
||||
}
|
||||
|
||||
// Step 5: Find the purchased version by matching version_id
|
||||
// After payment, it should be returned with price = 0 (free/licensed)
|
||||
const selectedOption = options.find(opt => opt.version_id === purchasedVersionId);
|
||||
|
||||
if (!selectedOption) {
|
||||
throw new Error(`Purchased version (ID: ${purchasedVersionId}) not found in available options. Please try manually.`);
|
||||
}
|
||||
|
||||
// Verify it has a download source
|
||||
if (!selectedOption.source) {
|
||||
throw new Error("Selected software option has no download link");
|
||||
}
|
||||
|
||||
console.log("Found purchased version:", selectedOption);
|
||||
console.log("Version price:", selectedOption.price, "(should be 0 after license activation)");
|
||||
await logCommunication(`Auto-install: Starting installation of ${selectedOption.name} v${selectedOption.version} (version_id: ${purchasedVersionId})`, \'sent\');
|
||||
|
||||
// Step 6: Start automatic installation
|
||||
console.log("Step 4: Starting installation...");
|
||||
await downloadAndInstallSoftware(selectedOption);
|
||||
|
||||
// Close the payment modal after starting installation
|
||||
setTimeout(() => {
|
||||
closePaymentModal();
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Auto-installation failed:", error);
|
||||
await logCommunication(`Auto-installation error: ${error.message}`, \'error\');
|
||||
|
||||
// Update modal to show error with actionable message
|
||||
const modal = document.getElementById("paymentModal");
|
||||
if (modal) {
|
||||
const modalContent = modal.querySelector(\'.modal-content > div\');
|
||||
if (modalContent) {
|
||||
modalContent.innerHTML = `
|
||||
<i class="fa-solid fa-exclamation-circle" style="font-size: 64px; color: #dc3545; margin-bottom: 20px;"></i>
|
||||
<h2 style="color: #721c24; margin-bottom: 15px;">Auto-Installation Failed</h2>
|
||||
<p style="margin-bottom: 10px; color: #333;">${error.message}</p>
|
||||
<p style="font-size: 14px; color: #666; margin-bottom: 25px;">Please close this popup and manually connect your device to install the software.</p>
|
||||
<button onclick="closePaymentModal()" class="btn" style="padding: 12px 30px;">Continue</button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Trigger auto-install when payment success is detected
|
||||
if (typeof window.PAYMENT_SUCCESS_ORDER_ID !== \'undefined\') {
|
||||
// Wait for page to fully load and JavaScript to initialize, then trigger
|
||||
setTimeout(() => {
|
||||
triggerAutoInstallAfterPayment();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Close modal on background click
|
||||
document.addEventListener("click", function(e) {
|
||||
const helpModal = document.getElementById("helpModal");
|
||||
|
||||
Reference in New Issue
Block a user