05/24 Enhance functionalities

This commit is contained in:
2026-05-24 18:10:11 -04:00
parent 6605484927
commit fbf271ed71
15 changed files with 593 additions and 30 deletions
+41 -2
View File
@@ -8,9 +8,10 @@ from flask import (Blueprint, render_template, request, redirect, url_for,
from models import (
get_all_bids, get_bid, create_bid, update_bid, delete_bid,
get_bid_updates, add_bid_update, delete_bid_update, BID_STATUSES,
log_action,
log_action, get_bids_due_soon, get_admin_emails,
)
from utils.decorators import login_required
from utils.decorators import login_required, admin_required
from utils.email import send_email
logger = logging.getLogger("routes.bid_tracker")
bid_tracker_bp = Blueprint("bid_tracker", __name__, url_prefix="/bids")
@@ -237,3 +238,41 @@ def delete_update_json(update_id):
except Exception as e:
logger.error(f"delete_update_json error: {e}")
return jsonify({"error": str(e)}), 500
@bid_tracker_bp.route("/remind", methods=["POST"])
@admin_required
def send_reminders():
"""Send an email digest of bids due within 7 days to all admin users with emails."""
user = session["user"]
bids = get_bids_due_soon(days=7)
recipients = get_admin_emails()
if not bids:
flash("No active bids due within 7 days.", "info")
return redirect(url_for("bid_tracker.bids_list"))
if not recipients:
flash("No admin email addresses configured. Add them via Admin → Users.", "warning")
return redirect(url_for("bid_tracker.bids_list"))
lines = [f"Bid Deadline Reminder — {len(bids)} bid(s) due within 7 days:\n"]
for b in bids:
due = str(b["due_date"])[:10] if b.get("due_date") else "N/A"
line = f"{b['title']} — Due: {due} — Status: {b['status']}"
if b.get("solicitation_number"):
line += f" — Sol#: {b['solicitation_number']}"
lines.append(line)
lines.append("\nLog in to Website Checker for full details.")
body = "\n".join(lines)
try:
send_email(recipients, "Website Checker — Upcoming Bid Deadlines", body)
log_action(user["id"], "BID_REMIND", "bid_tracker", None,
f"Bid reminder email sent to {len(recipients)} admin(s), {len(bids)} bid(s) listed.")
flash(f"Reminder digest sent to {len(recipients)} recipient(s).", "success")
except Exception as e:
logger.error(f"send_reminders error: {e}")
flash(f"Failed to send email: {e}", "danger")
return redirect(url_for("bid_tracker.bids_list"))