255 lines
8.5 KiB
Python
255 lines
8.5 KiB
Python
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() |