-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscheduler.py
More file actions
120 lines (97 loc) · 3.75 KB
/
Copy pathscheduler.py
File metadata and controls
120 lines (97 loc) · 3.75 KB
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
110
111
112
113
114
115
116
117
118
119
120
"""
Scheduled Tasks for ISUFST CareHub.
Automated jobs for reminders, expiry alerts, and maintenance.
"""
from apscheduler.schedulers.background import BackgroundScheduler
from models import db, User, Appointment, Inventory
from models_extended import AppointmentExtended
from notification_service import notify_appointment_reminder, notify_expiring_medicines
from datetime import datetime, date, timedelta
from flask import current_app
scheduler = BackgroundScheduler()
def send_appointment_reminders():
"""Send reminders 24 hours before appointments."""
with current_app.app_context():
tomorrow = date.today() + timedelta(days=1)
# Get appointments for tomorrow
appointments = Appointment.query.filter(
Appointment.appointment_date == tomorrow,
Appointment.status.in_(['Confirmed', 'Pending'])
).all()
for appt in appointments:
# Check if reminder already sent
ext = AppointmentExtended.query.filter_by(appointment_id=appt.id).first()
if ext and not ext.reminder_sent:
notify_appointment_reminder(appt, appt.student)
ext.reminder_sent = True
db.session.commit()
print(f'[SCHEDULER] Sent {len(appointments)} appointment reminders')
def check_expiring_medicines():
"""Weekly check for expiring medicines and alert admins."""
with current_app.app_context():
# Get medicines expiring in next 30 days
expiry_threshold = date.today() + timedelta(days=30)
expiring = Inventory.query.filter(
Inventory.category == 'Medicine',
Inventory.expiry_date <= expiry_threshold,
Inventory.expiry_date >= date.today(),
Inventory.quantity > 0
).all()
if expiring:
# Get all admins
admins = User.query.filter(
User.role == 'admin',
User.is_active == True
).all()
notify_expiring_medicines(admins, expiring)
print(f'[SCHEDULER] Alerted {len(admins)} admins about {len(expiring)} expiring medicines')
def auto_cancel_no_shows():
"""Automatically mark missed appointments as no-show."""
with current_app.app_context():
yesterday = date.today() - timedelta(days=1)
# Find appointments that were not completed/cancelled
no_shows = Appointment.query.filter(
Appointment.appointment_date < date.today(),
Appointment.status.in_(['Pending', 'Confirmed'])
).all()
count = 0
for appt in no_shows:
appt.status = 'No Show'
count += 1
db.session.commit()
print(f'[SCHEDULER] Marked {count} appointments as no-show')
def init_scheduler(app):
"""Initialize and start the scheduler."""
# Daily reminder check at 9:00 AM
scheduler.add_job(
func=send_appointment_reminders,
trigger='cron',
hour=9,
minute=0,
id='appointment_reminders',
replace_existing=True
)
# Weekly medicine expiry check (Monday 8:00 AM)
scheduler.add_job(
func=check_expiring_medicines,
trigger='cron',
day_of_week='mon',
hour=8,
minute=0,
id='expiry_check',
replace_existing=True
)
# Daily no-show check at midnight
scheduler.add_job(
func=auto_cancel_no_shows,
trigger='cron',
hour=0,
minute=15,
id='no_show_check',
replace_existing=True
)
scheduler.start()
print('[SCHEDULER] Background scheduler started')
# Ensure scheduler stops on app shutdown
import atexit
atexit.register(lambda: scheduler.shutdown())