← Files ClaraARCHIVED FILE
vendor/modules/courseware/sales_plan_view.py
3.76 KB · Oct 5, 2026 · 00:02 UTC
"""Readable views of native Plan CSVs; no calculation or source mutation."""
from __future__ import annotations
import csv
import html
import io
def _esc(value):
return html.escape(str(value), quote=True)
def _number(value, language):
raw = str(value or "")
# Format native decimal strings without changing precision or rounding.
sign = raw[:1] if raw[:1] in "+-" else ""
unsigned = raw[len(sign) :]
whole, dot, fraction = unsigned.partition(".")
if not whole.isdigit() or (dot and not fraction.isdigit()):
return _esc(raw)
decimal, separator = (
(".", ",")
if language == "en"
else (",", "." if language in {"it", "de", "es"} else "\u202f")
)
grouped = f"{int(whole):,}".replace(",", separator)
return _esc(sign + grouped + (decimal + fraction if dot else ""))
def sales_plan_body(name: str, text: str, ui: dict, language: str) -> str:
rows = list(csv.DictReader(io.StringIO(text)))
labels = ui["sales_plan"]
metrics = labels["metrics"]
blocks = []
if name == "scenario_summary.csv":
groups = {}
for row in rows:
key = (row["summary_level"], row["dimension_name"], row["dimension_value"])
groups.setdefault(key, []).append(row)
for (level, dimension, value), members in sorted(
groups.items(), key=lambda item: item[0][0] != "total"
):
title = (
labels["total"]
if level == "total"
else labels.get(dimension, dimension) + ": " + value
)
heads = [
labels[k]
for k in ["metric", "unit", "actual", "plan", "delta", "percent"]
]
body = []
for row in members:
values = [
_esc(metrics.get(row["metric"], row["metric"])),
_esc(labels.get(row["unit"], row["unit"])),
]
values.extend(
_number(row[k], language)
for k in ["actual", "plan", "delta", "delta_pct_rounded_4dp"]
)
body.append("<tr>" + "".join(f"<td>{v}</td>" for v in values) + "</tr>")
blocks.append(f"<h3>{_esc(title)}</h3>" + _table(heads, body))
else:
groups = {}
for row in rows:
groups.setdefault(row["assumption_id"], []).append(row)
for assumption, members in groups.items():
heads = [
labels[k]
for k in [
"source",
"period",
"driver",
"before",
"after",
"percent",
"status",
]
]
body = []
for row in members:
values = [
_esc(row["source_row_id"]),
_esc(row["target_period"]),
_esc(metrics.get(row["driver"], row["driver"])),
]
values.extend(
_number(row[k], language)
for k in ["before_value", "after_value", "change_pct"]
)
values.append(_esc(labels.get(row["status"], row["status"])))
body.append("<tr>" + "".join(f"<td>{v}</td>" for v in values) + "</tr>")
blocks.append(
f"<h3>{_esc(labels['assumption'])}: {_esc(assumption)}</h3>"
+ _table(heads, body)
)
return "".join(blocks)
def _table(heads, body):
return (
"<div class='table-scroll' tabindex='0'><table><thead><tr>"
+ "".join(f"<th scope='col'>{_esc(h)}</th>" for h in heads)
+ "</tr></thead><tbody>"
+ "".join(body)
+ "</tbody></table></div>"
)
SHA-256: 115977d03c034ed5f363d6fd5c8c82648ed1349067ac61e48d0701b10caa7e7b