04/23 Fixed bugs
This commit is contained in:
@@ -376,14 +376,46 @@ def update_user(admin_id, user_id, username, role, full_name, is_active, passwor
|
||||
|
||||
|
||||
def delete_user(admin_id, user_id):
|
||||
"""
|
||||
Hard-delete a user record.
|
||||
Guards:
|
||||
- An admin cannot delete their own account.
|
||||
- The last active admin account cannot be deleted.
|
||||
Raises ValueError with a descriptive message when either guard fires.
|
||||
"""
|
||||
conn = None
|
||||
try:
|
||||
conn = get_connection()
|
||||
cur = conn.cursor()
|
||||
cur = conn.cursor(dictionary=True)
|
||||
|
||||
# Guard 1: self-delete
|
||||
if admin_id == user_id:
|
||||
cur.close()
|
||||
raise ValueError("You cannot delete your own account.")
|
||||
|
||||
# Guard 2: prevent removing the last active admin
|
||||
cur.execute(
|
||||
"SELECT role FROM users WHERE id=%s", (user_id,)
|
||||
)
|
||||
target = cur.fetchone()
|
||||
if target and target["role"] == "admin":
|
||||
cur.execute(
|
||||
"SELECT COUNT(*) AS n FROM users WHERE role='admin' AND is_active=1"
|
||||
)
|
||||
admin_count = cur.fetchone()["n"]
|
||||
if admin_count <= 1:
|
||||
cur.close()
|
||||
raise ValueError(
|
||||
"Cannot delete the last active administrator account. "
|
||||
"Promote another user to admin first."
|
||||
)
|
||||
|
||||
cur.execute("DELETE FROM users WHERE id=%s", (user_id,))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
log_action(admin_id, "DELETE_USER", "users", user_id, f"Deleted user id={user_id}.")
|
||||
log_action(admin_id, "DELETE_USER", "users", user_id,
|
||||
f"Deleted user id={user_id}.")
|
||||
logger.info(f"User id={user_id} deleted by admin_id={admin_id}.")
|
||||
finally:
|
||||
if conn:
|
||||
conn.close()
|
||||
@@ -649,6 +681,13 @@ def get_today_checks(user_id: int):
|
||||
WHERE s.is_active = 1
|
||||
AND w.is_active = 1
|
||||
AND LOCATE(CAST(DAYOFWEEK(CURDATE()) AS CHAR), s.days_of_week) > 0
|
||||
AND (
|
||||
w.visibility = 'all'
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM website_users wu
|
||||
WHERE wu.website_id = w.id AND wu.user_id = %s
|
||||
)
|
||||
)
|
||||
AND (
|
||||
w.check_type = 'daily'
|
||||
OR (
|
||||
@@ -664,7 +703,7 @@ def get_today_checks(user_id: int):
|
||||
GROUP BY w.id, sc.id, sc.checked_at, sc.user_note, sc.user_id
|
||||
ORDER BY sort_order, w.name
|
||||
""",
|
||||
(user_id, user_id, user_id)
|
||||
(user_id, user_id, user_id, user_id)
|
||||
)
|
||||
else:
|
||||
# Legacy fallback: show active websites, filtered by visibility
|
||||
@@ -861,17 +900,27 @@ def get_unchecked_report(target_date=None, user_id=None):
|
||||
conn = get_connection()
|
||||
cur = conn.cursor(dictionary=True)
|
||||
|
||||
date_val = str(target_date) if target_date else None
|
||||
|
||||
user_filter = "AND u.id = %s" if user_id else ""
|
||||
params_inner = [date_val or "CURDATE()"]
|
||||
if user_id:
|
||||
params_inner.append(user_id)
|
||||
|
||||
# Use a bind param only when a specific date is provided.
|
||||
# When no date is given, embed CURDATE() directly in SQL so MySQL
|
||||
# evaluates it as a function — passing "CURDATE()" as a %s bind
|
||||
# parameter treats it as a literal string, not a SQL function, and
|
||||
# causes the NOT EXISTS filter to match nothing (returns 0 rows).
|
||||
if target_date:
|
||||
date_val = str(target_date)
|
||||
date_expr = "%s"
|
||||
date_params = [date_val]
|
||||
else:
|
||||
date_expr = "CURDATE()"
|
||||
date_params = []
|
||||
|
||||
params = date_params + ([user_id] if user_id else []) + date_params
|
||||
|
||||
cur.execute(
|
||||
f"""
|
||||
SELECT
|
||||
%s AS check_date,
|
||||
{date_expr} AS check_date,
|
||||
u.username,
|
||||
COALESCE(u.full_name, u.username) AS full_name,
|
||||
w.name AS website_name,
|
||||
@@ -887,11 +936,11 @@ def get_unchecked_report(target_date=None, user_id=None):
|
||||
SELECT 1 FROM shift_checks sc
|
||||
WHERE sc.website_id = w.id
|
||||
AND sc.user_id = u.id
|
||||
AND DATE(sc.checked_at) = %s
|
||||
AND DATE(sc.checked_at) = {date_expr}
|
||||
)
|
||||
ORDER BY u.username, w.name
|
||||
""",
|
||||
([date_val or "CURDATE()"] + ([user_id] if user_id else []) + [date_val or "CURDATE()"])
|
||||
params
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
|
||||
Reference in New Issue
Block a user