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
This commit is contained in:
ijuanes 2026-06-20 08:53:55 +01:00
parent c9f3382c7c
commit f5bbb93d59

32
app.py
View file

@ -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/<int:user_id>')
def user_loans_detail(user_id):
"""