58 lines
2.6 KiB
Python
Executable File
58 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
"""Генерирует docs/estimate.md (с mermaid-графиками) и web/index.html."""
|
||
from pathlib import Path
|
||
import json, yaml
|
||
|
||
ROOT = Path(__file__).resolve().parent.parent
|
||
DATA, GEN, WEB = ROOT/"data", ROOT/"generated", ROOT/"web"
|
||
GEN.mkdir(exist_ok=True); WEB.mkdir(exist_ok=True)
|
||
|
||
def load(p): return yaml.safe_load(p.read_text())
|
||
|
||
def main():
|
||
comps = {c["id"]: c for c in load(DATA/"components.yaml")["items"]}
|
||
nodes = load(DATA/"nodes.yaml")["nodes"]
|
||
overrides = load(DATA/"prices.yaml").get("overrides") or {}
|
||
|
||
rows, per_node, per_cat, total = [], {}, {}, 0
|
||
for n in nodes:
|
||
nsum = 0
|
||
for it in n["items"]:
|
||
c = comps[it["component_id"]]
|
||
price = overrides.get(c["id"], it.get("price", c.get("price", 0)))
|
||
qty = it.get("qty", 1)
|
||
sub = price * qty
|
||
nsum += sub; total += sub
|
||
per_cat[c["category"]] = per_cat.get(c["category"], 0) + sub
|
||
rows.append((n["name"], c["category"], c["name"], qty, price, sub, c.get("links", [])))
|
||
per_node[n["name"]] = nsum
|
||
|
||
# ---------- markdown ----------
|
||
md = ["# Смета\n", f"**Итого: {total:,.0f} ₽**\n".replace(",", " "), "## Таблица\n"]
|
||
md.append("| Узел | Категория | Наименование | Кол-во | Цена, ₽ | Сумма, ₽ | Ссылки |")
|
||
md.append("|------|-----------|--------------|:------:|--------:|---------:|--------|")
|
||
for r in rows:
|
||
links = " · ".join(f"[{l['title']}]({l['url']})" for l in r[6])
|
||
md.append(f"| {r[0]} | {r[1]} | {r[2]} | {r[3]} | {r[4]:,} | {r[5]:,} | {links} |".replace(",", " "))
|
||
md += ["\n## Распределение по узлам\n", "```mermaid", "pie showData", ' title "Бюджет по узлам"']
|
||
for k, v in per_node.items(): md.append(f' "{k}" : {v}')
|
||
md.append("```\n")
|
||
md += ["## Распределение по категориям\n", "```mermaid", "pie showData", ' title "Бюджет по категориям"']
|
||
for k, v in per_cat.items(): md.append(f' "{k}" : {v}')
|
||
md.append("```")
|
||
(ROOT/"docs"/"estimate.md").write_text("\n".join(md))
|
||
|
||
# ---------- HTML-дашборд ----------
|
||
payload = {
|
||
"total": total,
|
||
"per_node": per_node,
|
||
"per_cat": per_cat,
|
||
"rows": [{"node":r[0],"cat":r[1],"name":r[2],"qty":r[3],"price":r[4],"sub":r[5],
|
||
"links":r[6]} for r in rows],
|
||
}
|
||
(WEB/"data.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2))
|
||
print(f"[OK] Итого: {total:,.0f} ₽".replace(",", " "))
|
||
|
||
if __name__ == "__main__":
|
||
main()
|