med scheduling fixes

This commit is contained in:
2026-02-17 18:33:43 -06:00
parent 8ac7a5129a
commit cf2b4be033

View File

@@ -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 16 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 # 16 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 16 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")