mirror of
https://github.com/Sea-Haven-Industries/afterhours-shift-manager.git
synced 2026-09-30 20:43:12 +00:00
- Reject /oncall pick and /oncall drop for past dates - Show ephemeral error when stale pickup buttons are clicked - Hide pickup buttons for dates in the past - Add explicit "Day (8am-5pm)" and "Night (5pm-8am)" labels to schedule lines, pickup buttons, and shift change notifications
This commit is contained in:
parent
9dd7cbd0f8
commit
e9b55d357b
2 changed files with 44 additions and 12 deletions
|
|
@ -8,6 +8,12 @@ EASTERN = ZoneInfo("America/New_York")
|
|||
WEEKEND_DAYS = {"Saturday", "Sunday"}
|
||||
|
||||
|
||||
SHIFT_LABELS = {
|
||||
"day": "Day (8am–5pm)",
|
||||
"night": "Night (5pm–8am)",
|
||||
}
|
||||
|
||||
|
||||
def _format_shift_line(
|
||||
date: datetime,
|
||||
ext: str,
|
||||
|
|
@ -17,8 +23,8 @@ def _format_shift_line(
|
|||
shift_type: str = "night",
|
||||
) -> str:
|
||||
day_label = date.strftime("%a %b %-d")
|
||||
if shift_type == "day":
|
||||
day_label += " (Day 8a–5p)"
|
||||
if shift_type in SHIFT_LABELS:
|
||||
day_label += f" {SHIFT_LABELS[shift_type]}"
|
||||
if is_today:
|
||||
day_label = f"*{day_label} (today)*"
|
||||
|
||||
|
|
@ -56,17 +62,19 @@ def build_week_schedule(schedule, start_date: datetime | None = None) -> list[di
|
|||
day_name = date.strftime("%A")
|
||||
is_today = date_str == today_str
|
||||
|
||||
is_past = date_str < today_str
|
||||
|
||||
# Weekend day shift (8am–5pm)
|
||||
if day_name in WEEKEND_DAYS:
|
||||
ext, name, source = schedule.resolve_shift(date_str, day_name, "day")
|
||||
lines.append(_format_shift_line(date, ext, name, source, is_today, "day"))
|
||||
if source == "available":
|
||||
if source == "available" and not is_past:
|
||||
open_shifts.append((date_str, "day"))
|
||||
|
||||
# After-hours (night) shift
|
||||
ext, name, source = schedule.resolve_shift(date_str, day_name)
|
||||
lines.append(_format_shift_line(date, ext, name, source, is_today))
|
||||
if source == "available":
|
||||
if source == "available" and not is_past:
|
||||
open_shifts.append((date_str, "night"))
|
||||
|
||||
blocks = [
|
||||
|
|
@ -89,14 +97,14 @@ def build_week_schedule(schedule, start_date: datetime | None = None) -> list[di
|
|||
elements = []
|
||||
for date_str, shift_type in open_shifts:
|
||||
dt = datetime.strptime(date_str, "%Y-%m-%d")
|
||||
suffix = " (Day)" if shift_type == "day" else ""
|
||||
label = "Day" if shift_type == "day" else "Night"
|
||||
action_suffix = "_day" if shift_type == "day" else ""
|
||||
elements.append(
|
||||
{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": f"Pick up {dt.strftime('%a %b %-d')}{suffix}",
|
||||
"text": f"Pick up {dt.strftime('%a %b %-d')} {label}",
|
||||
},
|
||||
"action_id": f"pickup_{date_str}{action_suffix}",
|
||||
"style": "primary",
|
||||
|
|
@ -112,20 +120,26 @@ def build_week_schedule(schedule, start_date: datetime | None = None) -> list[di
|
|||
|
||||
|
||||
def build_shift_change_message(
|
||||
user_id: str, date_str: str, action: str, ext: str, name: str
|
||||
user_id: str,
|
||||
date_str: str,
|
||||
action: str,
|
||||
ext: str,
|
||||
name: str,
|
||||
shift_type: str = "night",
|
||||
) -> list[dict]:
|
||||
"""Build a channel notification for a shift change."""
|
||||
dt = datetime.strptime(date_str, "%Y-%m-%d")
|
||||
day_label = dt.strftime("%A, %b %-d")
|
||||
type_label = f" ({SHIFT_LABELS.get(shift_type, shift_type)})" if shift_type == "day" else ""
|
||||
|
||||
if action == "picked_up":
|
||||
text = f":white_check_mark: <@{user_id}> picked up the shift for *{day_label}* (Ext {ext})"
|
||||
text = f":white_check_mark: <@{user_id}> picked up the *{day_label}*{type_label} shift (Ext {ext})"
|
||||
elif action == "dropped":
|
||||
text = f":warning: <@{user_id}> dropped the shift for *{day_label}* — it's now *Available*"
|
||||
text = f":warning: <@{user_id}> dropped the *{day_label}*{type_label} shift — it's now *Available*"
|
||||
elif action == "swapped":
|
||||
text = f":arrows_counterclockwise: <@{user_id}> swapped into the shift for *{day_label}* (Ext {ext})"
|
||||
text = f":arrows_counterclockwise: <@{user_id}> swapped into the *{day_label}*{type_label} shift (Ext {ext})"
|
||||
else:
|
||||
text = f"Shift updated for *{day_label}*: {name} (Ext {ext})"
|
||||
text = f"Shift updated for *{day_label}*{type_label}: {name} (Ext {ext})"
|
||||
|
||||
return [{"type": "section", "text": {"type": "mrkdwn", "text": text}}]
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,15 @@ def create_app(
|
|||
user_id = body["user"]["id"]
|
||||
channel_id = body["channel"]["id"]
|
||||
|
||||
today_str = datetime.now(EASTERN).strftime("%Y-%m-%d")
|
||||
if date_str < today_str:
|
||||
client.chat_postEphemeral(
|
||||
channel=channel_id,
|
||||
user=user_id,
|
||||
text="That shift has already passed and can't be picked up.",
|
||||
)
|
||||
return
|
||||
|
||||
employee = schedule.get_employee_by_slack_id(user_id)
|
||||
if not employee:
|
||||
client.chat_postEphemeral(
|
||||
|
|
@ -177,7 +186,8 @@ def create_app(
|
|||
_update_3cx_routing(employee["extension"])
|
||||
|
||||
blocks = build_shift_change_message(
|
||||
user_id, date_str, "picked_up", employee["extension"], employee["name"]
|
||||
user_id, date_str, "picked_up", employee["extension"], employee["name"],
|
||||
shift_type=shift_type,
|
||||
)
|
||||
respond(
|
||||
response_type="in_channel",
|
||||
|
|
@ -345,6 +355,10 @@ def create_app(
|
|||
return
|
||||
|
||||
date_str = date.strftime("%Y-%m-%d")
|
||||
if date_str < datetime.now(EASTERN).strftime("%Y-%m-%d"):
|
||||
respond(text="You can't pick up a shift in the past.")
|
||||
return
|
||||
|
||||
day_name = date.strftime("%A")
|
||||
ext, name, source = schedule.resolve_shift(date_str, day_name)
|
||||
|
||||
|
|
@ -396,6 +410,10 @@ def create_app(
|
|||
return
|
||||
|
||||
date_str = date.strftime("%Y-%m-%d")
|
||||
if date_str < datetime.now(EASTERN).strftime("%Y-%m-%d"):
|
||||
respond(text="You can't drop a shift in the past.")
|
||||
return
|
||||
|
||||
day_name = date.strftime("%A")
|
||||
ext, name, source = schedule.resolve_shift(date_str, day_name)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue