feat: Implement invoice generation and emailing functionality

- Added invoice generation logic using DomPDF.
- Integrated invoice data retrieval from the API.
- Implemented language determination for invoices based on customer data.
- Added options to email invoices to customers and admin.
- Included HTML output option for direct viewing in the browser.
- Ensured proper redirection and error handling throughout the process.
This commit is contained in:
“VeLiTi”
2026-01-07 14:36:48 +01:00
parent 543f0b3cac
commit 08263c7933
46 changed files with 4982 additions and 151 deletions

View File

@@ -122,7 +122,7 @@ $view .= '<div class="content-block">
<div id="connectdevice" style="display:flex; gap: 10px; margin-bottom: 20px;">
<button class="btn" id="connectButton" onClick="connectDeviceForSoftware()" style="min-width: 150px;">
<i class="fa-solid fa-plug"></i>Connect
<i class="fa-solid fa-plug"></i> Connect
</button>
<div id="readStatus" style="flex: 1; background-color: #f1f1f1; border-radius: 4px; overflow: hidden;">
<div id="readBar" style="height: 100%; transition: width 0.3s ease;"></div>
@@ -143,10 +143,10 @@ $view .= '<div class="content-block">
</div>
</div>
<div id="noUpdatesMessage" style="margin: 20px 0; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 12px; text-align: center; display:none;">
<i class="fa-solid fa-check-circle" style="font-size: 48px; margin-bottom: 15px;"></i>
<p style="margin: 0; font-size: 18px; font-weight: 500;"><strong>'.$softwaretool_no_updates.'</strong></p>
<p style="margin: 10px 0 0 0; opacity: 0.9;">Your device is up to date</p>
<div id="noUpdatesMessage" style="margin: 20px 0; padding: 30px; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 3px; text-align: center; display:none; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
<i class="fa-solid fa-check-circle" style="font-size: 48px; margin-bottom: 15px; color: #28a745;"></i>
<p style="margin: 0; font-size: 18px; font-weight: 600; color: #155724;"><strong>'.$softwaretool_no_updates.'</strong></p>
<p style="margin: 10px 0 0 0; color: #6c757d; font-size: 14px;">Your device is up to date</p>
</div>
<div id="uploadSection" style="margin-top: 10px; display:none;">
@@ -157,6 +157,8 @@ $view .= '<div class="content-block">
disabled>Install Software
<span class="upload-progress"></span>
</button>
<!-- Hidden checkbox that upload.js expects -->
<input type="checkbox" id="action_firmware" style="display:none;">
</div>
</div>
</div>
@@ -245,6 +247,108 @@ echo '
closePaymentModal();
}
});
// Monitor upload completion
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === "attributes" && mutation.attributeName === "checked") {
const actionFirmware = document.getElementById("action_firmware");
if (actionFirmware && actionFirmware.checked) {
console.log("Upload completion detected!");
// Upload completed successfully
handleUploadCompletion(true);
}
}
});
});
// Also monitor for readBar changes to detect completion
const readBarObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === "childList" || mutation.type === "characterData") {
const readBar = document.getElementById("readBar");
if (readBar && readBar.innerHTML && readBar.innerHTML.includes("Firmware update completed")) {
console.log("Firmware update completed detected via readBar!");
setTimeout(() => handleUploadCompletion(true), 500);
}
}
});
});
// Start observing when upload section is visible
function startUploadMonitoring() {
const actionFirmware = document.getElementById("action_firmware");
const readBar = document.getElementById("readBar");
if (actionFirmware) {
observer.observe(actionFirmware, {
attributes: true,
attributeFilter: ["checked"]
});
console.log("Started monitoring action_firmware checkbox");
}
if (readBar) {
readBarObserver.observe(readBar, {
childList: true,
subtree: true,
characterData: true
});
console.log("Started monitoring readBar for completion");
}
}
// Handle upload completion (success or failure)
window.handleUploadCompletion = function(success) {
console.log("handleUploadCompletion called with success:", success);
const installStatus = document.getElementById("installationStatus");
const readBar = document.getElementById("readBar");
if (success) {
// Success handling
console.log("Updating UI for successful completion");
if (installStatus) {
installStatus.innerHTML = \'\' +
\'<i class="fa-solid fa-check-circle" style="font-size: 48px; color: #28a745; margin-bottom: 15px;"></i>\' +
\'<p style="margin: 0; font-size: 18px; font-weight: 600; color: #155724;">Installation Complete!</p>\' +
\'<p style="margin: 5px 0 0 0; color: #666; font-size: 14px;">Your device has been successfully updated</p>\';
}
// Ensure progress bar is at 100%
if (readBar) {
readBar.style.width = "100%";
readBar.style.background = "#04AA6D";
readBar.innerHTML = "Firmware update completed - 100%";
console.log("Updated readBar to 100%");
}
} else {
// Failure handling
console.log("Updating UI for failed completion");
if (installStatus) {
installStatus.innerHTML = \'\' +
\'<i class="fa-solid fa-exclamation-circle" style="font-size: 48px; color: #dc3545; margin-bottom: 15px;"></i>\' +
\'<p style="margin: 0; font-size: 18px; font-weight: 600; color: #721c24;">Installation Failed</p>\' +
\'<p style="margin: 5px 0 0 0; color: #666; font-size: 14px;">Please try again or contact support</p>\';
}
if (readBar) {
readBar.style.width = "100%";
readBar.style.background = "#dc3545";
readBar.innerHTML = "Installation failed";
}
}
// Stop monitoring
observer.disconnect();
readBarObserver.disconnect();
console.log("Stopped monitoring observers");
};
// Monitor for upload errors
window.addEventListener("error", function(e) {
if (e.message && e.message.includes("upload")) {
handleUploadCompletion(false);
}
});
</script>';
template_footer();