File size: 4,455 Bytes
0474977
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import streamlit as st
import pandas as pd
from config.db import get_collection
from utils.text_cleaner import clean_text
from utils.search import rank_results

st.set_page_config(page_title="Expense Search System", layout="wide")
st.title("🔍 Expense Search Dashboard")

# --- 1️⃣ Input/Search Layer ---
user_input = st.text_input("Search (Date / Company / Remark / Description / Amount)")

if user_input:
    clean_input = clean_text(user_input)
    collection = get_collection()

    # --- Build query WITHOUT $text to avoid MongoDB error ---
    query = {
        "$or": [
            {"date": {"$regex": clean_input, "$options": "i"}},  # Date search
            {"home company": {"$regex": clean_input, "$options": "i"}},  # Company search
            {"description": {"$regex": clean_input, "$options": "i"}},  # Description search
            {"remarks": {"$regex": clean_input, "$options": "i"}},  # Remarks search
            {"description_clean": {"$regex": clean_input, "$options": "i"}},  # Cleaned description
        ]
    }
    
    # Try to match amount if input is numeric
    try:
        amount_value = float(clean_input.replace(",", ""))
        query["$or"].append({"amount": amount_value})
    except ValueError:
        pass  # Not a number, skip amount matching

    # --- Fetch ALL matching records from MongoDB ---
    docs = list(collection.find(
        query,
        {
            "date": 1,
            "description": 1,
            "remarks": 1,
            "amount": 1,
            "home company": 1,
            "description_clean": 1
        }
    ))  # Removed limit to fetch ALL records

    if docs:
        # --- Rank using fuzzy search ---
        ranked = rank_results(clean_input, docs)
        df = pd.DataFrame(ranked)
        df = df[['date', 'description', 'remarks', 'home company', 'amount']]
        df.rename(columns={"home company": "Company"}, inplace=True)

        # --- 2️⃣ Quick Summary Metrics ---
        total_transactions = len(df)
        total_amount = df['amount'].sum()
        inward_total = df[df['remarks'].str.lower().str.contains("inward", na=False)]['amount'].sum()
        outward_total = df[df['remarks'].str.lower().str.contains("outward", na=False)]['amount'].sum()
        net_total = inward_total - outward_total

        st.subheader("📊 Quick Summary")
        c1, c2, c3, c4, c5 = st.columns(5)
        c1.metric("Transactions", total_transactions)
        c2.metric("Total Amount", f"{total_amount:,.2f}")
        c3.metric("Inward", f"{inward_total:,.2f}")
        c4.metric("Outward", f"{outward_total:,.2f}")
        c5.metric("Net Total", f"{net_total:,.2f}")

        # --- 3️⃣ Matched Transactions Table ---
        st.subheader("🧾 Matched Transactions")
        st.dataframe(df, use_container_width=True)

        # --- 4️⃣ Remarks Breakup ---
        st.subheader("🏷️ Remarks Breakup")
        remarks_summary = df.groupby('remarks')['amount'].agg(['count', 'sum']).reset_index()
        remarks_summary.rename(columns={"count": "Transactions", "sum": "Total Amount", "remarks": "Remark"}, inplace=True)
        st.table(remarks_summary)

        # --- 5️⃣ Company Involvement ---
        st.subheader("🏢 Company Summary")
        company_summary = df.groupby('Company')['amount'].agg(['count', 'sum']).reset_index()
        company_summary.rename(columns={"count": "Transactions", "sum": "Total Amount"}, inplace=True)
        st.table(company_summary)

        # --- 6️⃣ Date Summary (if multiple dates present) ---
        st.subheader("📅 Date-wise Summary")
        date_summary = df.groupby('date')['amount'].agg(['count', 'sum']).reset_index()
        date_summary.rename(columns={"count": "Transactions", "sum": "Total Amount", "date": "Date"}, inplace=True)
        st.table(date_summary)

        # --- 7️⃣ Optional Visuals ---
        st.subheader("📊 Visual Insights")
        col1, col2 = st.columns(2)

        with col1:
            st.markdown("**🥧 Inward vs Outward Pie Chart**")
            pie_data = pd.DataFrame({
                "Type": ["Inward", "Outward"],
                "Amount": [inward_total, outward_total]
            })
            st.bar_chart(pie_data.set_index("Type"))

        with col2:
            st.markdown("**📊 Amount by Company**")
            st.bar_chart(company_summary.set_index("Company")["Total Amount"])

    else:
        st.warning("No confident match found")