import streamlit as st import pandas as pd from data.scriptloader import get_sql from data.db import get_conn from auth_runtime import require_login from ui.sidebar import build_sidebar, hide_sidebar_if_logged_out from auth import get_fullname_for_user from sqlalchemy import text import duckdb import altair as alt from tools.helpers import display_value, calc_variance_pct # hide_sidebar_if_logged_out() st.set_page_config(page_title="Co-App Home", page_icon="🏠", layout="wide") authenticator = require_login() st.session_state["authenticator"] = authenticator DISPLAY_UNIT = "Mio. €" def load_data(): sql = get_sql("ergebnis_kpi") engine = get_conn("co_dw") with engine.connect() as conn: df = pd.read_sql(text(sql), con=conn, params={"jahr": 2025, "monat": 12}) return df # def calc_variance_pct(actual, plan): # variance = actual - plan # if plan == 0: # return None # if actual * plan < 0: # return None # return variance / abs(plan) def build_dashboard(): df = load_data() # st.dataframe(df) be_ist_kum = df["akt_jahr"].sum() #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Kalkulation KPI Betriebsergebnis #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ operating_result_actual_ytd = df["akt_jahr_bis_monat"].sum() operating_result_actual_ytd_str = f"{int(operating_result_actual_ytd)/ANZ_EINHEIT:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + " Mio. €" operating_result_plan_ytd = df["plan_akt_jahr_bis_monat"].sum() operating_result_actual_ytd_py = df["vor_jahr_bis_monat"].sum() operating_result_variance = operating_result_actual_ytd - operating_result_plan_ytd operating_result_vaiance_pct = calc_variance_pct(operating_result_actual_ytd, operating_result_plan_ytd) #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Dashboard - Ebene 1 Betriebsergebnis #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ col_1, col_2 = st.columns(2, border=True,vertical_alignment="center") with col_1: st.metric(label="Betriebsergebnis", value=operating_result_actual_ytd) operation_result_monthly = df["akt_jahr_monat"].sum() be_ist_vorjahr_kum = df["vor_jahr"].sum() be_ist_monat = df["akt_jahr_monat"].sum() be_ist_vorjahr_monat = df["vor_jahr_monat"].sum() be_ist_kum_anz = f"{int(be_ist_kum)/ANZ_EINHEIT:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + " Mio. €" be_ist_monat_anz = f"{int(be_ist_monat)/ANZ_EINHEIT:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + " Mio. €" be_ist_vorjahr_kum_anz = f"{int(be_ist_vorjahr_kum)/ANZ_EINHEIT:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + " Mio. €" be_ist_monat_vorjahr_anz = f"{int(be_ist_vorjahr_monat)/ANZ_EINHEIT:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".") + " Mio. €" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Ebene 1 - Ergebnis-KPIs #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Beispiel-Daten (ersetze das durch deine echten Monatswerte) months = pd.date_range(end=pd.Timestamp.today().normalize(), periods=12, freq="MS") values = pd.Series([120, 80, -30, 50, 40, 10, -20, 60, 70, 30, 20, -10], index=months) df = pd.DataFrame({"month": months, "BE": values}).set_index("month") current = df["BE"].iloc[-1] prev = df["BE"].iloc[-2] delta = current - prev col1, col2, col3 = st.columns(3) with col1: st.metric( "Betriebsergebnis (intern)", f"{current:,.0f} €", f"{delta:,.0f} €" ) with st.expander("Verlauf letzte 12 Monate", expanded=False): # st.bar_chart(df["BE"]) # fig, ax = plt.subplots() # ax.plot(df.index, df["BE"], marker="o") # ax.axhline(0, linewidth=1) # Nulllinie für negative Werte # ax.set_xlabel("") # ax.set_ylabel("€") # ax.tick_params(axis="x", rotation=45) # st.pyplot(fig, clear_figure=True) df_reset = df.reset_index() df_reset["Monat"] = df_reset["month"].dt.strftime("%Y-%m") chart = ( alt.Chart(df_reset) .mark_bar(size=28) # Balkendicke .encode( x=alt.X("Monat:N", sort=None, title=""), y=alt.Y("BE:Q", title="€"), color=alt.condition( alt.datum.BE < 0, alt.value("#d62728"), # rot alt.value("#2ca02c"), # grün ) ) ) labels = ( alt.Chart(df_reset) .mark_text(dy=-8) .encode( x="Monat:N", y="BE:Q", text=alt.Text("BE:Q", format=",.0f") ) ) spark = ( alt.Chart(df_reset) .mark_line(point=True) .encode( x=alt.X("Monat:N", axis=None), y=alt.Y("BE:Q", axis=None) ) .properties(height=60) ) st.altair_chart(spark, use_container_width=True) # st.altair_chart(chart + labels, use_container_width=True) # col_operating_result, col_contribution_margin = st.columns(2,border=True) # col_ue_n, col_ae_f, col_ab_f = st.columns(3,border=True,) # with col_ue_n: # with st.expander(label="Umsatz",): # st.metric(label="BE-Ist kumuliert (monat)",value=f"{be_ist_kum_anz} ({be_ist_monat_anz})", delta="-5", border=True) # st.text("Umsatz") # with col_ae_f: # st.text("Auftragseingang fest") # with col_ab_f: # st.text("Auftragsbestand fest") # with col_operating_result: # internal_operating_result = f"BE = {be_ist_kum_anz} Mio. €" # st.metric(label="BE-Ist kumuliert (monat)",value=f"{internal_operating_result} ({be_ist_monat_anz})", delta="-5", border=True) # with st.expander(label=st.markdown(f"# {internal_operating_result}")): # st.text("Verlauf...") # # st.text("ERGTAB") # st.metric(label="BE-Ist kumuliert (monat)",value=f"{be_ist_kum_anz} ({be_ist_monat_anz})", delta="-5", border=True) # erg = duckdb.sql(""" # select # 'Umsatz' as Kostenart, # sum(case when co_koa_grp = 'CO1000' then akt_jahr else 0 end) as Aktuell, # sum(case when co_koa_grp = 'CO1000' then plan_akt_jahr else 0 end) as Plan, # sum(case when co_koa_grp = 'CO1000' then vor_jahr else 0 end) as Vorjahr # from # df # """).fetchdf() # st.metric(label="BE-Ist kumuliert (monat)",value=f"{be_ist_kum_anz} ({be_ist_monat_anz})", delta="-5", border=True) # st.dataframe(erg, hide_index=True) # col_erg_ist = st.columns(1) # with col_erg_ist: # st.metric(label="BE-Ist (monat)",value=be_ist_monat_anz, delta="-5", border=True) # col1, col2 = st.columns(2) # with col1: # # st.metric(label="BE-Ist (kumuliert)",value=be_ist_kum_anz, delta="-5", border=True) # with st.success("Ergebnis"): # st.button(f"{be_ist_kum_anz}") # # st.success("plus 10% zu Vorjahr") # # with col2: # # st.error("-10% zu Plan") # # with col_erg_plan: # # st.info("minus 5%") # # st.warning("minus 10%") # # st.success("plus 10%") # # st.error("minus 20%") # # with col_erg_vorjahr: # # st.metric(label="BE-Vorjahr (kumuliert)",value=be_ist_vorjahr_kum_anz, delta="-5", border=True) # # st.metric(label="BE-Vorjahr (monat)",value=be_ist_monat_anz, delta="-5", border=True) # # st.dataframe(load_data()) if __name__ == "__main__": df = build_dashboard()