Spaces:
Running
Running
Make KPI card in Inventory tab filter by the item selected in the table
Browse files- streamlit_app.py +42 -4
streamlit_app.py
CHANGED
|
@@ -2386,13 +2386,51 @@ with tab_inv:
|
|
| 2386 |
& (inv_filt["Date"].dt.month == _m_sel)
|
| 2387 |
]
|
| 2388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2389 |
# ββ KPI tiles β total Value_Used in the month + per-customer rate
|
| 2390 |
# Customers for the same month come from kpi_daily, filtered by
|
| 2391 |
# the same sidebar Restaurant / Branch filters so the ratio is
|
| 2392 |
# consistent with whichever scope the user is viewing.
|
| 2393 |
_value_used_total = (
|
| 2394 |
-
float(
|
| 2395 |
-
if "Value_Used" in
|
| 2396 |
)
|
| 2397 |
_cust_in_month = kpi_daily.copy() if not kpi_daily.empty else pd.DataFrame()
|
| 2398 |
if not _cust_in_month.empty and "Date" in _cust_in_month.columns:
|
|
@@ -2412,8 +2450,8 @@ with tab_inv:
|
|
| 2412 |
_value_per_cust = (_value_used_total / _cust_total) if _cust_total > 0 else None
|
| 2413 |
|
| 2414 |
_qty_used_total = (
|
| 2415 |
-
float(
|
| 2416 |
-
if "Qty_Used" in
|
| 2417 |
)
|
| 2418 |
_qty_per_cust = (_qty_used_total / _cust_total) if _cust_total > 0 else None
|
| 2419 |
|
|
|
|
| 2386 |
& (inv_filt["Date"].dt.month == _m_sel)
|
| 2387 |
]
|
| 2388 |
|
| 2389 |
+
# ββ Read prior table selection (if any) BEFORE computing KPIs ββββ
|
| 2390 |
+
# `st.dataframe(on_select="rerun", key="inv_table")` (rendered
|
| 2391 |
+
# further down) stores its selection in st.session_state under
|
| 2392 |
+
# that key. By reading it here at the top of the rerun we can
|
| 2393 |
+
# use the picked item to filter both the KPI tiles AND the
|
| 2394 |
+
# downstream charts β keeping all three in sync.
|
| 2395 |
+
_ranked_preview = (
|
| 2396 |
+
latest_rows[latest_rows[sort_by] > 0]
|
| 2397 |
+
.sort_values(sort_by, ascending=False)
|
| 2398 |
+
.head(100)
|
| 2399 |
+
)
|
| 2400 |
+
_selected_item: "str | None" = None
|
| 2401 |
+
_prior_table_state = st.session_state.get("inv_table")
|
| 2402 |
+
if _prior_table_state is not None and "Item" in _ranked_preview.columns:
|
| 2403 |
+
try:
|
| 2404 |
+
# The state object exposes `.selection.rows` in recent
|
| 2405 |
+
# Streamlit; fall back to dict access for older builds.
|
| 2406 |
+
if hasattr(_prior_table_state, "selection"):
|
| 2407 |
+
_sel_rows = list(_prior_table_state.selection.rows)
|
| 2408 |
+
elif isinstance(_prior_table_state, dict):
|
| 2409 |
+
_sel_rows = list(_prior_table_state.get("selection", {}).get("rows", []))
|
| 2410 |
+
else:
|
| 2411 |
+
_sel_rows = []
|
| 2412 |
+
if _sel_rows:
|
| 2413 |
+
_i = _sel_rows[0]
|
| 2414 |
+
if 0 <= _i < len(_ranked_preview):
|
| 2415 |
+
_selected_item = str(_ranked_preview.iloc[_i]["Item"])
|
| 2416 |
+
except Exception:
|
| 2417 |
+
_selected_item = None
|
| 2418 |
+
|
| 2419 |
+
# KPI source rows: when a row is selected, narrow to just that
|
| 2420 |
+
# item; otherwise use the full month-filtered set.
|
| 2421 |
+
_kpi_rows = (
|
| 2422 |
+
latest_rows[latest_rows["Item"] == _selected_item]
|
| 2423 |
+
if (_selected_item is not None and "Item" in latest_rows.columns)
|
| 2424 |
+
else latest_rows
|
| 2425 |
+
)
|
| 2426 |
+
|
| 2427 |
# ββ KPI tiles β total Value_Used in the month + per-customer rate
|
| 2428 |
# Customers for the same month come from kpi_daily, filtered by
|
| 2429 |
# the same sidebar Restaurant / Branch filters so the ratio is
|
| 2430 |
# consistent with whichever scope the user is viewing.
|
| 2431 |
_value_used_total = (
|
| 2432 |
+
float(_kpi_rows["Value_Used"].sum())
|
| 2433 |
+
if "Value_Used" in _kpi_rows.columns else 0.0
|
| 2434 |
)
|
| 2435 |
_cust_in_month = kpi_daily.copy() if not kpi_daily.empty else pd.DataFrame()
|
| 2436 |
if not _cust_in_month.empty and "Date" in _cust_in_month.columns:
|
|
|
|
| 2450 |
_value_per_cust = (_value_used_total / _cust_total) if _cust_total > 0 else None
|
| 2451 |
|
| 2452 |
_qty_used_total = (
|
| 2453 |
+
float(_kpi_rows["Qty_Used"].sum())
|
| 2454 |
+
if "Qty_Used" in _kpi_rows.columns else 0.0
|
| 2455 |
)
|
| 2456 |
_qty_per_cust = (_qty_used_total / _cust_total) if _cust_total > 0 else None
|
| 2457 |
|