42 lines
1.9 KiB
Python
42 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
# ruff: noqa: F405
|
|
|
|
|
|
import streamlit as st
|
|
|
|
from dashboard.common import * # noqa: F403, F405
|
|
|
|
def page_transactions(db_path: str) -> None:
|
|
category_options, _ = get_category_options(db_path)
|
|
people_df = read_sql(db_path, "SELECT DISTINCT person FROM transactions WHERE status='active' AND person<>'' ORDER BY person")
|
|
people = people_df["person"].tolist() if not people_df.empty else []
|
|
col1, col2, col3, col4, col5 = st.columns(5)
|
|
start = col1.date_input("시작일", value=None)
|
|
end = col2.date_input("종료일", value=None)
|
|
category = col3.selectbox("카테고리", ["전체"] + [c for c in category_options if c])
|
|
person = col4.selectbox("인원", ["전체"] + people)
|
|
text = col5.text_input("사용처 검색")
|
|
clauses = ["t.status='active'"]
|
|
params: list[Any] = []
|
|
if start:
|
|
clauses.append("t.transaction_date>=?"); params.append(str(start))
|
|
if end:
|
|
clauses.append("t.transaction_date<=?"); params.append(str(end))
|
|
if category != "전체":
|
|
clauses.append("t.category=?"); params.append(category)
|
|
if person != "전체":
|
|
clauses.append("t.person=?"); params.append(person)
|
|
if text:
|
|
clauses.append("t.merchant LIKE ?"); params.append(f"%{text}%")
|
|
df = transaction_df(db_path, "WHERE " + " AND ".join(clauses), tuple(params), limit=2000)
|
|
st.dataframe(df.drop(columns=["id", "amount", "balance_after", "is_fixed"], errors="ignore"), width="stretch", height=500)
|
|
|
|
if not df.empty:
|
|
render_section_label("✏️", "선택 거래 수정")
|
|
options = {f"{r.transaction_datetime or r.transaction_date} · {r.merchant} · {format_krw(r.amount)} · {r.category or '미분류'}": r.id for r in df.itertuples()}
|
|
label = st.selectbox("수정할 거래", list(options.keys()))
|
|
tx_id = options[label]
|
|
tx = df[df["id"] == tx_id].iloc[0].to_dict()
|
|
update_transaction_form(tx, "tx", db_path)
|