Ressource-Pool
Dieser Commit ist enthalten in:
@@ -91,6 +91,67 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Resource Pool Allocation -->
|
||||
<div class="card mt-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-server"></i> Ressourcen-Zuweisung pro Lizenz
|
||||
<small class="text-muted float-end" id="resourceStatus"></small>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label for="domainCount" class="form-label">
|
||||
<i class="fas fa-globe"></i> Domains
|
||||
</label>
|
||||
<select class="form-select" id="domainCount" name="domain_count" required>
|
||||
{% for i in range(11) %}
|
||||
<option value="{{ i }}" {% if i == 1 %}selected{% endif %}>{{ i }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<small class="form-text text-muted">
|
||||
Verfügbar: <span id="domainsAvailable" class="fw-bold">-</span>
|
||||
| Benötigt: <span id="domainsNeeded" class="fw-bold">-</span>
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="ipv4Count" class="form-label">
|
||||
<i class="fas fa-network-wired"></i> IPv4-Adressen
|
||||
</label>
|
||||
<select class="form-select" id="ipv4Count" name="ipv4_count" required>
|
||||
{% for i in range(11) %}
|
||||
<option value="{{ i }}" {% if i == 1 %}selected{% endif %}>{{ i }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<small class="form-text text-muted">
|
||||
Verfügbar: <span id="ipv4Available" class="fw-bold">-</span>
|
||||
| Benötigt: <span id="ipv4Needed" class="fw-bold">-</span>
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="phoneCount" class="form-label">
|
||||
<i class="fas fa-phone"></i> Telefonnummern
|
||||
</label>
|
||||
<select class="form-select" id="phoneCount" name="phone_count" required>
|
||||
{% for i in range(11) %}
|
||||
<option value="{{ i }}" {% if i == 1 %}selected{% endif %}>{{ i }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<small class="form-text text-muted">
|
||||
Verfügbar: <span id="phoneAvailable" class="fw-bold">-</span>
|
||||
| Benötigt: <span id="phoneNeeded" class="fw-bold">-</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning mt-3 mb-0" role="alert">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Batch-Ressourcen:</strong> Jede Lizenz erhält die angegebene Anzahl an Ressourcen.
|
||||
Bei 10 Lizenzen mit je 2 Domains werden insgesamt 20 Domains benötigt.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
🔑 Batch generieren
|
||||
@@ -243,6 +304,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('customerName').required = false;
|
||||
document.getElementById('email').required = false;
|
||||
});
|
||||
|
||||
// Resource Availability Check
|
||||
checkResourceAvailability();
|
||||
|
||||
// Event Listener für Resource Count und Quantity Änderungen
|
||||
document.getElementById('domainCount').addEventListener('change', checkResourceAvailability);
|
||||
document.getElementById('ipv4Count').addEventListener('change', checkResourceAvailability);
|
||||
document.getElementById('phoneCount').addEventListener('change', checkResourceAvailability);
|
||||
document.getElementById('quantity').addEventListener('input', checkResourceAvailability);
|
||||
});
|
||||
|
||||
// Vorschau-Funktion
|
||||
@@ -269,5 +339,96 @@ document.getElementById('quantity').addEventListener('input', function(e) {
|
||||
e.target.value = 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Funktion zur Prüfung der Ressourcen-Verfügbarkeit für Batch
|
||||
function checkResourceAvailability() {
|
||||
const quantity = parseInt(document.getElementById('quantity').value) || 1;
|
||||
const domainCount = parseInt(document.getElementById('domainCount').value) || 0;
|
||||
const ipv4Count = parseInt(document.getElementById('ipv4Count').value) || 0;
|
||||
const phoneCount = parseInt(document.getElementById('phoneCount').value) || 0;
|
||||
|
||||
// Berechne Gesamtbedarf
|
||||
const totalDomains = domainCount * quantity;
|
||||
const totalIpv4 = ipv4Count * quantity;
|
||||
const totalPhones = phoneCount * quantity;
|
||||
|
||||
// Update "Benötigt" Anzeigen
|
||||
document.getElementById('domainsNeeded').textContent = totalDomains;
|
||||
document.getElementById('ipv4Needed').textContent = totalIpv4;
|
||||
document.getElementById('phoneNeeded').textContent = totalPhones;
|
||||
|
||||
// API-Call zur Verfügbarkeitsprüfung
|
||||
fetch(`/api/resources/check-availability?domain=${totalDomains}&ipv4=${totalIpv4}&phone=${totalPhones}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Update der Verfügbarkeitsanzeigen
|
||||
updateAvailabilityDisplay('domainsAvailable', data.domain_available, totalDomains);
|
||||
updateAvailabilityDisplay('ipv4Available', data.ipv4_available, totalIpv4);
|
||||
updateAvailabilityDisplay('phoneAvailable', data.phone_available, totalPhones);
|
||||
|
||||
// Gesamtstatus aktualisieren
|
||||
updateBatchResourceStatus(data, totalDomains, totalIpv4, totalPhones, quantity);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler bei Verfügbarkeitsprüfung:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// Hilfsfunktion zur Anzeige der Verfügbarkeit
|
||||
function updateAvailabilityDisplay(elementId, available, requested) {
|
||||
const element = document.getElementById(elementId);
|
||||
element.textContent = available;
|
||||
|
||||
const neededElement = element.parentElement.querySelector('.fw-bold:last-child');
|
||||
|
||||
if (requested > 0 && available < requested) {
|
||||
element.classList.remove('text-success');
|
||||
element.classList.add('text-danger');
|
||||
neededElement.classList.add('text-danger');
|
||||
neededElement.classList.remove('text-success');
|
||||
} else if (available < 50) {
|
||||
element.classList.remove('text-success', 'text-danger');
|
||||
element.classList.add('text-warning');
|
||||
} else {
|
||||
element.classList.remove('text-danger', 'text-warning');
|
||||
element.classList.add('text-success');
|
||||
neededElement.classList.remove('text-danger');
|
||||
neededElement.classList.add('text-success');
|
||||
}
|
||||
}
|
||||
|
||||
// Gesamtstatus der Ressourcen-Verfügbarkeit für Batch
|
||||
function updateBatchResourceStatus(data, totalDomains, totalIpv4, totalPhones, quantity) {
|
||||
const statusElement = document.getElementById('resourceStatus');
|
||||
let hasIssue = false;
|
||||
let message = '';
|
||||
|
||||
if (totalDomains > 0 && data.domain_available < totalDomains) {
|
||||
hasIssue = true;
|
||||
message = `⚠️ Nicht genügend Domains (${data.domain_available}/${totalDomains})`;
|
||||
} else if (totalIpv4 > 0 && data.ipv4_available < totalIpv4) {
|
||||
hasIssue = true;
|
||||
message = `⚠️ Nicht genügend IPv4-Adressen (${data.ipv4_available}/${totalIpv4})`;
|
||||
} else if (totalPhones > 0 && data.phone_available < totalPhones) {
|
||||
hasIssue = true;
|
||||
message = `⚠️ Nicht genügend Telefonnummern (${data.phone_available}/${totalPhones})`;
|
||||
} else {
|
||||
message = `✅ Ressourcen für ${quantity} Lizenzen verfügbar`;
|
||||
}
|
||||
|
||||
statusElement.textContent = message;
|
||||
statusElement.className = hasIssue ? 'text-danger' : 'text-success';
|
||||
|
||||
// Disable submit button if not enough resources
|
||||
const submitButton = document.querySelector('button[type="submit"]');
|
||||
submitButton.disabled = hasIssue;
|
||||
if (hasIssue) {
|
||||
submitButton.classList.add('btn-secondary');
|
||||
submitButton.classList.remove('btn-primary');
|
||||
} else {
|
||||
submitButton.classList.add('btn-primary');
|
||||
submitButton.classList.remove('btn-secondary');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren