ngwakomadikwe commited on
Commit
49888b0
·
verified ·
1 Parent(s): 6be52bf

Create admin_service.py (Admin Management Service)

Browse files
admin_service.py (Admin Management Service) ADDED
@@ -0,0 +1,372 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Admin Service Layer for ThutoAI
3
+ Handles admin authentication and school management operations
4
+ """
5
+ from models import DatabaseManager
6
+ import hashlib
7
+ import json
8
+ from datetime import datetime
9
+
10
+ class AdminService:
11
+ def __init__(self):
12
+ self.db = DatabaseManager()
13
+
14
+ def authenticate_admin(self, username, password):
15
+ """Authenticate admin user"""
16
+ conn = self.db.get_connection()
17
+ cursor = conn.cursor()
18
+
19
+ password_hash = hashlib.sha256(password.encode()).hexdigest()
20
+
21
+ cursor.execute('''
22
+ SELECT id, username, full_name, email, role, is_active
23
+ FROM admin_users
24
+ WHERE username = ? AND password_hash = ? AND is_active = 1
25
+ ''', (username, password_hash))
26
+
27
+ admin = cursor.fetchone()
28
+
29
+ if admin:
30
+ # Update last login
31
+ cursor.execute('''
32
+ UPDATE admin_users SET last_login = CURRENT_TIMESTAMP WHERE id = ?
33
+ ''', (admin[0],))
34
+ conn.commit()
35
+
36
+ conn.close()
37
+ return {
38
+ 'id': admin[0],
39
+ 'username': admin[1],
40
+ 'full_name': admin[2],
41
+ 'email': admin[3],
42
+ 'role': admin[4],
43
+ 'is_active': bool(admin[5])
44
+ }
45
+
46
+ conn.close()
47
+ return None
48
+
49
+ # Announcement Management
50
+ def create_announcement(self, title, content, priority='normal', target_audience='all', expires_at=None, created_by='admin'):
51
+ """Create a new announcement"""
52
+ conn = self.db.get_connection()
53
+ cursor = conn.cursor()
54
+
55
+ cursor.execute('''
56
+ INSERT INTO announcements (title, content, priority, target_audience, expires_at)
57
+ VALUES (?, ?, ?, ?, ?)
58
+ ''', (title, content, priority, target_audience, expires_at))
59
+
60
+ announcement_id = cursor.lastrowid
61
+ conn.commit()
62
+ conn.close()
63
+
64
+ return announcement_id
65
+
66
+ def update_announcement(self, announcement_id, title=None, content=None, priority=None, target_audience=None, expires_at=None):
67
+ """Update an existing announcement"""
68
+ conn = self.db.get_connection()
69
+ cursor = conn.cursor()
70
+
71
+ updates = []
72
+ params = []
73
+
74
+ if title:
75
+ updates.append("title = ?")
76
+ params.append(title)
77
+ if content:
78
+ updates.append("content = ?")
79
+ params.append(content)
80
+ if priority:
81
+ updates.append("priority = ?")
82
+ params.append(priority)
83
+ if target_audience:
84
+ updates.append("target_audience = ?")
85
+ params.append(target_audience)
86
+ if expires_at:
87
+ updates.append("expires_at = ?")
88
+ params.append(expires_at)
89
+
90
+ if updates:
91
+ params.append(announcement_id)
92
+ cursor.execute(f'''
93
+ UPDATE announcements SET {", ".join(updates)} WHERE id = ?
94
+ ''', params)
95
+ conn.commit()
96
+
97
+ conn.close()
98
+ return True
99
+
100
+ def delete_announcement(self, announcement_id):
101
+ """Delete an announcement"""
102
+ conn = self.db.get_connection()
103
+ cursor = conn.cursor()
104
+
105
+ cursor.execute('UPDATE announcements SET is_active = 0 WHERE id = ?', (announcement_id,))
106
+ conn.commit()
107
+ conn.close()
108
+
109
+ return True
110
+
111
+ def get_all_announcements(self):
112
+ """Get all announcements for admin management"""
113
+ conn = self.db.get_connection()
114
+ cursor = conn.cursor()
115
+
116
+ cursor.execute('''
117
+ SELECT id, title, content, priority, target_audience, created_at, expires_at, is_active
118
+ FROM announcements
119
+ ORDER BY created_at DESC
120
+ ''')
121
+
122
+ announcements = cursor.fetchall()
123
+ conn.close()
124
+
125
+ return [
126
+ {
127
+ 'id': ann[0],
128
+ 'title': ann[1],
129
+ 'content': ann[2],
130
+ 'priority': ann[3],
131
+ 'target_audience': ann[4],
132
+ 'created_at': ann[5],
133
+ 'expires_at': ann[6],
134
+ 'is_active': bool(ann[7])
135
+ }
136
+ for ann in announcements
137
+ ]
138
+
139
+ # Syllabus Management
140
+ def create_syllabus(self, subject, grade_level, chapter_number, chapter_title, topics,
141
+ learning_objectives=None, duration_weeks=None, resources=None,
142
+ assessment_methods=None, created_by='admin'):
143
+ """Create a new syllabus entry"""
144
+ conn = self.db.get_connection()
145
+ cursor = conn.cursor()
146
+
147
+ # Convert lists to JSON strings
148
+ topics_json = json.dumps(topics) if isinstance(topics, list) else topics
149
+ resources_json = json.dumps(resources) if isinstance(resources, list) else resources
150
+
151
+ cursor.execute('''
152
+ INSERT INTO syllabus (subject, grade_level, chapter_number, chapter_title, topics,
153
+ learning_objectives, duration_weeks, resources, assessment_methods, created_by)
154
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
155
+ ''', (subject, grade_level, chapter_number, chapter_title, topics_json,
156
+ learning_objectives, duration_weeks, resources_json, assessment_methods, created_by))
157
+
158
+ syllabus_id = cursor.lastrowid
159
+ conn.commit()
160
+ conn.close()
161
+
162
+ return syllabus_id
163
+
164
+ def get_syllabus(self, subject=None, grade_level=None):
165
+ """Get syllabus data"""
166
+ conn = self.db.get_connection()
167
+ cursor = conn.cursor()
168
+
169
+ query = '''
170
+ SELECT id, subject, grade_level, chapter_number, chapter_title, topics,
171
+ learning_objectives, duration_weeks, resources, assessment_methods,
172
+ created_by, created_at, updated_at
173
+ FROM syllabus
174
+ WHERE is_active = 1
175
+ '''
176
+ params = []
177
+
178
+ if subject:
179
+ query += ' AND subject = ?'
180
+ params.append(subject)
181
+ if grade_level:
182
+ query += ' AND grade_level = ?'
183
+ params.append(grade_level)
184
+
185
+ query += ' ORDER BY subject, grade_level, chapter_number'
186
+
187
+ cursor.execute(query, params)
188
+ syllabus_data = cursor.fetchall()
189
+ conn.close()
190
+
191
+ return [
192
+ {
193
+ 'id': syl[0],
194
+ 'subject': syl[1],
195
+ 'grade_level': syl[2],
196
+ 'chapter_number': syl[3],
197
+ 'chapter_title': syl[4],
198
+ 'topics': json.loads(syl[5]) if syl[5] else [],
199
+ 'learning_objectives': syl[6],
200
+ 'duration_weeks': syl[7],
201
+ 'resources': json.loads(syl[8]) if syl[8] else [],
202
+ 'assessment_methods': syl[9],
203
+ 'created_by': syl[10],
204
+ 'created_at': syl[11],
205
+ 'updated_at': syl[12]
206
+ }
207
+ for syl in syllabus_data
208
+ ]
209
+
210
+ def update_syllabus(self, syllabus_id, **kwargs):
211
+ """Update syllabus entry"""
212
+ conn = self.db.get_connection()
213
+ cursor = conn.cursor()
214
+
215
+ # Convert lists to JSON if needed
216
+ if 'topics' in kwargs and isinstance(kwargs['topics'], list):
217
+ kwargs['topics'] = json.dumps(kwargs['topics'])
218
+ if 'resources' in kwargs and isinstance(kwargs['resources'], list):
219
+ kwargs['resources'] = json.dumps(kwargs['resources'])
220
+
221
+ updates = []
222
+ params = []
223
+
224
+ for key, value in kwargs.items():
225
+ if key in ['subject', 'grade_level', 'chapter_number', 'chapter_title', 'topics',
226
+ 'learning_objectives', 'duration_weeks', 'resources', 'assessment_methods', 'is_active']:
227
+ updates.append(f"{key} = ?")
228
+ params.append(value)
229
+
230
+ if updates:
231
+ updates.append("updated_at = CURRENT_TIMESTAMP")
232
+ params.append(syllabus_id)
233
+ cursor.execute(f'''
234
+ UPDATE syllabus SET {", ".join(updates)} WHERE id = ?
235
+ ''', params)
236
+ conn.commit()
237
+
238
+ conn.close()
239
+ return True
240
+
241
+ # Timetable Management
242
+ def create_timetable_entry(self, class_section, day_of_week, period_number, start_time,
243
+ end_time, subject, teacher_name=None, room_number=None, created_by='admin'):
244
+ """Create a new timetable entry"""
245
+ conn = self.db.get_connection()
246
+ cursor = conn.cursor()
247
+
248
+ cursor.execute('''
249
+ INSERT INTO timetable (class_section, day_of_week, period_number, start_time, end_time,
250
+ subject, teacher_name, room_number, created_by)
251
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
252
+ ''', (class_section, day_of_week, period_number, start_time, end_time,
253
+ subject, teacher_name, room_number, created_by))
254
+
255
+ timetable_id = cursor.lastrowid
256
+ conn.commit()
257
+ conn.close()
258
+
259
+ return timetable_id
260
+
261
+ def get_timetable(self, class_section=None, day_of_week=None):
262
+ """Get timetable data"""
263
+ conn = self.db.get_connection()
264
+ cursor = conn.cursor()
265
+
266
+ query = '''
267
+ SELECT id, class_section, day_of_week, period_number, start_time, end_time,
268
+ subject, teacher_name, room_number, created_by, created_at
269
+ FROM timetable
270
+ WHERE is_active = 1
271
+ '''
272
+ params = []
273
+
274
+ if class_section:
275
+ query += ' AND class_section = ?'
276
+ params.append(class_section)
277
+ if day_of_week:
278
+ query += ' AND day_of_week = ?'
279
+ params.append(day_of_week)
280
+
281
+ query += ' ORDER BY class_section, day_of_week, period_number'
282
+
283
+ cursor.execute(query, params)
284
+ timetable_data = cursor.fetchall()
285
+ conn.close()
286
+
287
+ return [
288
+ {
289
+ 'id': tt[0],
290
+ 'class_section': tt[1],
291
+ 'day_of_week': tt[2],
292
+ 'period_number': tt[3],
293
+ 'start_time': tt[4],
294
+ 'end_time': tt[5],
295
+ 'subject': tt[6],
296
+ 'teacher_name': tt[7],
297
+ 'room_number': tt[8],
298
+ 'created_by': tt[9],
299
+ 'created_at': tt[10]
300
+ }
301
+ for tt in timetable_data
302
+ ]
303
+
304
+ def update_timetable_entry(self, timetable_id, **kwargs):
305
+ """Update timetable entry"""
306
+ conn = self.db.get_connection()
307
+ cursor = conn.cursor()
308
+
309
+ updates = []
310
+ params = []
311
+
312
+ for key, value in kwargs.items():
313
+ if key in ['class_section', 'day_of_week', 'period_number', 'start_time', 'end_time',
314
+ 'subject', 'teacher_name', 'room_number']:
315
+ updates.append(f"{key} = ?")
316
+ params.append(value)
317
+
318
+ if updates:
319
+ updates.append("updated_at = CURRENT_TIMESTAMP")
320
+ params.append(timetable_id)
321
+ cursor.execute(f'''
322
+ UPDATE timetable SET {", ".join(updates)} WHERE id = ?
323
+ ''', params)
324
+ conn.commit()
325
+
326
+ conn.close()
327
+ return True
328
+
329
+ def delete_timetable_entry(self, timetable_id):
330
+ """Delete timetable entry"""
331
+ conn = self.db.get_connection()
332
+ cursor = conn.cursor()
333
+
334
+ cursor.execute('UPDATE timetable SET is_active = 0 WHERE id = ?', (timetable_id,))
335
+ conn.commit()
336
+ conn.close()
337
+
338
+ return True
339
+
340
+ # Dashboard Statistics
341
+ def get_admin_dashboard_stats(self):
342
+ """Get statistics for admin dashboard"""
343
+ conn = self.db.get_connection()
344
+ cursor = conn.cursor()
345
+
346
+ stats = {}
347
+
348
+ # Count active announcements
349
+ cursor.execute('SELECT COUNT(*) FROM announcements WHERE is_active = 1')
350
+ stats['active_announcements'] = cursor.fetchone()[0]
351
+
352
+ # Count syllabus entries
353
+ cursor.execute('SELECT COUNT(*) FROM syllabus WHERE is_active = 1')
354
+ stats['syllabus_entries'] = cursor.fetchone()[0]
355
+
356
+ # Count timetable entries
357
+ cursor.execute('SELECT COUNT(*) FROM timetable WHERE is_active = 1')
358
+ stats['timetable_entries'] = cursor.fetchone()[0]
359
+
360
+ # Count students
361
+ cursor.execute('SELECT COUNT(*) FROM students')
362
+ stats['total_students'] = cursor.fetchone()[0]
363
+
364
+ # Count upcoming exams
365
+ cursor.execute('SELECT COUNT(*) FROM examinations WHERE exam_date >= date("now")')
366
+ stats['upcoming_exams'] = cursor.fetchone()[0]
367
+
368
+ conn.close()
369
+ return stats
370
+
371
+ # Initialize admin service
372
+ admin_service = AdminService()