From 08e4e939ab096ee71b0c234985a3d13e12d95303 Mon Sep 17 00:00:00 2001 From: UserIsMH Date: Sat, 21 Jun 2025 20:15:50 +0200 Subject: [PATCH] Die UNterscheidung von Test und Echt Lizenzen ist strikter --- v2_adminpanel/routes/batch_routes.py | 59 +++++++++++++++++++++++++ v2_adminpanel/templates/batch_form.html | 29 ++++++++++-- v2_adminpanel/templates/index.html | 22 +++++++-- 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/v2_adminpanel/routes/batch_routes.py b/v2_adminpanel/routes/batch_routes.py index 0e3bcf1..266282f 100644 --- a/v2_adminpanel/routes/batch_routes.py +++ b/v2_adminpanel/routes/batch_routes.py @@ -42,6 +42,12 @@ def batch_create(): valid_from = request.form['valid_from'] valid_until = request.form['valid_until'] device_limit = int(request.form['device_limit']) + + # Resource allocation parameters + domain_count = int(request.form.get('domain_count', 0)) + ipv4_count = int(request.form.get('ipv4_count', 0)) + phone_count = int(request.form.get('phone_count', 0)) + # Validierung if count < 1 or count > 100: flash('Anzahl muss zwischen 1 und 100 liegen!', 'error') @@ -90,6 +96,59 @@ def batch_create(): 'license_key': license_key }) + # Allocate resources if requested + if domain_count > 0 or ipv4_count > 0 or phone_count > 0: + # Allocate domains + if domain_count > 0: + cur.execute(""" + UPDATE resource_pool + SET status = 'allocated', + license_id = %s, + allocated_at = NOW() + WHERE id IN ( + SELECT id FROM resource_pool + WHERE type = 'domain' + AND status = 'available' + AND is_fake = %s + ORDER BY id + LIMIT %s + ) + """, (license_id, is_fake, domain_count)) + + # Allocate IPv4s + if ipv4_count > 0: + cur.execute(""" + UPDATE resource_pool + SET status = 'allocated', + license_id = %s, + allocated_at = NOW() + WHERE id IN ( + SELECT id FROM resource_pool + WHERE type = 'ipv4' + AND status = 'available' + AND is_fake = %s + ORDER BY id + LIMIT %s + ) + """, (license_id, is_fake, ipv4_count)) + + # Allocate phones + if phone_count > 0: + cur.execute(""" + UPDATE resource_pool + SET status = 'allocated', + license_id = %s, + allocated_at = NOW() + WHERE id IN ( + SELECT id FROM resource_pool + WHERE type = 'phone' + AND status = 'available' + AND is_fake = %s + ORDER BY id + LIMIT %s + ) + """, (license_id, is_fake, phone_count)) + # Audit-Log log_audit('CREATE', 'license', license_id, new_values={ diff --git a/v2_adminpanel/templates/batch_form.html b/v2_adminpanel/templates/batch_form.html index 10036dc..51f1d78 100644 --- a/v2_adminpanel/templates/batch_form.html +++ b/v2_adminpanel/templates/batch_form.html @@ -236,8 +236,7 @@ function calculateValidUntil() { break; } - // Ein Tag abziehen, da der Starttag mitgezählt wird - endDate.setDate(endDate.getDate() - 1); + // Kein Tag abziehen - die Lizenz ist bis einschließlich des Enddatums gültig document.getElementById('validUntil').value = endDate.toISOString().split('T')[0]; } @@ -252,6 +251,9 @@ document.addEventListener('DOMContentLoaded', function() { const today = new Date().toISOString().split('T')[0]; document.getElementById('validFrom').value = today; + // Initialize customer is_fake map + window.customerIsFakeMap = {}; + // Berechne initiales Ablaufdatum calculateValidUntil(); @@ -273,8 +275,15 @@ document.addEventListener('DOMContentLoaded', function() { processResults: function (data, params) { params.page = params.page || 1; - // "Neuer Kunde" Option immer oben anzeigen + // Store is_fake status for each customer const results = data.results || []; + results.forEach(customer => { + if (customer.id !== 'new') { + window.customerIsFakeMap[customer.id] = customer.is_fake || false; + } + }); + + // "Neuer Kunde" Option immer oben anzeigen if (params.page === 1) { results.unshift({ id: 'new', @@ -330,6 +339,9 @@ document.addEventListener('DOMContentLoaded', function() { showCustomerTypeIndicator(e.params.data.is_fake ? 'fake' : 'real'); } } + + // Update resource availability check when customer changes + checkResourceAvailability(); }); // Clear handler @@ -339,6 +351,8 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('customerName').required = false; document.getElementById('email').required = false; hideCustomerTypeIndicator(); + window.customerIsFakeMap = {}; + checkResourceAvailability(); }); // Resource Availability Check @@ -393,8 +407,15 @@ function checkResourceAvailability() { document.getElementById('ipv4Needed').textContent = totalIpv4; document.getElementById('phoneNeeded').textContent = totalPhones; + // Get customer's is_fake status + const selectedCustomer = document.getElementById('customer_id'); + let isFake = 'false'; + if (selectedCustomer && selectedCustomer.value && window.customerIsFakeMap) { + isFake = window.customerIsFakeMap[selectedCustomer.value] ? 'true' : 'false'; + } + // API-Call zur Verfügbarkeitsprüfung - fetch(`/api/resources/check-availability?domain=${totalDomains}&ipv4=${totalIpv4}&phone=${totalPhones}`) + fetch(`/api/resources/check-availability?domain=${totalDomains}&ipv4=${totalIpv4}&phone=${totalPhones}&is_fake=${isFake}`) .then(response => response.json()) .then(data => { // Update der Verfügbarkeitsanzeigen diff --git a/v2_adminpanel/templates/index.html b/v2_adminpanel/templates/index.html index c5deab2..faa7c21 100644 --- a/v2_adminpanel/templates/index.html +++ b/v2_adminpanel/templates/index.html @@ -270,8 +270,7 @@ function calculateValidUntil() { break; } - // Ein Tag abziehen, da der Starttag mitgezählt wird - endDate.setDate(endDate.getDate() - 1); + // Kein Tag abziehen - die Lizenz ist bis einschließlich des Enddatums gültig document.getElementById('validUntil').value = endDate.toISOString().split('T')[0]; } @@ -366,6 +365,9 @@ document.addEventListener('DOMContentLoaded', function() { nameInput.required = true; emailInput.required = true; + // New customers are currently hardcoded as fake (TODO in backend) + window.selectedCustomerIsFake = true; + // Zeige Indikator für neuen Kunden showCustomerTypeIndicator('new'); } else { @@ -377,11 +379,17 @@ document.addEventListener('DOMContentLoaded', function() { nameInput.value = ''; emailInput.value = ''; + // Store customer's is_fake status + window.selectedCustomerIsFake = e.params.data.is_fake || false; + // Zeige Indikator basierend auf Kundendaten if (e.params.data.is_fake !== undefined) { showCustomerTypeIndicator(e.params.data.is_fake ? 'fake' : 'real'); } } + + // Update resource availability check with new customer status + checkResourceAvailability(); }); // Clear handler @@ -390,9 +398,14 @@ document.addEventListener('DOMContentLoaded', function() { document.getElementById('emailDiv').style.display = 'none'; document.getElementById('customerName').required = false; document.getElementById('email').required = false; + window.selectedCustomerIsFake = false; + checkResourceAvailability(); hideCustomerTypeIndicator(); }); + // Store selected customer's is_fake status + window.selectedCustomerIsFake = false; + // Resource Availability Check checkResourceAvailability(); @@ -408,8 +421,11 @@ function checkResourceAvailability() { const ipv4Count = parseInt(document.getElementById('ipv4Count').value) || 0; const phoneCount = parseInt(document.getElementById('phoneCount').value) || 0; + // Include is_fake parameter based on selected customer + const isFake = window.selectedCustomerIsFake ? 'true' : 'false'; + // API-Call zur Verfügbarkeitsprüfung - fetch(`{{ url_for('api.check_resource_availability') }}?domain=${domainCount}&ipv4=${ipv4Count}&phone=${phoneCount}`) + fetch(`{{ url_for('api.check_resource_availability') }}?domain=${domainCount}&ipv4=${ipv4Count}&phone=${phoneCount}&is_fake=${isFake}`) .then(response => response.json()) .then(data => { // Update der Verfügbarkeitsanzeigen