mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 19:23:13 +00:00
Apply ruff check --fix and ruff format across all Python files to pass CI pipeline. Remove unused imports (os, sys), fix f-strings without placeholders. Update README to reflect sync-roster Lambda, corrected shared layer path, and current project structure.
144 lines
4.2 KiB
Python
144 lines
4.2 KiB
Python
import json
|
|
import os
|
|
from decimal import Decimal
|
|
|
|
from shared.db import current_week, get_orders, get_roster, get_summary
|
|
from shared.slack import post_channel_message, send_dm
|
|
|
|
|
|
class DecimalEncoder(json.JSONEncoder):
|
|
def default(self, o):
|
|
if isinstance(o, Decimal):
|
|
return float(o)
|
|
return super().default(o)
|
|
|
|
|
|
def lambda_handler(event, context):
|
|
event_type = event.get("event", "")
|
|
|
|
if event_type == "menu_published":
|
|
return handle_menu_published(event)
|
|
elif event_type == "orders_aggregated":
|
|
return handle_orders_aggregated(event)
|
|
elif event_type == "reminder":
|
|
return handle_reminder(event)
|
|
|
|
return {"error": f"Unknown event type: {event_type}"}
|
|
|
|
|
|
def handle_menu_published(event):
|
|
form_url = os.environ.get("FORM_URL", "")
|
|
week = event.get("week", current_week())
|
|
meal_count = event.get("meal_count", "")
|
|
|
|
text = "This week's meal order is open! Deadline: Thursday 6pm."
|
|
blocks = [
|
|
{
|
|
"type": "header",
|
|
"text": {"type": "plain_text", "text": "Meal Order Open"},
|
|
},
|
|
{
|
|
"type": "section",
|
|
"text": {
|
|
"type": "mrkdwn",
|
|
"text": (
|
|
f"*<{form_url}|Place your order>*\n\n"
|
|
f"*Deadline:* Thursday 6pm\n"
|
|
f"*Menu:* {meal_count} meals available"
|
|
),
|
|
},
|
|
},
|
|
]
|
|
|
|
post_channel_message(text, blocks)
|
|
return {"status": "notified", "event": "menu_published", "week": week}
|
|
|
|
|
|
def handle_orders_aggregated(event):
|
|
week = event.get("week", current_week())
|
|
summary = get_summary(week)
|
|
if not summary:
|
|
return {"status": "no_summary", "week": week}
|
|
|
|
total_employees = int(summary.get("total_employees", 0))
|
|
total_meals = int(summary.get("total_meals", 0))
|
|
grand_total = float(summary.get("grand_total", 0))
|
|
|
|
meal_lines = []
|
|
for m in summary.get("meals", []):
|
|
meal_lines.append(f"{m['meal']}: *{int(m['quantity'])}*")
|
|
meal_list = "\n".join(meal_lines)
|
|
|
|
text = f"Meal orders closed for {week}. {total_employees} employees, {total_meals} meals, ${grand_total:.2f} total."
|
|
blocks = [
|
|
{
|
|
"type": "header",
|
|
"text": {"type": "plain_text", "text": f"Meal Orders Closed — {week}"},
|
|
},
|
|
{
|
|
"type": "section",
|
|
"text": {
|
|
"type": "mrkdwn",
|
|
"text": (
|
|
f"*{total_employees}* employees ordered\n"
|
|
f"*{total_meals}* total meals\n"
|
|
f"*${grand_total:.2f}* grand total"
|
|
),
|
|
},
|
|
},
|
|
{"type": "divider"},
|
|
{
|
|
"type": "section",
|
|
"text": {
|
|
"type": "mrkdwn",
|
|
"text": f"*Order for Redefine Meals:*\n{meal_list}",
|
|
},
|
|
},
|
|
]
|
|
|
|
post_channel_message(text, blocks)
|
|
return {"status": "notified", "event": "orders_aggregated", "week": week}
|
|
|
|
|
|
def handle_reminder(event):
|
|
week = event.get("week", current_week())
|
|
form_url = os.environ.get("FORM_URL", "")
|
|
|
|
roster = get_roster()
|
|
if not roster:
|
|
return {"status": "no_roster"}
|
|
|
|
orders = get_orders(week)
|
|
ordered_emails = {o["employee_email"].lower() for o in orders}
|
|
|
|
missing = [emp for emp in roster if emp["email"].lower() not in ordered_emails]
|
|
|
|
dm_count = 0
|
|
for emp in missing:
|
|
slack_id = emp.get("slack_user_id")
|
|
if not slack_id:
|
|
continue
|
|
send_dm(
|
|
slack_id,
|
|
f"Meal orders close at 6pm today. Place your order: {form_url}",
|
|
blocks=[
|
|
{
|
|
"type": "section",
|
|
"text": {
|
|
"type": "mrkdwn",
|
|
"text": (
|
|
f"Hey {emp['name'].split()[0]}! Meal orders close at *6pm today*.\n\n"
|
|
f"*<{form_url}|Place your order>*"
|
|
),
|
|
},
|
|
}
|
|
],
|
|
)
|
|
dm_count += 1
|
|
|
|
return {
|
|
"status": "reminders_sent",
|
|
"week": week,
|
|
"dm_count": dm_count,
|
|
"missing_count": len(missing),
|
|
}
|