mirror of
https://github.com/Sea-Haven-Industries/afterhours-shift-manager.git
synced 2026-09-30 07:53:11 +00:00
Merge pull request #8 from Sea-Haven-Industries/feature/oncall-rate-command
feat: Add /oncall rate command for managing pay rates
This commit is contained in:
commit
9782cd98ee
3 changed files with 72 additions and 0 deletions
53
src/app.py
53
src/app.py
|
|
@ -105,6 +105,8 @@ def create_app(bot_token: str, signing_secret: str) -> App:
|
|||
respond(blocks=build_roster_blocks(schedule.get_roster()))
|
||||
elif text == "pay":
|
||||
_show_pay(respond, schedule)
|
||||
elif text.startswith("rate"):
|
||||
_handle_rate(respond, schedule, text)
|
||||
elif text.startswith("register"):
|
||||
_handle_register(respond, schedule, user_id, text)
|
||||
elif text.startswith("pick"):
|
||||
|
|
@ -177,6 +179,57 @@ def create_app(bot_token: str, signing_secret: str) -> App:
|
|||
else:
|
||||
respond(text=f"No pay record found for the week of {prev_monday.strftime('%b %-d')}.")
|
||||
|
||||
def _handle_rate(respond, schedule, text):
|
||||
parts = text.split()
|
||||
# /oncall rate — show current rates
|
||||
if len(parts) == 1:
|
||||
default_rate = schedule.get_shift_rate()
|
||||
roster = schedule.get_roster()
|
||||
lines = [f"*Default rate:* ${default_rate:.2f}/shift\n"]
|
||||
custom = [(e["SK"], e.get("name", "Unknown"), float(e["shift_rate"])) for e in roster if e.get("shift_rate")]
|
||||
if custom:
|
||||
lines.append("*Per-person rates:*")
|
||||
for ext, name, rate in sorted(custom, key=lambda x: x[0]):
|
||||
lines.append(f"• {name} (Ext {ext}) — ${rate:.2f}/shift")
|
||||
else:
|
||||
lines.append("_No per-person rates set — everyone uses the default._")
|
||||
respond(text="\n".join(lines))
|
||||
return
|
||||
|
||||
# /oncall rate default <amount>
|
||||
if parts[1] == "default":
|
||||
if len(parts) < 3:
|
||||
respond(text="Usage: `/oncall rate default <amount>` (e.g. `/oncall rate default 50`)")
|
||||
return
|
||||
try:
|
||||
amount = float(parts[2].replace("$", ""))
|
||||
except ValueError:
|
||||
respond(text=f"Invalid amount: `{parts[2]}`")
|
||||
return
|
||||
schedule.set_default_shift_rate(amount)
|
||||
respond(text=f"Default shift rate set to *${amount:.2f}*.")
|
||||
return
|
||||
|
||||
# /oncall rate <extension> <amount>
|
||||
if len(parts) < 3:
|
||||
respond(text="Usage: `/oncall rate <extension> <amount>` (e.g. `/oncall rate 114 75`)")
|
||||
return
|
||||
|
||||
ext = parts[1]
|
||||
employee = schedule.get_employee_by_extension(ext)
|
||||
if not employee:
|
||||
respond(text=f"Extension `{ext}` not found in the roster.")
|
||||
return
|
||||
|
||||
try:
|
||||
amount = float(parts[2].replace("$", ""))
|
||||
except ValueError:
|
||||
respond(text=f"Invalid amount: `{parts[2]}`")
|
||||
return
|
||||
|
||||
schedule.set_employee_shift_rate(ext, amount)
|
||||
respond(text=f"Shift rate for *{employee['name']}* (Ext {ext}) set to *${amount:.2f}*.")
|
||||
|
||||
def _handle_register(respond, schedule, user_id, text):
|
||||
parts = text.split()
|
||||
if len(parts) < 2:
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ def build_help_blocks() -> list[dict]:
|
|||
"`/oncall swap <date> @person` — Swap your shift with someone\n"
|
||||
"`/oncall register <extension>` — Link your Slack account to your extension\n"
|
||||
"`/oncall pay` — Show last week's pay summary\n"
|
||||
"`/oncall rate` — Show current shift rates\n"
|
||||
"`/oncall rate default <amount>` — Set the default rate\n"
|
||||
"`/oncall rate <ext> <amount>` — Set a person's rate\n"
|
||||
"`/oncall roster` — Show all registered employees\n"
|
||||
"`/oncall help` — Show this help message\n\n"
|
||||
"_Dates can be: today, tomorrow, monday, friday, 4/5, 2026-04-05_"
|
||||
|
|
|
|||
|
|
@ -127,6 +127,22 @@ class ShiftSchedule:
|
|||
resp = self.table.get_item(Key={"PK": "CONFIG", "SK": "CONFIG"})
|
||||
return resp.get("Item", {})
|
||||
|
||||
def set_default_shift_rate(self, rate: float) -> None:
|
||||
"""Set the global default shift rate in config."""
|
||||
self.table.update_item(
|
||||
Key={"PK": "CONFIG", "SK": "CONFIG"},
|
||||
UpdateExpression="SET shift_rate = :r",
|
||||
ExpressionAttributeValues={":r": str(rate)},
|
||||
)
|
||||
|
||||
def set_employee_shift_rate(self, extension: str, rate: float) -> None:
|
||||
"""Set a per-person shift rate on a roster entry."""
|
||||
self.table.update_item(
|
||||
Key={"PK": "ROSTER", "SK": extension},
|
||||
UpdateExpression="SET shift_rate = :r",
|
||||
ExpressionAttributeValues={":r": str(rate)},
|
||||
)
|
||||
|
||||
def get_shift_rate(self, extension: str | None = None) -> float:
|
||||
"""Get the per-shift pay rate.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue