#!/usr/bin/env python3
import json
from weasyprint import HTML
s=json.load(open("stats.json"))
def eur(x): return f"{x:,.2f}".replace(",","X").replace(".",",").replace("X",".")
def pct(a,b): return f"{(b/a-1)*100:+.1f}".replace(".",",")+" %"
tot_d=s['tot_r']-s['tot_b']
mat_d=s['mat_r']-s['mat_b']; mach_d=s['mach_r']-s['mach_b']
pers_d=s['pers_r']-s['pers_b']; sur_d=s['sur_r']-s['sur_b']

top_rows="".join(
 f"<tr><td>{t}</td><td>{p or '—'}</td><td class='n'>{eur(b)}</td><td class='n'>{eur(r)}</td>"
 f"<td class='n'>{eur(r-b)}</td><td class='n pos'>{pct(b,r)}</td></tr>"
 for t,p,b,r in s['top'])

html=f"""<!doctype html><html><head><meta charset='utf-8'><style>
@page {{ size:A4; margin:10mm 13mm; }}
* {{ font-family:'Inter','Helvetica Neue',Arial,sans-serif; box-sizing:border-box; }}
body {{ color:#1a2227; font-size:9.3pt; line-height:1.34; }}
h1 {{ font-size:17pt; margin:0; color:#037493; letter-spacing:-.3px; }}
.sub {{ color:#5b6b73; font-size:8.5pt; margin:2px 0 0; }}
.bar {{ height:3px; background:#037493; margin:8px 0 12px; border-radius:2px; }}
.kpi {{ display:flex; gap:10px; margin:0 0 12px; }}
.kpi .box {{ flex:1; border:1.5px solid #037493; border-radius:4px; padding:9px 11px; }}
.kpi .box.red {{ border-color:#c0392b; }}
.kpi .big {{ font-size:19pt; font-weight:700; color:#037493; }}
.kpi .box.red .big {{ color:#c0392b; }}
.kpi .lbl {{ font-size:7.6pt; color:#5b6b73; text-transform:uppercase; letter-spacing:.4px; }}
h2 {{ font-size:10.5pt; color:#037493; margin:9px 0 4px; border-bottom:1px solid #d7e3e7; padding-bottom:2px; }}
.para {{ background:#eef6f8; border-left:3px solid #037493; padding:8px 11px; border-radius:0 4px 4px 0; margin:6px 0; }}
table {{ width:100%; border-collapse:collapse; margin:4px 0; font-size:8.6pt; }}
th {{ background:#037493; color:#fff; text-align:left; padding:4px 6px; font-weight:600; }}
td {{ padding:3px 6px; border-bottom:1px solid #e6edef; }}
td.n {{ text-align:right; font-variant-numeric:tabular-nums; }}
.pos {{ color:#c0392b; font-weight:600; }} .neg {{ color:#1e8449; font-weight:600; }}
.lever {{ margin:4px 0; padding:6px 10px; background:#fafbfb; border:1px solid #e6edef; border-radius:4px; }}
.lever b {{ color:#037493; }}
.ask {{ font-size:8.7pt; }} .ask li {{ margin:3px 0; }}
.foot {{ margin-top:14px; font-size:7.4pt; color:#90a0a6; border-top:1px solid #e6edef; padding-top:6px; }}
.flag {{ display:inline-block; background:#fff3b0; border:1px solid #e8cf5a; border-radius:3px; padding:0 5px; font-size:7.6pt; }}
</style></head><body>

<h1>BMW QAF G60 DP — Verhandlungs-Briefing</h1>
<p class="sub">Basis (RIK 24Q4) vs. RePricing (RIK 26Q1) · {s['reiter']} Bauteil-Positionen · Werte je Teilesatz (EUR) · erstellt durch SupplierPulse</p>
<div class="bar"></div>

<div class="kpi">
  <div class="box red"><div class="lbl">Angebotspreis gesamt</div><div class="big">{pct(s['tot_b'],s['tot_r'])}</div><div class="sub">{eur(s['tot_b'])} → {eur(s['tot_r'])} € &nbsp;(+{eur(tot_d)} €)</div></div>
  <div class="box"><div class="lbl">Materialkosten</div><div class="big neg" style="color:#1e8449">{pct(s['mat_b'],s['mat_r'])}</div><div class="sub">wird günstiger</div></div>
  <div class="box red"><div class="lbl">Zuschläge</div><div class="big">{pct(s['sur_b'],s['sur_r'])}</div><div class="sub">mehr als verdoppelt</div></div>
</div>

<div class="para"><b>Die Kernaussage:</b> Der Angebotspreis steigt um <b>+{eur(tot_d)} € (+{pct(s['tot_b'],s['tot_r']).strip('+')})</b> — obwohl die <b>Materialkosten des Lieferanten um {pct(s['mat_b'],s['mat_r'])} sinken</b>. Der gesamte Anstieg kommt aus Maschinen-Stundensätzen, einem neuen Ineffizienz-Aufschlag und verdoppelten Gemeinkosten-/Gewinn-Aufschlägen — nicht aus echten Mehrkosten.</div>

<h2>Wo der Anstieg herkommt (Σ über alle Positionen)</h2>
<table>
<tr><th>Kostenblock</th><th>Basis €</th><th>RePricing €</th><th>Delta €</th><th>Delta %</th></tr>
<tr><td>Material gesamt</td><td class="n">{eur(s['mat_b'])}</td><td class="n">{eur(s['mat_r'])}</td><td class="n">{eur(mat_d)}</td><td class="n neg">{pct(s['mat_b'],s['mat_r'])}</td></tr>
<tr><td>Maschine</td><td class="n">{eur(s['mach_b'])}</td><td class="n">{eur(s['mach_r'])}</td><td class="n">{eur(mach_d)}</td><td class="n pos">{pct(s['mach_b'],s['mach_r'])}</td></tr>
<tr><td>Personal (Lohn)</td><td class="n">{eur(s['pers_b'])}</td><td class="n">{eur(s['pers_r'])}</td><td class="n">{eur(pers_d)}</td><td class="n pos">{pct(s['pers_b'],s['pers_r'])}</td></tr>
<tr><td>Zuschläge (Overhead/Gewinn)</td><td class="n">{eur(s['sur_b'])}</td><td class="n">{eur(s['sur_r'])}</td><td class="n">{eur(sur_d)}</td><td class="n pos">{pct(s['sur_b'],s['sur_r'])}</td></tr>
</table>

<h2>Die 3 Haupthebel — und wie wir sie kontern</h2>
<div class="lever"><b>1 · Maschinen-Stundensatz ×2,95 (+195 %)</b> — identischer Faktor über fast alle Teile. Kein bauteilbezogener Mehraufwand, sondern eine zentrale Stellschraube. <i>Forderung:</i> Maschinenstundensatz-Kalkulation + Benchmark offenlegen; Anstieg ist nicht plausibel.</div>
<div class="lever"><b>2 · Neuer Ineffizienz-Aufschlag 55 % auf Lohn</b> — gleichzeitig wurde der sichtbare Lohnsatz gesenkt (DE 44,33 → 38 €/h). Netto-Lohnkosten trotzdem +32,9 %. <i>Forderung:</i> 55 % Ineffizienz streichen oder begründen — das ist eine versteckte Preiserhöhung.</div>
<div class="lever"><b>3 · Gemeinkosten Material 7 → 16,6 % &amp; Gewinn Material 3 → 6 %</b> — Aufschläge verdoppelt, obwohl der Granulat-Einkauf 9–30 % billiger wurde. <i>Forderung:</i> Einkaufsvorteil durchreichen; Aufschlagssätze auf Basis-Niveau zurück.</div>

<h2>Bauteile mit größtem Preissprung (€) — einzeln prüfen</h2>
<table>
<tr><th>Reiter</th><th>Bauteil</th><th>Basis €</th><th>RePricing €</th><th>Delta €</th><th>Delta %</th></tr>
{top_rows}
</table>
<p class="ask"><span class="flag">Achtung Anomalie</span> &nbsp;Positionen {", ".join(s['partspec'])} weichen vom globalen Maschinen-Hebel ab → hier liegt eine <b>bauteilspezifische</b> Änderung (Prozess/Scope) vor, die getrennt zu hinterfragen ist.</p>

<div class="foot">Quelle: 100 - G60_DP_QAF_Basis_24_10_BMW.xlsm · 20260508_BMW QAF_G60_DP_RePricing_HO.xlsm. Detailvergleich aller {s['reiter']} Positionen siehe Excel „QAF_Vergleich_G60_DP.xlsx". Vertraulich — enthält Lieferanten-Kalkulationsdaten.</div>
</body></html>"""
open("onepager.html","w").write(html)
HTML(string=html).write_pdf("Verhandlung_1Pager_G60_DP.pdf")
print("PDF written")
