diff --git a/src/server/app.py b/src/server/app.py index ad2cc98..54f89b0 100644 --- a/src/server/app.py +++ b/src/server/app.py @@ -37,6 +37,21 @@ def latest_menu_file() -> Path | None: return files[0] if files else None +def _official_menu_retail_by_name() -> dict[str, Decimal]: + menu_file = latest_menu_file() + if not menu_file: + return {} + with open(menu_file) as f: + meals = (json.load(f) or {}).get("meals") or [] + out: dict[str, Decimal] = {} + for meal in meals: + name = (meal.get("name") or "").strip() + if not name or meal.get("price") is None: + continue + out[name] = Decimal(str(meal["price"])) + return out + + @app.route("/") def index(): form_file = OUTPUT_DIR / f"order-form-{current_week()}.html" @@ -154,8 +169,17 @@ def submit_order(): subsidy_mult = Decimal("1") - (subsidy_pct / Decimal("100")) filtered = [i for i in items if i.get("quantity", 0) > 0] + official_retail = _official_menu_retail_by_name() + if not official_retail: + return jsonify({"error": "Menu temporarily unavailable"}), 503 for item in filtered: - retail = Decimal(str(item.get("retail_price", item.get("price", 0)) or 0)) + meal_name = (item.get("name") or "").strip() + if meal_name not in official_retail: + return jsonify({"error": "One or more meals are not on this week's menu"}), 400 + + for item in filtered: + meal_name = (item.get("name") or "").strip() + retail = official_retail[meal_name] qty = Decimal(str(item.get("quantity", 0))) bulk_price = (retail * bulk_mult).quantize(TWO_PLACES, rounding=ROUND_HALF_UP) emp_price = (bulk_price * subsidy_mult).quantize( diff --git a/src/server/generate_form.py b/src/server/generate_form.py index 800e524..0f1af40 100644 --- a/src/server/generate_form.py +++ b/src/server/generate_form.py @@ -104,7 +104,8 @@ function initGoogleAuth() { function handleCredentialResponse(response) { googleCredential = response.credential; const b64 = response.credential.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'); - const payload = JSON.parse(atob(b64)); + const payloadBytes = Uint8Array.from(atob(b64), c => c.charCodeAt(0)); + const payload = JSON.parse(new TextDecoder().decode(payloadBytes)); googleUser = { name: payload.name, email: payload.email }; document.getElementById('auth-overlay').style.display = 'none';