06/08 Add Inspector filter in Reports page

This commit is contained in:
2026-06-08 09:43:52 -04:00
parent 0ef0a4c388
commit 26d9901d6a
2 changed files with 43 additions and 7 deletions
+30 -7
View File
@@ -56,10 +56,14 @@ def index():
customer_facility_ids = get_customer_scope(current_user) # None = unrestricted
is_inspector = current_user.role == 'inspector'
# Pre-compute the set of inspection IDs conducted by this inspector.
# Used in _scope_issue to avoid adding a join to queries that already
# have their own joins (e.g. issue_severity, issue_status group-by queries).
inspector_inspection_ids = []
# Inspector filter — admin / director / project_manager only
inspector_filter = None
if current_user.role in ('admin', 'director', 'project_manager'):
inspector_filter = request.args.get('inspector_id', type=int) or None
# Pre-compute inspection ID sets used by _scope_issue to avoid join conflicts.
inspector_inspection_ids = [] # own inspections (inspector role)
filter_inspection_ids = None # filtered inspector's inspections (admin/dir/PM)
if is_inspector:
inspector_inspection_ids = [
row[0] for row in
@@ -67,10 +71,19 @@ def index():
.filter(Inspection.inspector_id == current_user.id)
.all()
]
elif inspector_filter:
filter_inspection_ids = [
row[0] for row in
db.session.query(Inspection.id)
.filter(Inspection.inspector_id == inspector_filter)
.all()
]
def _scope_insp(q):
if is_inspector:
return q.filter(Inspection.inspector_id == current_user.id)
if inspector_filter:
q = q.filter(Inspection.inspector_id == inspector_filter)
if customer_facility_ids is not None:
if not customer_facility_ids:
return q.filter(False)
@@ -79,12 +92,13 @@ def index():
def _scope_issue(q):
if is_inspector:
# Scope to issues flagged during this inspector's own inspections.
# Uses a pre-computed ID list (subquery) to avoid join conflicts
# with queries that already carry their own joins/group-by clauses.
if not inspector_inspection_ids:
return q.filter(False)
return q.filter(Issue.inspection_id.in_(inspector_inspection_ids))
if filter_inspection_ids is not None:
if not filter_inspection_ids:
return q.filter(False)
return q.filter(Issue.inspection_id.in_(filter_inspection_ids))
if customer_facility_ids is not None:
if not customer_facility_ids:
return q.filter(False)
@@ -128,6 +142,8 @@ def index():
Inspection.status == 'completed',
Inspection.overall_score.isnot(None),
)
if inspector_filter:
fac_score_q = fac_score_q.filter(Inspection.inspector_id == inspector_filter)
if customer_facility_ids is not None:
fac_score_q = fac_score_q.filter(
Facility.id.in_(customer_facility_ids) if customer_facility_ids else False
@@ -193,6 +209,11 @@ def index():
Issue.reported_at <= end,
)).order_by(Issue.reported_at.desc()).limit(10).all()
inspectors = []
if current_user.role in ('admin', 'director', 'project_manager'):
inspectors = User.query.filter_by(role='inspector', active=True)\
.order_by(User.full_name, User.username).all()
return render_template('reports/index.html',
start=start, end=end,
total_inspections=total_inspections,
@@ -206,6 +227,8 @@ def index():
top_inspectors=[{'username': r.username, 'count': r.count, 'avg_score': round(float(r.avg_score), 2) if r.avg_score else None} for r in top_inspectors],
critical_issues=critical_issues,
is_inspector=is_inspector,
inspectors=inspectors,
inspector_filter=inspector_filter,
)
+13
View File
@@ -39,6 +39,19 @@
<input type="date" name="end" class="form-control form-control-sm"
value="{{ end.strftime('%Y-%m-%d') }}">
</div>
{% if inspectors %}
<div class="col-md-3">
<label class="form-label small mb-1">Inspector</label>
<select name="inspector_id" class="form-select form-select-sm">
<option value="">All Inspectors</option>
{% for u in inspectors %}
<option value="{{ u.id }}" {% if inspector_filter == u.id %}selected{% endif %}>
{{ u.display_name }}
</option>
{% endfor %}
</select>
</div>
{% endif %}
<div class="col-auto">
<button class="btn btn-sm btn-primary">Apply</button>
<a href="{{ url_for('reports.index') }}" class="btn btn-sm btn-outline-secondary">Reset</a>