IAMTFRMZA commited on
Commit
593765d
Β·
verified Β·
1 Parent(s): 1ec30a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -106
app.py CHANGED
@@ -3,118 +3,109 @@ import gspread
3
  import gradio as gr
4
  from oauth2client.service_account import ServiceAccountCredentials
5
  from datetime import datetime
6
- import time
 
 
7
 
8
- # ------------------ AUTH ------------------
9
- VALID_USERS = {
10
- "[email protected]": "Pass.123",
11
- "[email protected]": "Pass.123",
12
- "[email protected]": "Pass.123"
13
- }
14
-
15
- # ------------------ GOOGLE SHEET SETUP ------------------
16
  scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
17
  creds = ServiceAccountCredentials.from_json_keyfile_name("credentials.json", scope)
18
  client = gspread.authorize(creds)
19
  sheet_file = client.open("userAccess")
20
 
21
- # ------------------ RETRY LOGIC ------------------
22
- def load_tab(sheet_name, retries=3, delay=5):
23
- for attempt in range(retries):
24
- try:
25
- df = pd.DataFrame(sheet_file.worksheet(sheet_name).get_all_records())
26
- return df
27
- except gspread.exceptions.APIError as e:
28
- if attempt < retries - 1:
29
- time.sleep(delay)
30
- else:
31
- return pd.DataFrame([[f"⚠️ API Error: {str(e)}"]], columns=["Error"])
32
-
33
- # ------------------ HELPERS ------------------
34
- def get_combined_orders(date_str):
35
- df_field = load_tab("Field Sales")
36
- df_ts = load_tab("TeleSales")
37
-
38
- combined = []
39
-
40
- if not df_field.empty:
41
- df_field['Date'] = pd.to_datetime(df_field['Date'], errors='coerce')
42
- df_field['DateStr'] = df_field['Date'].dt.date.astype(str)
43
- df_field = df_field[df_field['DateStr'] == date_str.strip()]
44
- df_field['Order Value'] = pd.to_numeric(df_field['Order Value'], errors='coerce').fillna(0)
45
- df_field_orders = df_field.groupby("Rep").agg({
46
- "Order Received": lambda x: (x == "Yes").sum(),
47
- "Order Value": "sum"
48
- }).reset_index().rename(columns={
49
- "Order Received": "Orders Received",
50
- "Order Value": "Total Order Value"
51
- })
52
- df_field_orders["Source"] = "Field Sales"
53
- combined.append(df_field_orders)
54
-
55
- if not df_ts.empty:
56
- df_ts['Date'] = pd.to_datetime(df_ts['Date'], errors='coerce')
57
- df_ts['DateStr'] = df_ts['Date'].dt.date.astype(str)
58
- df_ts = df_ts[df_ts['DateStr'] == date_str.strip()]
59
- df_ts['Order Value'] = pd.to_numeric(df_ts['Order Value'], errors='coerce').fillna(0)
60
- df_ts_orders = df_ts.groupby("Rep").agg({
61
- "Order Received": lambda x: (x == "Yes").sum(),
62
- "Order Value": "sum"
63
- }).reset_index().rename(columns={
64
- "Order Received": "Orders Received",
65
- "Order Value": "Total Order Value"
66
- })
67
- df_ts_orders["Source"] = "TeleSales"
68
- combined.append(df_ts_orders)
69
-
70
- if combined:
71
- return pd.concat(combined, ignore_index=True)
72
- else:
73
- return pd.DataFrame([["No orders on this date"]], columns=["Message"])
74
-
75
- # Define other helper functions similarly using load_tab...
76
-
77
- # ------------------ GRADIO APP ------------------
78
  with gr.Blocks() as app:
79
- with gr.Row():
80
- with gr.Column(visible=True) as login_ui:
81
- gr.Markdown("## πŸ” Login Required")
82
- email = gr.Textbox(label="Email")
83
- password = gr.Textbox(label="Password", type="password")
84
- login_btn = gr.Button("Login")
85
- login_msg = gr.Markdown("")
86
-
87
- with gr.Column(visible=False) as main_ui:
88
- gr.Markdown("## πŸ—‚οΈ CarMat Dashboard")
89
-
90
- df_initial = load_tab("Field Sales")
91
- unique_dates = sorted(df_initial["Date"].astype(str).unique(), reverse=True) if not df_initial.empty else []
92
-
93
- # --- Tabs ---
94
- with gr.Tab("πŸ“Š Summary"):
95
- gr.Markdown("Summary content coming soon...")
96
-
97
- with gr.Tab("πŸ“‚ Field Sales"):
98
- field_df = gr.Dataframe(value=load_tab("Field Sales"), label="πŸ“‚ Field Sales Records", interactive=False)
99
- gr.Button("πŸ”„ Refresh").click(fn=lambda: load_tab("Field Sales"), outputs=field_df)
100
-
101
- with gr.Tab("πŸ“ž TeleSales"):
102
- ts_table = gr.Dataframe(value=load_tab("TeleSales"), label="πŸ“ž TeleSales Summary")
103
- gr.Button("πŸ”„ Refresh").click(fn=lambda: load_tab("TeleSales"), outputs=ts_table)
104
-
105
- with gr.Tab("πŸ“¦ Orders Summary"):
106
- order_date = gr.Dropdown(label="Select Date", choices=unique_dates, interactive=True)
107
- order_table = gr.Dataframe(label="🧾 Combined Order Summary")
108
- order_date.change(fn=get_combined_orders, inputs=order_date, outputs=order_table)
109
-
110
- # Continue similarly for other tabs...
111
-
112
- def do_login(user, pw):
113
- if VALID_USERS.get(user) == pw:
114
- return gr.update(visible=False), gr.update(visible=True), ""
115
- else:
116
- return gr.update(visible=True), gr.update(visible=False), "❌ Invalid login."
117
-
118
- login_btn.click(fn=do_login, inputs=[email, password], outputs=[login_ui, main_ui, login_msg])
 
 
 
 
119
 
