visa25 commited on
Commit
b00efca
Β·
verified Β·
1 Parent(s): e785998

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +332 -145
app.py CHANGED
@@ -1,212 +1,399 @@
1
  import gradio as gr
2
  import pandas as pd
3
- from datetime import datetime, timedelta
4
  import os
 
5
 
6
 
7
- # ===============================
8
- # FILE SETTINGS
9
- # ===============================
10
- DATA_FILE = "permissions.xlsx"
11
  STAFF_FILE = "staff_details.xlsx"
 
 
 
 
12
 
13
 
14
- # ===============================
15
- # CREATE FILES IF NOT EXISTS
16
- # ===============================
17
- def create_files():
18
 
19
- if not os.path.exists(DATA_FILE):
20
- df = pd.DataFrame(columns=[
21
- "Staff ID",
22
- "Name",
23
- "Department",
24
- "Date",
25
- "From Time",
26
- "To Time",
27
- "Reason",
28
- "Applied On"
29
- ])
30
- df.to_excel(DATA_FILE, index=False)
31
 
32
- if not os.path.exists(STAFF_FILE):
33
- staff = pd.DataFrame({
34
- "Staff ID": ["SRC001", "SRC002"],
35
- "Name": ["Ramesh", "Suresh"],
36
- "Department": ["CSE", "IT"]
37
- })
38
- staff.to_excel(STAFF_FILE, index=False)
39
 
 
40
 
41
- create_files()
 
42
 
43
 
44
- # ===============================
45
- # TIME CONVERTER
46
- # ===============================
47
- def convert_time(time_str):
48
- return datetime.strptime(time_str.strip(), "%I:%M %p")
49
 
50
 
51
- # ===============================
52
- # VALIDATION FUNCTION
53
- # ===============================
54
- def validate_and_save(staff_id, name, dept, date, from_time, to_time, reason):
55
 
56
- # -------------------------------
57
- # Empty Validation
58
- # -------------------------------
59
- if not all([staff_id, name, dept, date, from_time, to_time, reason]):
60
- return "❌ All fields are required"
61
 
 
 
 
 
62
 
63
- # -------------------------------
64
- # Date Validation
65
- # -------------------------------
66
  today = datetime.today().date()
67
- selected_date = datetime.strptime(date, "%Y-%m-%d").date()
68
 
69
- allowed_dates = [
70
- today,
71
- today + timedelta(days=1),
72
- today + timedelta(days=2)
73
- ]
74
 
75
- if selected_date not in allowed_dates:
76
- return "❌ You can apply only for Today / Tomorrow / Day After Tomorrow"
77
 
78
 
79
- # -------------------------------
80
- # Time Validation
81
- # -------------------------------
82
  try:
83
- start = convert_time(from_time)
84
- end = convert_time(to_time)
85
  except:
86
- return "❌ Time must be in format: HH:MM AM/PM (Ex: 10:00 AM)"
 
 
 
87
 
 
 
 
88
 
89
- # -------------------------------
90
- # Office Time Limits
91
- # -------------------------------
92
- office_start = datetime.strptime("08:45 AM", "%I:%M %p")
93
- office_end = datetime.strptime("05:20 PM", "%I:%M %p")
94
 
 
 
95
 
96
- if start < office_start or end > office_end:
97
- return "❌ Time must be between 8:45 AM and 5:20 PM"
98
 
99
 
100
- # -------------------------------
101
- # One Hour Validation
102
- # -------------------------------
103
- diff = (end - start).seconds / 3600
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
- if diff != 1:
106
- return "❌ Permission allowed for exactly 1 hour only"
107
 
 
108
 
109
- # -------------------------------
110
- # Save to Excel
111
- # -------------------------------
112
- df = pd.read_excel(DATA_FILE)
113
 
114
- new_data = {
115
- "Staff ID": staff_id,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  "Name": name,
117
  "Department": dept,
118
  "Date": date,
119
- "From Time": from_time,
120
- "To Time": to_time,
121
  "Reason": reason,
122
- "Applied On": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
123
  }
124
 
125
- df = pd.concat([df, pd.DataFrame([new_data])], ignore_index=True)
126
- df.to_excel(DATA_FILE, index=False)
127
 
128
- return "βœ… Permission Applied Successfully"
129
 
130
 
131
- # ===============================
132
- # GRADIO UI
133
- # ===============================
134
- with gr.Blocks(theme=gr.themes.Soft()) as app:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
- # ---------- STYLE ----------
137
- gr.HTML("""
138
- <style>
139
- .center {
140
- text-align: center;
141
- }
142
- </style>
143
- """)
144
 
145
- # ---------- HEADER ----------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  gr.HTML("""
147
- <div class="center">
148
- <img src="file/logo.jpg" width="120"><br><br>
149
  <h2>SRC, SASTRA</h2>
