Gowthamgokul commited on
Commit
0474977
·
verified ·
1 Parent(s): be1d6d4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py CHANGED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from config.db import get_collection
4
+ from utils.text_cleaner import clean_text
5
+ from utils.search import rank_results
6
+
7
+ st.set_page_config(page_title="Expense Search System", layout="wide")
8
+ st.title("🔍 Expense Search Dashboard")
9
+
10
+ # --- 1️⃣ Input/Search Layer ---
11
+ user_input = st.text_input("Search (Date / Company / Remark / Description / Amount)")
12
+
13
+ if user_input:
14
+ clean_input = clean_text(user_input)
15
+ collection = get_collection()
16
+
17
+ # --- Build query WITHOUT $text to avoid MongoDB error ---
18
+ query = {
19
+ "$or": [
20
+ {"date": {"$regex": clean_input, "$options": "i"}}, # Date search
21
+ {"home company": {"$regex": clean_input, "$options": "i"}}, # Company search
22
+ {"description": {"$regex": clean_input, "$options": "i"}}, # Description search
23
+ {"remarks": {"$regex": clean_input, "$options": "i"}}, # Remarks search
24
+ {"description_clean": {"$regex": clean_input, "$options": "i"}}, # Cleaned description
25
+ ]
26
+ }
27
+
28
+ # Try to match amount if input is numeric
29
+ try:
30
+ amount_value = float(clean_input.replace(",", ""))
31
+ query["$or"].append({"amount": amount_value})
32
+ except ValueError:
33
+ pass # Not a number, skip amount matching
34
+
35
+ # --- Fetch ALL matching records from MongoDB ---
36
+ docs = list(collection.find(
37
+ query,
38
+ {
39
+ "date": 1,
40
+ "description": 1,
41
+ "remarks": 1,
42
+ "amount": 1,
43
+ "home company": 1,
44
+ "description_clean": 1
45
+ }
46
+ )) # Removed limit to fetch ALL records
47
+
48
+ if docs:
49
+ # --- Rank using fuzzy search ---
50
+ ranked = rank_results(clean_input, docs)
51
+ df = pd.DataFrame(ranked)
52
+ df = df[['date', 'description', 'remarks', 'home company', 'amount']]
53
+ df.rename(columns={"home company": "Company"}, inplace=True)
54
+
55
+ # --- 2️⃣ Quick Summary Metrics ---
56
+ total_transactions = len(df)
57
+ total_amount = df['amount'].sum()
58
+ inward_total = df[df['remarks'].str.lower().str.contains("inward", na=False)]['amount'].sum()
59
+ outward_total = df[df['remarks'].str.lower().str.contains("outward", na=False)]['amount'].sum()
60
+ net_total = inward_total - outward_total
61
+
62
+ st.subheader("📊 Quick Summary")
63
+ c1, c2, c3, c4, c5 = st.columns(5)
64
+ c1.metric("Transactions", total_transactions)
65
+ c2.metric("Total Amount", f"{total_amount:,.2f}")
66
+ c3.metric("Inward", f"{inward_total:,.2f}")
67
+ c4.metric("Outward", f"{outward_total:,.2f}")
68
+ c5.metric("Net Total", f"{net_total:,.2f}")
69
+
70
+ # --- 3️⃣ Matched Transactions Table ---
71
+ st.subheader("🧾 Matched Transactions")
72
+ st.dataframe(df, use_container_width=True)
73
+
74
+ # --- 4️⃣ Remarks Breakup ---
75
+ st.subheader("🏷️ Remarks Breakup")
76
+ remarks_summary = df.groupby('remarks')['amount'].agg(['count', 'sum']).reset_index()
77
+ remarks_summary.rename(columns={"count": "Transactions", "sum": "Total Amount", "remarks": "Remark"}, inplace=True)
78
+ st.table(remarks_summary)
79
+
80
+ # --- 5️⃣ Company Involvement ---
81
+ st.subheader("🏢 Company Summary")
82
+ company_summary = df.groupby('Company')['amount'].agg(['count', 'sum']).reset_index()
83
+ company_summary.rename(columns={"count": "Transactions", "sum": "Total Amount"}, inplace=True)
84
+ st.table(company_summary)
85
+
86
+ # --- 6️⃣ Date Summary (if multiple dates present) ---
87
+ st.subheader("📅 Date-wise Summary")
88
+ date_summary = df.groupby('date')['amount'].agg(['count', 'sum']).reset_index()
89
+ date_summary.rename(columns={"count": "Transactions", "sum": "Total Amount", "date": "Date"}, inplace=True)
90
+ st.table(date_summary)
91
+
92
+ # --- 7️⃣ Optional Visuals ---
93
+ st.subheader("📊 Visual Insights")
94
+ col1, col2 = st.columns(2)
95
+
96
+ with col1:
97
+ st.markdown("**🥧 Inward vs Outward Pie Chart**")
98
+ pie_data = pd.DataFrame({
99
+ "Type": ["Inward", "Outward"],
100
+ "Amount": [inward_total, outward_total]
101
+ })
102
+ st.bar_chart(pie_data.set_index("Type"))
103
+
104
+ with col2:
105
+ st.markdown("**📊 Amount by Company**")
106
+ st.bar_chart(company_summary.set_index("Company")["Total Amount"])
107
+
108
+ else:
109
+ st.warning("No confident match found")