120
  app.launch()
 
3
  import gradio as gr
4
  from oauth2client.service_account import ServiceAccountCredentials
5
  from datetime import datetime
6
+ from geopy.distance import geodesic
7
+ import folium
8
+ from io import BytesIO
9
 
10
+ # Google Sheets Auth
 
 
 
 
 
 
 
11
  scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
12
  creds = ServiceAccountCredentials.from_json_keyfile_name("credentials.json", scope)
13
  client = gspread.authorize(creds)
14
  sheet_file = client.open("userAccess")
15
 
16
+ # Load Data
17
+ def load_tab(sheet_name):
18
+ try:
19
+ df = pd.DataFrame(sheet_file.worksheet(sheet_name).get_all_records())
20
+ return df
21
+ except:
22
+ return pd.DataFrame(["⚠️ Could not load sheet."], columns=["Error"])
23
+
24
+ # GPS calculations
25
+ def calculate_gps_data(df):
26
+ df = df.sort_values(['Date', 'Time']).reset_index(drop=True)
27
+ df[['Latitude', 'Longitude']] = df['Location'].str.split(', ', expand=True).astype(float)
28
+
29
+ df['Kms Travelled'] = 0.0
30
+ df['Duration Between Calls (min)'] = 0.0
31
+
32
+ for i in range(1, len(df)):
33
+ prev_coords = (df.at[i-1, 'Latitude'], df.at[i-1, 'Longitude'])
34
+ current_coords = (df.at[i, 'Latitude'], df.at[i, 'Longitude'])
35
+ df.at[i, 'Kms Travelled'] = geodesic(prev_coords, current_coords).km
36
+
37
+ prev_time = pd.to_datetime(df.at[i-1, 'Date'] + ' ' + df.at[i-1, 'Time'])
38
+ current_time = pd.to_datetime(df.at[i, 'Date'] + ' ' + df.at[i, 'Time'])
39
+ df.at[i, 'Duration Between Calls (min)'] = (current_time - prev_time).total_seconds() / 60.0
40
+
41
+ return df
42
+
43
+ # Load and process Field Sales data
44
+ field_sales_df = calculate_gps_data(load_tab("Field Sales"))
45
+
46
+ # Map generation
47
+ def generate_map(df):
48
+ if df.empty or df[['Latitude', 'Longitude']].isna().all().all():
49
+ return None
50
+
51
+ coords = df[['Latitude', 'Longitude']].dropna().values
52
+ map_center = coords[0]
53
+ m = folium.Map(location=map_center, zoom_start=12)
54
+
55
+ for idx, coord in enumerate(coords):
56
+ folium.Marker(location=coord, popup=f"Visit {idx+1}").add_to(m)
57
+
58
+ folium.PolyLine(coords, color='blue').add_to(m)
59
+
60
+ buf = BytesIO()
61
+ m.save(buf, close_file=False)
62
+ return buf.getvalue().decode()
63
+
64
+ # Gradio Interface
 
 
 
 
 
 
 
 
65
  with gr.Blocks() as app:
66
+ gr.Markdown("## πŸš— CarMat Dashboard")
67
+
68
+ unique_dates = sorted(field_sales_df['Date'].unique(), reverse=True)
69
+
70
+ # Field Sales Tab
71
+ with gr.Tab("πŸ—ΊοΈ Field Sales"):
72
+ date_selector = gr.Dropdown(label="Select Date", choices=unique_dates)
73
+ data_output = gr.DataFrame()
74
+ map_html = gr.HTML()
75
+
76
+ def update_field_sales(date):
77
+ day_df = field_sales_df[field_sales_df['Date'] == date]
78
+ map_render = generate_map(day_df)
79
+ return day_df, map_render
80
+
81
+ date_selector.change(fn=update_field_sales, inputs=date_selector, outputs=[data_output, map_html])
82
+
83
+ # Summary Tab
84
+ with gr.Tab("πŸ“Š Summary"):
85
+ date_summary = gr.Dropdown(label="Select Date", choices=unique_dates)
86
+ summary_visits = gr.DataFrame()
87
+
88
+ def update_summary(date):
89
+ day_df = field_sales_df[field_sales_df['Date'] == date]
90
+ visits = day_df.groupby("Rep").size().reset_index(name="Total Visits")
91
+ return visits
92
+
93
+ date_summary.change(fn=update_summary, inputs=date_summary, outputs=summary_visits)
94
+
95
+ # Orders Tab
96
+ with gr.Tab("πŸ“¦ Orders"):
97
+ order_date = gr.Dropdown(label="Select Date", choices=unique_dates)
98
+ orders_output = gr.DataFrame()
99
+
100
+ def orders_summary(date):
101
+ day_df = field_sales_df[field_sales_df['Date'] == date]
102
+ orders_df = day_df[day_df["Order Received"] == "Yes"]
103
+ summary = orders_df.groupby("Rep").agg({
104
+ "Order Value": "sum",
105
+ "Order Received": "count"
106
+ }).rename(columns={"Order Received": "Orders Count"}).reset_index()
107
+ return summary
108
+
109
+ order_date.change(fn=orders_summary, inputs=order_date, outputs=orders_output)
110
 
111
  app.launch()