150
  <h3>Staff Permission Management System</h3>
151
  <hr>
152
- </div>
153
  """)
154
 
155
 
156
- # ---------- FORM ----------
157
- with gr.Row():
158
- with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
- staff_id = gr.Textbox(label="Staff ID")
161
- name = gr.Textbox(label="Name")
162
- dept = gr.Textbox(label="Department")
163
 
164
- date = gr.Textbox(
165
- label="Date (YYYY-MM-DD)",
166
- placeholder="2026-02-15"
167
- )
168
 
169
- from_time = gr.Textbox(
170
- label="From Time (HH:MM AM/PM)",
171
- placeholder="10:00 AM"
172
- )
173
 
174
- to_time = gr.Textbox(
175
- label="To Time (HH:MM AM/PM)",
176
- placeholder="11:00 AM"
177
- )
178
 
179
- reason = gr.Textbox(
180
- label="Reason",
181
- lines=3
182
- )
183
 
184
- submit = gr.Button("Apply Permission")
185
 
186
- result = gr.Textbox(
187
- label="Status",
188
- interactive=False
189
- )
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- # ---------- BUTTON ----------
193
  submit.click(
194
- validate_and_save,
195
- inputs=[
196
- staff_id,
197
- name,
198
- dept,
199
- date,
200
- from_time,
201
- to_time,
202
- reason
203
- ],
204
- outputs=result
205
  )
206
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
- # ===============================
209
- # LAUNCH
210
- # ===============================
211
- if __name__ == "__main__":
212
- app.launch()
 
1
  import gradio as gr
2
  import pandas as pd
 
3
  import os
4
+ from datetime import datetime, timedelta
5
 
6
 
7
+ # ---------------- CONFIG ---------------- #
8
+
 
 
9
  STAFF_FILE = "staff_details.xlsx"
10
+ PERMISSION_FILE = "permissions.xlsx"
11
+
12
+ ADMIN_USER = "admin"
13
+ ADMIN_PASS = "admin123"
14
 
15
 
16
+ # ---------------- INIT ---------------- #
 
 
 
17
 
18
+ if not os.path.exists(PERMISSION_FILE):
19
+ df = pd.DataFrame(columns=[
20
+ "StaffID",
21
+ "Name",
22
+ "Department",
23
+ "Date",
24
+ "FromTime",
25
+ "ToTime",
26
+ "Reason",
27
+ "SubmittedOn"
28
+ ])
29
+ df.to_excel(PERMISSION_FILE, index=False)
30
 
 
 
 
 
 
 
 
31
 
32
+ # ---------------- LOADERS ---------------- #
33
 
34
+ def load_staff():
35
+ return pd.read_excel(STAFF_FILE)
36
 
37
 
38
+ def load_permissions():
39
+ return pd.read_excel(PERMISSION_FILE)
 
 
 
40
 
41
 
42
+ # ---------------- VALIDATORS ---------------- #
 
 
 
43
 
44
+ # Date: Only Today / Tomorrow / Day after Tomorrow
45
+ def validate_date_range(date_str):
 
 
 
46
 
47
+ try:
48
+ d = datetime.strptime(date_str, "%d/%m/%Y").date()
49
+ except:
50
+ return False, "❌ Date format must be DD/MM/YYYY"
51
 
 
 
 
52
  today = datetime.today().date()
53
+ max_day = today + timedelta(days=2)
54
 
55
+ if d < today:
56
+ return False, "❌ Past date not allowed"
57
+
58
+ if d > max_day:
59
+ return False, "❌ Apply only within 2 days"
60
 
61
+ return True, ""
 
62
 
63
 
64
+ # Time: 08:45 - 17:20 and exactly 1 hour
65
+ def validate_time_range(f, t):
66
+
67
  try:
68
+ f_time = datetime.strptime(f, "%H:%M")
69
+ t_time = datetime.strptime(t, "%H:%M")
70
  except:
71
+ return False, "❌ Time format must be HH:MM (24-hour)"
72
+
73
+ min_time = datetime.strptime("08:45", "%H:%M")
74
+ max_time = datetime.strptime("17:20", "%H:%M")
75
 
76
+ # Check range
77
+ if f_time < min_time or t_time > max_time:
78
+ return False, "❌ Time allowed: 08:45 to 17:20 only"
79
 
80
+ # Check 1 hour duration
81
+ diff = (t_time - f_time).total_seconds() / 3600
 
 
 
82
 
83
+ if diff != 1:
84
+ return False, "❌ Permission must be exactly 1 hour"
85
 
86
+ return True, ""
 
87
 
88
 
89
+ # ---------------- STAFF FUNCTIONS ---------------- #
90
+
91
+ def fetch_staff(staff_id):
92
+
93
+ df = load_staff()
94
+ row = df[df["StaffID"] == staff_id]
95
+
96
+ if row.empty:
97
+ return "Not Found", "Not Found", "0"
98
+
99
+ name = row.iloc[0]["Name"]
100
+ dept = row.iloc[0]["Department"]
101
+
102
+ perms = load_permissions()
103
+ count = len(perms[perms["StaffID"] == staff_id])
104
+
105
+ return name, dept, str(count)
106
+
107
+
108
+ def submit_permission(staff_id, date, f, t, reason):
109
+
110
+ # Basic validation
111
+ if staff_id.strip() == "":
112
+ return "❌ Staff ID Required"
113
+
114
+ if date.strip() == "":
115
+ return "❌ Date Required"
116
+
117
+ if f.strip() == "" or t.strip() == "":
118
+ return "❌ Time Required"
119
+
120
+ if reason.strip() == "":
121
+ return "❌ Reason Required"
122
+
123
+
124
+ # Date validation
125
+ ok, msg = validate_date_range(date)
126
+ if not ok:
127
+ return msg
128
+
129
+
130
+ # Time validation
131
+ ok, msg = validate_time_range(f, t)
132
+ if not ok:
133
+ return msg
134
+
135
+
136
+ # Staff validation
137
+ staff = load_staff()
138
+ row = staff[staff["StaffID"] == staff_id]
139
+
140
+ if row.empty:
141
+ return "❌ Invalid Staff ID"
142
 
 
 
143
 
144
+ perms = load_permissions()
145
 
 
 
 
 
146
 
147
+ # Same day check (max 2)
148
+ same_day = perms[
149
+ (perms["StaffID"] == staff_id) &
150
+ (perms["Date"] == date)
151
+ ]
152
+
153
+ if len(same_day) == 1:
154
+ return "⚠️ Second permission today β†’ Apply Leave"
155
+
156
+ if len(same_day) >= 2:
157
+ return "❌ Daily limit reached"
158
+
159
+
160
+ # Monthly limit (2 only)
161
+ m = date.split("/")[1]
162
+ y = date.split("/")[2]
163
+
164
+ same_month = perms[
165
+ (perms["StaffID"] == staff_id) &
166
+ (perms["Date"].str.contains(f"/{m}/{y}", na=False))
167
+ ]
168
+
169
+ if len(same_month) >= 2:
170
+ return "❌ Monthly limit reached (2 only)"
171
+
172
+
173
+ # Save
174
+ name = row.iloc[0]["Name"]
175
+ dept = row.iloc[0]["Department"]
176
+
177
+ now = datetime.now().strftime("%d/%m/%Y %H:%M")
178
+
179
+ new_row = {
180
+ "StaffID": staff_id,
181
  "Name": name,
182
  "Department": dept,
183
  "Date": date,
184
+ "FromTime": f,
185
+ "ToTime": t,
186
  "Reason": reason,
187
+ "SubmittedOn": now
188
  }
189
 
190
+ perms = pd.concat([perms, pd.DataFrame([new_row])], ignore_index=True)
191
+ perms.to_excel(PERMISSION_FILE, index=False)
192
 
193
+ return "βœ… Permission Submitted Successfully"
194
 
195
 
196
+ def delete_permission(staff_id, date):
197
+
198
+ perms = load_permissions()
199
+ before = len(perms)
200
+
201
+ perms = perms[
202
+ ~((perms["StaffID"] == staff_id) &
203
+ (perms["Date"] == date))
204
+ ]
205
+
206
+ perms.to_excel(PERMISSION_FILE, index=False)
207
+
208
+ if len(perms) == before:
209
+ return "❌ No Record Found"
210
+ else:
211
+ return "βœ… Deleted"
212
+
213
+
214
+ def clear_form():
215
+ return "", "", "", "", ""
216
+
217
+
218
+ # ---------------- ADMIN ---------------- #
219
+
220
+ def admin_login(user, pwd):
221
+
222
+ if user == ADMIN_USER and pwd == ADMIN_PASS:
223
+ return gr.update(visible=True), "βœ… Login Successful"
224
+
225
+ return gr.update(visible=False), "❌ Invalid Login"
226
+
227
+
228
+ def get_all_data():
229
+ return load_permissions()
230
+
231
+
232
+ def download_excel():
233
+ return PERMISSION_FILE
234
 
 
 
 
 
 
 
 
 
235
 
236
+ def monthly_report(month, year):
237
+
238
+ perms = load_permissions()
239
+
240
+ return perms[
241
+ perms["Date"].str.contains(f"/{month}/{year}", na=False)
242
+ ]
243
+
244
+
245
+ def dept_report(dept):
246
+
247
+ perms = load_permissions()
248
+
249
+ return perms[perms["Department"] == dept]
250
+
251
+
252
+ def reset_data():
253
+
254
+ df = pd.DataFrame(columns=[
255
+ "StaffID",
256
+ "Name",
257
+ "Department",
258
+ "Date",
259
+ "FromTime",
260
+ "ToTime",
261
+ "Reason",
262
+ "SubmittedOn"
263
+ ])
264
+
265
+ df.to_excel(PERMISSION_FILE, index=False)
266
+
267
+ return "βœ… All Data Cleared"
268
+
269
+
270
+ # ================= UI ================= #
271
+
272
+ with gr.Blocks() as app:
273
+
274
  gr.HTML("""
