From f5bbb93d59b125d12b01664da666c2f93fe443f0 Mon Sep 17 00:00:00 2001 From: ijuanes Date: Sat, 20 Jun 2026 08:53:55 +0100 Subject: [PATCH] fix(ui): fix user_loans SQL query with HAVING clause for status filter - Fix COUNT() misuse in SQLite subquery - Use HAVING clause for aggregate function filtering (with_loans, no_loans) - Properly count distinct users for pagination - Maintain all search and pagination functionality --- app.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app.py b/app.py index e44487b..fc96add 100644 --- a/app.py +++ b/app.py @@ -316,6 +316,7 @@ def user_loans(): conditions = [] params = [] + having_conditions = [] # Add search filter if search: @@ -323,31 +324,38 @@ def user_loans(): search_param = f"%{search}%" params.extend([search_param, search_param, search_param]) - # Add status filter + # Add status filter (use HAVING for aggregate functions) if status_filter == 'with_loans': - conditions.append("COUNT(l.id) > 0") + having_conditions.append("COUNT(l.id) > 0") elif status_filter == 'no_loans': - conditions.append("COUNT(l.id) = 0") + having_conditions.append("COUNT(l.id) = 0") - # Combine conditions + # Combine conditions for WHERE clause + where_clause = "" if conditions: - query += " WHERE " + " AND ".join(conditions) + where_clause = " WHERE " + " AND ".join(conditions) + + # Combine HAVING conditions + having_clause = "" + if having_conditions: + having_clause = " HAVING " + " AND ".join(having_conditions) # Group by and order - query += " GROUP BY u.id, u.name, u.identification, u.email, u.phone" - query += " ORDER BY u.name COLLATE NOCASE" + group_by = " GROUP BY u.id, u.name, u.identification, u.email, u.phone" + order_by = " ORDER BY u.name COLLATE NOCASE" # Get total count for pagination - count_query = f"SELECT COUNT(*) FROM ({query})" + # We need to count distinct users matching the criteria + count_query = f"SELECT COUNT(DISTINCT u.id) FROM users u LEFT JOIN loans l ON u.id = l.user_id AND l.status = 'active'{where_clause}{having_clause}" cursor.execute(count_query, params) total_users = cursor.fetchone()[0] total_pages = (total_users + per_page - 1) // per_page - # Add pagination to query - query += f" LIMIT {per_page} OFFSET {offset}" + # Build final query with pagination + final_query = query + where_clause + group_by + having_clause + order_by + f" LIMIT {per_page} OFFSET {offset}" # Execute main query - cursor.execute(query, params) + cursor.execute(final_query, params) users = cursor.fetchall() # Convert to list of dicts for template @@ -388,6 +396,8 @@ def user_loans(): per_page=per_page) + + @app.route('/user_loans/') def user_loans_detail(user_id): """