import streamlit as st # --- 1. PASSWORD PROTECTION SCREEN --- def check_password(): """Returns `True` if the user entered the correct password.""" def password_entered(): if st.session_state["password"] == "my_secret_password_123": # Change this password! st.session_state["password_correct"] = True del st.session_state["password"] # Don't store password else: st.session_state["password_correct"] = False if "password_correct" not in st.session_state: # First run, show input for password st.subheader("🔒 Private Accounting Login") st.text_input("Enter your password:", type="password", on_change=password_entered, key="password") if "password_correct" in st.session_state and not st.session_state["password_correct"]: st.error("😕 Password incorrect") return False elif not st.session_state["password_correct"]: # Incorrect password, show input again st.subheader("🔒 Private Accounting Login") st.text_input("Enter your password:", type="password", on_change=password_entered, key="password") st.error("😕 Password incorrect") return False else: # Correct password return True if not check_password(): st.stop() # Stop execution here if not logged in # --- 2. ACCOUNTING SYSTEM CLASS --- class AccountingSystem: def __init__(self): if "accounts" not in st.session_state: st.session_state.accounts = { "1010": {"name": "Cash / Bank", "type": "Asset"}, "1020": {"name": "Accounts Receivable", "type": "Asset"}, "2010": {"name": "Accounts Payable", "type": "Liability"}, "3010": {"name": "Owner's Equity", "type": "Equity"}, "4010": {"name": "Sales Revenue", "type": "Revenue"}, "5010": {"name": "Office Supplies & Expenses", "type": "Expense"}, } if "journal_entries" not in st.session_state: st.session_state.journal_entries = [] def record_transaction(self, date, description, debit_account, credit_account, amount): entry = { "date": date, "description": description, "debit_acc": debit_account, "credit_acc": credit_account, "amount": float(amount) } st.session_state.journal_entries.append(entry) def get_account_balances(self): balances = {acc: 0.0 for acc in st.session_state.accounts} for entry in st.session_state.journal_entries: d_acc = entry["debit_acc"] c_acc = entry["credit_acc"] amt = entry["amount"] if st.session_state.accounts[d_acc]["type"] in ["Asset", "Expense"]: balances[d_acc] += amt else: balances[d_acc] -= amt if st.session_state.accounts[c_acc]["type"] in ["Liability", "Equity", "Revenue"]: balances[c_acc] += amt else: balances[c_acc] -= amt return balances def generate_profit_and_loss(self): balances = self.get_account_balances() total_revenue = 0.0 total_expenses = 0.0 for acc_code, balance in balances.items(): acc_type = st.session_state.accounts[acc_code]["type"] if acc_type == "Revenue": total_revenue += balance elif acc_type == "Expense": total_expenses += balance net_income = total_revenue - total_expenses return { "Total Revenue": total_revenue, "Total Expenses": total_expenses, "Net Profit": net_income } def generate_balance_sheet(self): balances = self.get_account_balances() total_assets = 0.0 total_liabilities = 0.0 total_equity = 0.0 pnl = self.generate_profit_and_loss() net_profit = pnl["Net Profit"] for acc_code, balance in balances.items(): acc_type = st.session_state.accounts[acc_code]["type"] if acc_type == "Asset": total_assets += balance elif acc_type == "Liability": total_liabilities += balance elif acc_type == "Equity": total_equity += balance total_equity_with_profit = total_equity + net_profit return { "Total Assets": total_assets, "Total Liabilities": total_liabilities, "Total Equity": total_equity_with_profit, "Is Balanced": abs(total_assets - (total_liabilities + total_equity_with_profit)) < 0.01 } # --- 3. STREAMLIT WEB INTERFACE --- app = AccountingSystem() st.title("📊 My Private Accounting Dashboard") st.write("Welcome back! Manage your transactions and review your financial health securely.") # Sidebar Navigation menu = st.sidebar.selectbox("Navigation", ["Dashboard & Reports", "Add Manual Transaction", "Simulate Bank Feed"]) if menu == "Dashboard & Reports": st.subheader("📈 Financial Statements") col1, col2 = st.columns(2) # Profit & Loss Card with col1: st.markdown("### Profit & Loss") pnl = app.generate_profit_and_loss() st.metric(label="Total Revenue", value=f"${pnl['Total Revenue']:,.2f}") st.metric(label="Total Expenses", value=f"${pnl['Total Expenses']:,.2f}") st.metric(label="Net Profit", value=f"${pnl['Net Profit']:,.2f}") # Balance Sheet Card with col2: st.markdown("### Balance Sheet") bs = app.generate_balance_sheet() st.metric(label="Total Assets", value=f"${bs['Total Assets']:,.2f}") st.metric(label="Total Liabilities", value=f"${bs['Total Liabilities']:,.2f}") st.metric(label="Total Equity", value=f"${bs['Total Equity']:,.2f}") st.info(f"Books Balanced: {bs['Is Balanced']}") st.markdown("---") st.subheader("📋 Recent Transaction History") if st.session_state.journal_entries: st.table(st.session_state.journal_entries) else: st.write("No transactions recorded yet. Use the sidebar to add some!") elif menu == "Add Manual Transaction": st.subheader("✍️ Record a New Transaction") with st.form("transaction_form"): date = st.date_input("Transaction Date") description = st.text_input("Description (e.g., Client Payment, Rent)") account_options = {f"{k} - {v['name']}": k for k, v in st.session_state.accounts.items()} debit_choice = st.selectbox("Debit Account", list(account_options.keys())) credit_choice = st.selectbox("Credit Account", list(account_options.keys())) amount = st.number_input("Amount ($)", min_value=0.01, format="%.2f") submitted = st.form_submit_button("Record Transaction") if submitted: d_acc = account_options[debit_choice] c_acc = account_options[credit_choice] app.record_transaction(str(date), description, d_acc, c_acc, amount) st.success("Transaction successfully recorded!") elif menu == "Simulate Bank Feed": st.subheader("🏦 Bank Sync Simulation") st.write("Simulate automatic imports from your bank account webhooks.") if st.button("Run Bank Sync Now"): # Simulated incoming transactions sample_bank_data = [ ("2026-06-02", "Client Web Design Deposit", 1500.00), ("2026-06-03", "Office Depot Supplies", -125.50), ("2026-06-04", "Coworking Space Rent", -400.00) ] for date, desc, amt in sample_bank_data: if amt > 0: app.record_transaction(date, desc, "1010", "4010", amt) else: app.record_transaction(date, desc, "5010", "1010", abs(amt)) st.success("Successfully synced 3 new transactions from bank feed!")