275
+ <center>
 
276
  <h2>SRC, SASTRA</h2>
277
  <h3>Staff Permission Management System</h3>
278
  <hr>
279
+ </center>
280
  """)
281
 
282
 
283
+ # ---------------- STAFF TAB ---------------- #
284
+
285
+ with gr.Tab("Staff Panel"):
286
+
287
+ with gr.Row():
288
+
289
+ with gr.Column():
290
+
291
+ staff_id = gr.Textbox(label="Staff ID")
292
+
293
+ name = gr.Textbox(label="Name", interactive=False)
294
+ dept = gr.Textbox(label="Department", interactive=False)
295
+ count = gr.Textbox(label="Permission Count", interactive=False)
296
+
297
+ fetch = gr.Button("Fetch Details")
298
+
299
+
300
+ with gr.Column():
301
+
302
+ date = gr.Textbox(label="Date (DD/MM/YYYY)")
303
+ f = gr.Textbox(label="From (HH:MM 24-hr)")
304
+ t = gr.Textbox(label="To (HH:MM 24-hr)")
305
+
306
+ reason = gr.Textbox(label="Reason", lines=3)
307
+
308
+ with gr.Row():
309
+ submit = gr.Button("Submit", variant="primary")
310
+ delete = gr.Button("Delete", variant="stop")
311
+ clear = gr.Button("Clear")
312
+
313
+ status = gr.Textbox(label="Status", interactive=False)
314
+
315
+
316
+ # ---------------- ADMIN TAB ---------------- #
317
+
318
+ with gr.Tab("Admin Panel"):
319
 
320
+ admin_user = gr.Textbox(label="Username")
321
+ admin_pwd = gr.Textbox(label="Password", type="password")
 
322
 
323
+ login = gr.Button("Login")
 
 
 
324
 
325
+ msg = gr.Textbox(interactive=False)
 
 
 
326
 
327
+ admin_box = gr.Column(visible=False)
 
 
 
328
 
329
+ with admin_box:
 
 
 
330
 
331
+ gr.Markdown("### πŸ“Š All Records")
332
 
333
+ table = gr.Dataframe(interactive=False)
 
 
 
334
 
335
+ refresh = gr.Button("Refresh")
336
+
337
+
338
+ gr.Markdown("### πŸ“… Monthly Report")
339
+
340
+ month = gr.Textbox(label="Month (MM)")
341
+ year = gr.Textbox(label="Year (YYYY)")
342
+
343
+ month_btn = gr.Button("Generate")
344
+
345
+ month_table = gr.Dataframe()
346
+
347
+
348
+ gr.Markdown("### 🏒 Department Report")
349
+
350
+ dept_name = gr.Textbox(label="Department")
351
+
352
+ dept_btn = gr.Button("Generate")
353
+
354
+ dept_table = gr.Dataframe()
355
+
356
+
357
+ gr.Markdown("### πŸ“₯ Download")
358
+
359
+ down = gr.Button("Download Excel")
360
+
361
+ file = gr.File()
362
+
363
+
364
+ gr.Markdown("### ⚠️ Reset")
365
+
366
+ reset = gr.Button("Reset All", variant="stop")
367
+
368
+ reset_msg = gr.Textbox(interactive=False)
369
+
370
+
371
+ # ---------------- EVENTS ---------------- #
372
+
373
+ fetch.click(fetch_staff, staff_id, [name, dept, count])
374
 
 
375
  submit.click(
376
+ submit_permission,
377
+ [staff_id, date, f, t, reason],
378
+ status
 
 
 
 
 
 
 
 
379
  )
380
 
381
+ delete.click(delete_permission, [staff_id, date], status)
382
+
383
+ clear.click(clear_form, outputs=[date, f, t, reason, status])
384
+
385
+
386
+ login.click(admin_login, [admin_user, admin_pwd], [admin_box, msg])
387
+
388
+ refresh.click(get_all_data, outputs=table)
389
+
390
+ month_btn.click(monthly_report, [month, year], month_table)
391
+
392
+ dept_btn.click(dept_report, dept_name, dept_table)
393
+
394
+ down.click(download_excel, outputs=file)
395
+
396
+ reset.click(reset_data, outputs=reset_msg)
397
+
398
 
399
+ app.launch()