Fix M365 summary: per-product totals row and QWE Client-based missing assignments
- Total row now sums each license column individually instead of using colspan - Missing Assignment warning now flags licensed users with no QWE Client set, replacing the previous department-based company check Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -110,7 +110,7 @@ def _apply_overrides(users: list[dict], db: Session) -> list[dict]:
|
||||
|
||||
def _calculate_summary(users: list[dict]) -> dict:
|
||||
licensed = [u for u in users if u["is_licensed"]]
|
||||
missing = [u for u in licensed if not u["company"]]
|
||||
missing = [u for u in licensed if not u["qwe_client"].strip()]
|
||||
|
||||
# Per-QWE-Client breakdown (primary goal)
|
||||
client_groups: dict[str, list] = defaultdict(list)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
<!-- Missing assignments -->
|
||||
<details class="bg-amber-50 border border-amber-200 rounded-lg">
|
||||
<summary class="px-5 py-3 text-sm font-medium text-amber-800 cursor-pointer select-none">
|
||||
Missing Company Assignments ({{ summary.missing | length }}) — licensed users not in QWE AT / QWE SK / KFC AT / KFC SK / QWE
|
||||
Missing QWE Client Assignment ({{ summary.missing | length }}) — licensed users without a QWE Client set
|
||||
</summary>
|
||||
<ul class="px-5 pb-4 pt-2 text-xs text-amber-700 space-y-1 max-h-48 overflow-y-auto">
|
||||
{% for u in summary.missing %}
|
||||
@@ -362,11 +362,18 @@
|
||||
return;
|
||||
}
|
||||
|
||||
let grandCost = 0, grandUsers = 0;
|
||||
let grandCost = 0, grandUsers = 0,
|
||||
grandStd = 0, grandBasic = 0, grandDef = 0, grandPbiPro = 0, grandPbiPrem = 0;
|
||||
|
||||
const rowHtml = rows.map(r => {
|
||||
const cost = rowCost(r);
|
||||
grandCost += cost;
|
||||
grandUsers += r.count;
|
||||
grandCost += cost;
|
||||
grandUsers += r.count;
|
||||
grandStd += r.m365_standard;
|
||||
grandBasic += r.m365_basic;
|
||||
grandDef += r.defender_p1;
|
||||
grandPbiPro += r.pbi_pro;
|
||||
grandPbiPrem += r.pbi_premium;
|
||||
return `
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2 font-medium text-gray-900 whitespace-nowrap">${escHtml(r.name)}</td>
|
||||
@@ -384,7 +391,11 @@
|
||||
<tr class="bg-gray-50 border-t-2 border-gray-200 font-semibold text-sm">
|
||||
<td class="px-4 py-2 text-gray-900">Total</td>
|
||||
<td class="px-4 py-2 text-center text-gray-700">${grandUsers}</td>
|
||||
<td colspan="5"></td>
|
||||
<td class="px-4 py-2 text-center text-blue-700">${fmt(grandStd)}</td>
|
||||
<td class="px-4 py-2 text-center text-sky-700">${fmt(grandBasic)}</td>
|
||||
<td class="px-4 py-2 text-center text-orange-700">${fmt(grandDef)}</td>
|
||||
<td class="px-4 py-2 text-center text-purple-700">${fmt(grandPbiPro)}</td>
|
||||
<td class="px-4 py-2 text-center text-red-700">${fmt(grandPbiPrem)}</td>
|
||||
<td class="px-4 py-2 text-right text-gray-900 whitespace-nowrap">${fmtEur(grandCost)}</td>
|
||||
</tr>`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user