Sep 16 - Optimize code, part 2

This commit is contained in:
2026-09-16 14:31:41 -04:00
parent 2c5627354e
commit 13b56fb1d1
9 changed files with 632 additions and 140 deletions
+98 -38
View File
@@ -24,6 +24,7 @@ from sqlalchemy import text, or_, and_
from logger_handler import log_user_activity, log_database_operations
from utils.helpers import (
admin_required,
load_project_manager_scope,
expand_employee_id_filter,
get_base_employee_id,
get_client_ip,
@@ -837,27 +838,38 @@ def time_attendance_locations_api():
Used by the time attendance records page to dynamically scope the location dropdown."""
try:
project_id = request.args.get('project_id', '').strip()
conditions = ["location_name IS NOT NULL"]
params = {}
if project_id:
try:
project_id_int = int(project_id)
params['project_id'] = int(project_id)
except (ValueError, TypeError):
return jsonify({'success': False, 'error': 'Invalid project_id'}), 400
conditions.append("project_id = :project_id")
result = db.session.execute(text("""
SELECT DISTINCT location_name
FROM time_attendance
WHERE project_id = :project_id
AND location_name IS NOT NULL
ORDER BY location_name
"""), {'project_id': project_id_int})
else:
result = db.session.execute(text("""
SELECT DISTINCT location_name
FROM time_attendance
WHERE location_name IS NOT NULL
ORDER BY location_name
"""))
# Project Managers see only their assigned projects / locations (§4)
is_pm, allowed_project_ids, allowed_location_names = load_project_manager_scope()
if is_pm:
if not (allowed_project_ids or allowed_location_names):
return jsonify({'success': True, 'locations': []})
scope = []
if allowed_project_ids:
placeholders = ', '.join(f':pm_project_{i}' for i in range(len(allowed_project_ids)))
scope.append(f"project_id IN ({placeholders})")
params.update({f'pm_project_{i}': pid for i, pid in enumerate(allowed_project_ids)})
if allowed_location_names:
placeholders = ', '.join(f':pm_location_{i}' for i in range(len(allowed_location_names)))
scope.append(f"location_name IN ({placeholders})")
params.update({f'pm_location_{i}': loc for i, loc in enumerate(allowed_location_names)})
conditions.append('(' + ' OR '.join(scope) + ')')
result = db.session.execute(text(f"""
SELECT DISTINCT location_name
FROM time_attendance
WHERE {' AND '.join(conditions)}
ORDER BY location_name
"""), params)
locations = [row[0] for row in result.fetchall()]
logger_handler.logger.info(
@@ -878,28 +890,39 @@ def attendance_locations_api():
Used by the attendance report page to dynamically scope the location dropdown when a project is selected."""
try:
project_id = request.args.get('project_id', '').strip()
conditions = ["ad.location_name IS NOT NULL"]
params = {}
if project_id:
try:
project_id_int = int(project_id)
params['project_id'] = int(project_id)
except (ValueError, TypeError):
return jsonify({'success': False, 'error': 'Invalid project_id'}), 400
conditions.append("qc.project_id = :project_id")
result = db.session.execute(text("""
SELECT DISTINCT ad.location_name
FROM attendance_data ad
INNER JOIN qr_codes qc ON ad.qr_code_id = qc.id
WHERE qc.project_id = :project_id
AND ad.location_name IS NOT NULL
ORDER BY ad.location_name
"""), {'project_id': project_id_int})
else:
result = db.session.execute(text("""
SELECT DISTINCT location_name
FROM attendance_data
WHERE location_name IS NOT NULL
ORDER BY location_name
"""))
# Project Managers see only their assigned projects / locations (§4)
is_pm, allowed_project_ids, allowed_location_names = load_project_manager_scope()
if is_pm:
if not (allowed_project_ids or allowed_location_names):
return jsonify({'success': True, 'locations': []})
scope = []
if allowed_project_ids:
placeholders = ', '.join(f':pm_project_{i}' for i in range(len(allowed_project_ids)))
scope.append(f"qc.project_id IN ({placeholders})")
params.update({f'pm_project_{i}': pid for i, pid in enumerate(allowed_project_ids)})
if allowed_location_names:
placeholders = ', '.join(f':pm_location_{i}' for i in range(len(allowed_location_names)))
scope.append(f"ad.location_name IN ({placeholders})")
params.update({f'pm_location_{i}': loc for i, loc in enumerate(allowed_location_names)})
conditions.append('(' + ' OR '.join(scope) + ')')
result = db.session.execute(text(f"""
SELECT DISTINCT ad.location_name
FROM attendance_data ad
LEFT JOIN qr_codes qc ON ad.qr_code_id = qc.id
WHERE {' AND '.join(conditions)}
ORDER BY ad.location_name
"""), params)
locations = [row[0] for row in result.fetchall()]
logger_handler.logger.info(
@@ -930,15 +953,35 @@ def search_employees_api():
search_pattern = f"%{search_query}%"
# Project Managers may only search within their own projects (§4). A PM
# scoped by locations is resolved to the projects those locations belong
# to, so their report filter still works without exposing other projects.
is_pm, allowed_project_ids, allowed_location_names = load_project_manager_scope()
pm_project_ids = []
if is_pm:
pm_project_ids = list(allowed_project_ids)
if allowed_location_names:
location_projects = db.session.query(QRCode.project_id).filter(
QRCode.location.in_(allowed_location_names),
QRCode.project_id.isnot(None)
).distinct().all()
pm_project_ids.extend(row[0] for row in location_projects)
pm_project_ids = sorted(set(pm_project_ids))
if not pm_project_ids:
return jsonify({'employees': []})
# 1. Registered employees — search by ID or name
employees = Employee.query.filter(
employee_query = Employee.query.filter(
db.or_(
Employee.id.like(search_pattern),
Employee.firstName.like(search_pattern),
Employee.lastName.like(search_pattern),
db.func.concat(Employee.firstName, ' ', Employee.lastName).like(search_pattern)
)
).limit(10).all()
)
if is_pm:
employee_query = employee_query.filter(Employee.contractId.in_(pm_project_ids))
employees = employee_query.limit(10).all()
employee_list = [{
'id': emp.id,
@@ -955,17 +998,25 @@ def search_employees_api():
if len(employee_list) < 10:
remaining_slots = 10 - len(employee_list)
try:
unregistered_conditions = ["e.id IS NULL", "ad.employee_id LIKE :pattern"]
unregistered_params = {'pattern': search_pattern, 'lim': remaining_slots}
if is_pm:
placeholders = ', '.join(f':pm_project_{i}' for i in range(len(pm_project_ids)))
unregistered_conditions.append(f"qc.project_id IN ({placeholders})")
unregistered_params.update(
{f'pm_project_{i}': pid for i, pid in enumerate(pm_project_ids)})
unregistered_rows = db.session.execute(
text("""
text(f"""
SELECT DISTINCT ad.employee_id
FROM attendance_data ad
LEFT JOIN employee e ON CAST(ad.employee_id AS UNSIGNED) = e.id
WHERE e.id IS NULL
AND ad.employee_id LIKE :pattern
LEFT JOIN qr_codes qc ON ad.qr_code_id = qc.id
WHERE {' AND '.join(unregistered_conditions)}
ORDER BY ad.employee_id
LIMIT :lim
"""),
{'pattern': search_pattern, 'lim': remaining_slots}
unregistered_params
).fetchall()
for row in unregistered_rows:
@@ -999,7 +1050,16 @@ def get_project_locations_api():
if not project_id:
return jsonify({'success': False, 'locations': [], 'error': 'Project ID required'})
# Project Managers may only ask about their own projects (§4)
is_pm, allowed_project_ids, _ = load_project_manager_scope()
if is_pm and int(project_id) not in allowed_project_ids:
logger_handler.logger.warning(
f"Project Manager {session.get('username')} requested locations for "
f"project {project_id}, which is not assigned to them"
)
return jsonify({'success': True, 'locations': []})
# Get active QR codes for this project
qr_codes = QRCode.query.filter_by(
project_id=int(project_id),