med scheduling fixes
This commit is contained in:
@@ -424,8 +424,18 @@ async def handle_medication(message, session, parsed):
|
||||
await message.channel.send(f"Error: {resp.get('error', 'Failed to log')}")
|
||||
|
||||
elif action == "take_all":
|
||||
# Mark all currently pending (untaken, non-skipped, non-PRN) doses as taken
|
||||
# Auto-mark doses due within the last hour (clearly "just taken").
|
||||
# Ask about doses due 1–6 hours ago (today or yesterday) that aren't logged.
|
||||
timezone_offset = await _get_user_timezone(message, session, token)
|
||||
if timezone_offset is None:
|
||||
timezone_offset = 0
|
||||
|
||||
now_local = datetime.now(timezone(timedelta(minutes=-timezone_offset)))
|
||||
now_min = now_local.hour * 60 + now_local.minute
|
||||
current_hhmm = now_local.strftime("%H:%M")
|
||||
|
||||
CURRENT_WINDOW_MIN = 60 # ≤ 1 hour ago → auto-mark
|
||||
LOOKBACK_MIN = 6 * 60 # 1–6 hours ago → ask
|
||||
|
||||
resp, status = api_request("get", "/api/medications/today", token)
|
||||
if status != 200:
|
||||
@@ -433,34 +443,86 @@ async def handle_medication(message, session, parsed):
|
||||
return
|
||||
|
||||
meds_today = resp if isinstance(resp, list) else []
|
||||
marked = []
|
||||
skipped_already = []
|
||||
auto_doses = [] # (med_id, med_name, time_str) → mark silently
|
||||
ask_doses = [] # (med_id, med_name, time_str) → prompt user
|
||||
|
||||
for item in meds_today:
|
||||
med = item.get("medication", {})
|
||||
if item.get("is_prn"):
|
||||
continue
|
||||
times = item.get("scheduled_times", [])
|
||||
taken = set(item.get("taken_times", []))
|
||||
times = item.get("scheduled_times", [])
|
||||
taken = set(item.get("taken_times", []))
|
||||
skipped = set(item.get("skipped_times", []))
|
||||
med_id_local = med.get("id")
|
||||
med_name = med.get("name", "Unknown")
|
||||
med_name = med.get("name", "Unknown")
|
||||
|
||||
pending_times = [t for t in times if t not in taken and t not in skipped]
|
||||
if not pending_times:
|
||||
skipped_already.append(med_name)
|
||||
continue
|
||||
for t in times:
|
||||
if t in taken or t in skipped:
|
||||
continue
|
||||
|
||||
for t in pending_times:
|
||||
api_request("post", f"/api/medications/{med_id_local}/take", token, {"scheduled_time": t})
|
||||
marked.append(f"**{med_name}** ({', '.join(pending_times)})")
|
||||
h, m = map(int, t.split(":"))
|
||||
dose_min = h * 60 + m
|
||||
# Handle doses that cross midnight (yesterday's late doses)
|
||||
minutes_ago = now_min - dose_min
|
||||
if minutes_ago < 0:
|
||||
minutes_ago += 24 * 60
|
||||
|
||||
if not marked:
|
||||
await message.channel.send("✅ All medications are already logged for today!")
|
||||
else:
|
||||
if minutes_ago > LOOKBACK_MIN:
|
||||
continue # too old — ignore
|
||||
if t > current_hhmm and minutes_ago > CURRENT_WINDOW_MIN:
|
||||
continue # future dose that somehow wasn't caught — skip
|
||||
|
||||
if minutes_ago <= CURRENT_WINDOW_MIN:
|
||||
auto_doses.append((med_id_local, med_name, t))
|
||||
else:
|
||||
ask_doses.append((med_id_local, med_name, t))
|
||||
|
||||
# Mark the clearly-current doses immediately
|
||||
marked = []
|
||||
for med_id_local, med_name, t in auto_doses:
|
||||
api_request("post", f"/api/medications/{med_id_local}/take", token, {"scheduled_time": t})
|
||||
marked.append(f"**{med_name}** at {t}")
|
||||
|
||||
if marked:
|
||||
lines = "\n".join(f"✅ {m}" for m in marked)
|
||||
await message.channel.send(f"Logged as taken:\n{lines}")
|
||||
|
||||
# Ask about doses from 1–6 hours ago that weren't logged
|
||||
if ask_doses:
|
||||
if "pending_confirmations" not in session:
|
||||
session["pending_confirmations"] = {}
|
||||
session["pending_confirmations"]["med_past_due_check"] = {
|
||||
"action": "take_all_past_confirm",
|
||||
"interaction_type": "medication",
|
||||
"needs_confirmation": False,
|
||||
"doses": [[mid, name, t] for mid, name, t in ask_doses],
|
||||
}
|
||||
dose_lines = "\n".join(f"- **{name}** at {t}" for _, name, t in ask_doses)
|
||||
await message.channel.send(
|
||||
f"❓ Also found unlogged doses from the past 6 hours:\n{dose_lines}\n\n"
|
||||
f"Did you take these too? Reply **yes** or **no**."
|
||||
)
|
||||
elif not marked:
|
||||
await message.channel.send("✅ No past-due medications to log right now.")
|
||||
|
||||
elif action == "take_all_past_confirm":
|
||||
# Handles yes-confirmation for past-due doses surfaced by take_all
|
||||
doses = parsed.get("doses", [])
|
||||
marked = []
|
||||
for dose_info in doses:
|
||||
if isinstance(dose_info, (list, tuple)) and len(dose_info) >= 3:
|
||||
med_id_local, med_name, t = dose_info[0], dose_info[1], dose_info[2]
|
||||
api_request(
|
||||
"post", f"/api/medications/{med_id_local}/take", token,
|
||||
{"scheduled_time": t}
|
||||
)
|
||||
marked.append(f"**{med_name}** at {t}")
|
||||
if marked:
|
||||
lines = "\n".join(f"✅ {m}" for m in marked)
|
||||
await message.channel.send(f"Logged as taken:\n{lines}")
|
||||
else:
|
||||
await message.channel.send("No doses to log.")
|
||||
|
||||
elif action == "skip":
|
||||
med_id = parsed.get("medication_id")
|
||||
name = parsed.get("name")
|
||||
|
||||
Reference in New Issue
Block a user