Problem Kunden gelöscht
Dieser Commit ist enthalten in:
@@ -296,10 +296,25 @@ def api_customer_licenses(customer_id):
|
|||||||
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
|
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
|
||||||
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices,
|
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices,
|
||||||
CASE
|
CASE
|
||||||
WHEN l.valid_until < CURRENT_DATE THEN 'expired'
|
WHEN l.valid_until < CURRENT_DATE THEN 'abgelaufen'
|
||||||
WHEN l.is_active = false THEN 'inactive'
|
WHEN l.valid_until < CURRENT_DATE + INTERVAL '30 days' THEN 'läuft bald ab'
|
||||||
ELSE 'active'
|
WHEN l.is_active = false THEN 'inaktiv'
|
||||||
END as status
|
ELSE 'aktiv'
|
||||||
|
END as status,
|
||||||
|
l.domain_count,
|
||||||
|
l.ipv4_count,
|
||||||
|
l.phone_count,
|
||||||
|
(SELECT COUNT(*) FROM device_registrations WHERE license_id = l.id AND is_active = TRUE) as active_devices,
|
||||||
|
-- Actual resource counts
|
||||||
|
(SELECT COUNT(*) FROM license_resources lr
|
||||||
|
JOIN resource_pools rp ON lr.resource_id = rp.id
|
||||||
|
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'domain') as actual_domain_count,
|
||||||
|
(SELECT COUNT(*) FROM license_resources lr
|
||||||
|
JOIN resource_pools rp ON lr.resource_id = rp.id
|
||||||
|
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'ipv4') as actual_ipv4_count,
|
||||||
|
(SELECT COUNT(*) FROM license_resources lr
|
||||||
|
JOIN resource_pools rp ON lr.resource_id = rp.id
|
||||||
|
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'phone') as actual_phone_count
|
||||||
FROM licenses l
|
FROM licenses l
|
||||||
WHERE l.customer_id = %s
|
WHERE l.customer_id = %s
|
||||||
ORDER BY l.created_at DESC
|
ORDER BY l.created_at DESC
|
||||||
@@ -307,11 +322,47 @@ def api_customer_licenses(customer_id):
|
|||||||
|
|
||||||
licenses = []
|
licenses = []
|
||||||
for row in cur.fetchall():
|
for row in cur.fetchall():
|
||||||
|
license_id = row[0]
|
||||||
|
|
||||||
|
# Hole die konkreten zugewiesenen Ressourcen für diese Lizenz
|
||||||
|
conn2 = get_connection()
|
||||||
|
cur2 = conn2.cursor()
|
||||||
|
cur2.execute("""
|
||||||
|
SELECT rp.id, rp.resource_type, rp.resource_value, lr.assigned_at
|
||||||
|
FROM resource_pools rp
|
||||||
|
JOIN license_resources lr ON rp.id = lr.resource_id
|
||||||
|
WHERE lr.license_id = %s AND lr.is_active = true
|
||||||
|
ORDER BY rp.resource_type, rp.resource_value
|
||||||
|
""", (license_id,))
|
||||||
|
|
||||||
|
resources = {
|
||||||
|
'domains': [],
|
||||||
|
'ipv4s': [],
|
||||||
|
'phones': []
|
||||||
|
}
|
||||||
|
|
||||||
|
for res_row in cur2.fetchall():
|
||||||
|
resource_data = {
|
||||||
|
'id': res_row[0],
|
||||||
|
'value': res_row[2],
|
||||||
|
'assigned_at': res_row[3].strftime('%Y-%m-%d %H:%M:%S') if res_row[3] else None
|
||||||
|
}
|
||||||
|
|
||||||
|
if res_row[1] == 'domain':
|
||||||
|
resources['domains'].append(resource_data)
|
||||||
|
elif res_row[1] == 'ipv4':
|
||||||
|
resources['ipv4s'].append(resource_data)
|
||||||
|
elif res_row[1] == 'phone':
|
||||||
|
resources['phones'].append(resource_data)
|
||||||
|
|
||||||
|
cur2.close()
|
||||||
|
conn2.close()
|
||||||
|
|
||||||
licenses.append({
|
licenses.append({
|
||||||
'id': row[0],
|
'id': row[0],
|
||||||
'license_key': row[1],
|
'license_key': row[1],
|
||||||
'license_type': row[2],
|
'license_type': row[2],
|
||||||
'active': row[3],
|
'is_active': row[3], # Korrigiert von 'active' zu 'is_active'
|
||||||
'is_test': row[4],
|
'is_test': row[4],
|
||||||
'valid_from': row[5].strftime('%Y-%m-%d') if row[5] else None,
|
'valid_from': row[5].strftime('%Y-%m-%d') if row[5] else None,
|
||||||
'valid_until': row[6].strftime('%Y-%m-%d') if row[6] else None,
|
'valid_until': row[6].strftime('%Y-%m-%d') if row[6] else None,
|
||||||
@@ -319,10 +370,19 @@ def api_customer_licenses(customer_id):
|
|||||||
'created_at': row[8].strftime('%Y-%m-%d %H:%M:%S') if row[8] else None,
|
'created_at': row[8].strftime('%Y-%m-%d %H:%M:%S') if row[8] else None,
|
||||||
'active_sessions': row[9],
|
'active_sessions': row[9],
|
||||||
'registered_devices': row[10],
|
'registered_devices': row[10],
|
||||||
'status': row[11]
|
'status': row[11],
|
||||||
|
'domain_count': row[12],
|
||||||
|
'ipv4_count': row[13],
|
||||||
|
'phone_count': row[14],
|
||||||
|
'active_devices': row[15],
|
||||||
|
'actual_domain_count': row[16],
|
||||||
|
'actual_ipv4_count': row[17],
|
||||||
|
'actual_phone_count': row[18],
|
||||||
|
'resources': resources
|
||||||
})
|
})
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
'success': True, # Wichtig: Frontend erwartet dieses Feld
|
||||||
'customer': {
|
'customer': {
|
||||||
'id': customer['id'],
|
'id': customer['id'],
|
||||||
'name': customer['name'],
|
'name': customer['name'],
|
||||||
|
|||||||
@@ -295,8 +295,15 @@ function loadCustomerLicenses(customerId) {
|
|||||||
container.innerHTML = '<div class="text-center py-5"><div class="spinner-border text-primary" role="status"></div></div>';
|
container.innerHTML = '<div class="text-center py-5"><div class="spinner-border text-primary" role="status"></div></div>';
|
||||||
|
|
||||||
fetch(`{{ url_for('customers.api_customer_licenses', customer_id=0) }}`.replace('0', customerId))
|
fetch(`{{ url_for('customers.api_customer_licenses', customer_id=0) }}`.replace('0', customerId))
|
||||||
.then(response => response.json())
|
.then(response => {
|
||||||
|
console.log('API Response Status:', response.status);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
console.log('API Response Data:', data);
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
// Update header with customer info
|
// Update header with customer info
|
||||||
const customerItem = document.querySelector(`[data-customer-id="${customerId}"]`);
|
const customerItem = document.querySelector(`[data-customer-id="${customerId}"]`);
|
||||||
@@ -320,11 +327,14 @@ function loadCustomerLicenses(customerId) {
|
|||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
updateLicenseView(customerId, data.licenses);
|
updateLicenseView(customerId, data.licenses);
|
||||||
|
} else {
|
||||||
|
console.error('API returned success: false', data);
|
||||||
|
container.innerHTML = '<div class="alert alert-warning">Keine Lizenzdaten gefunden</div>';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
container.innerHTML = '<div class="alert alert-danger">Fehler beim Laden der Lizenzen</div>';
|
container.innerHTML = `<div class="alert alert-danger">Fehler beim Laden der Lizenzen: ${error.message}</div>`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
v2_adminpanel/test_api.html
Normale Datei
38
v2_adminpanel/test_api.html
Normale Datei
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>API Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Test Customer Licenses API</h1>
|
||||||
|
<button onclick="testAPI()">Test API</button>
|
||||||
|
<pre id="result"></pre>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function testAPI() {
|
||||||
|
// Test mit einem bekannten Kunden
|
||||||
|
fetch('/api/customer/1/licenses')
|
||||||
|
.then(response => {
|
||||||
|
console.log('Response status:', response.status);
|
||||||
|
console.log('Response headers:', response.headers);
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then(text => {
|
||||||
|
console.log('Raw response:', text);
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(text);
|
||||||
|
console.log('Parsed data:', data);
|
||||||
|
document.getElementById('result').textContent = JSON.stringify(data, null, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Parse error:', e);
|
||||||
|
document.getElementById('result').textContent = 'Parse error: ' + e + '\n\nRaw response:\n' + text;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Fetch error:', error);
|
||||||
|
document.getElementById('result').textContent = 'Fetch error: ' + error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
In neuem Issue referenzieren
Einen Benutzer sperren