Aug 6 - Add external inspector role
This commit is contained in:
+1
-1
@@ -344,7 +344,7 @@ def edit_user(user_id):
|
||||
@admin_required
|
||||
def assign_inspector_contracts(user_id):
|
||||
user = db.session.get(User, user_id)
|
||||
if user is None or user.role != 'inspector':
|
||||
if user is None or not user.is_inspector:
|
||||
abort(404)
|
||||
|
||||
from app.models.project import Project
|
||||
|
||||
@@ -22,10 +22,12 @@ logger = logging.getLogger(__name__)
|
||||
bp = Blueprint('broadcast', __name__, url_prefix='/admin/broadcast')
|
||||
|
||||
# All roles that can hold an active iOS session
|
||||
BROADCAST_ROLES = ['inspector', 'project_manager', 'director', 'admin']
|
||||
BROADCAST_ROLES = ['inspector', 'external_inspector', 'project_manager',
|
||||
'director', 'admin']
|
||||
|
||||
ROLE_LABELS = {
|
||||
'inspector': 'Inspectors',
|
||||
'inspector': 'Inspectors',
|
||||
'external_inspector': 'External Inspectors',
|
||||
'project_manager': 'Project Managers',
|
||||
'director': 'Directors',
|
||||
'admin': 'Admins',
|
||||
|
||||
@@ -37,7 +37,7 @@ def index():
|
||||
# Start of the current week (Monday 00:00) for the "Submitted This Week" card.
|
||||
week_start = today_start - timedelta(days=today_start.weekday())
|
||||
|
||||
is_inspector = current_user.role == 'inspector'
|
||||
is_inspector = current_user.is_inspector
|
||||
is_privileged = current_user.role in ['admin', 'director']
|
||||
is_customer = current_user.role == 'customer'
|
||||
is_project_manager = current_user.role == 'project_manager'
|
||||
@@ -336,7 +336,7 @@ def index():
|
||||
if is_privileged or is_project_manager or is_auditor:
|
||||
active_inspectors = (
|
||||
User.query
|
||||
.filter_by(role='inspector', active=True)
|
||||
.filter(User.role.in_(User.INSPECTOR_ROLES), User.active == True)
|
||||
.order_by(User.full_name, User.username)
|
||||
.all()
|
||||
)
|
||||
@@ -354,7 +354,11 @@ def index():
|
||||
.all()
|
||||
)
|
||||
inspector_activity = sorted(
|
||||
[{'name': u.display_name, 'count': today_counts.get(u.id, 0)}
|
||||
[{'name': u.display_name,
|
||||
'count': today_counts.get(u.id, 0),
|
||||
# phase49 — flags customer / third-party inspectors so the table
|
||||
# can badge them; internal and external are listed together.
|
||||
'external': u.is_external_inspector}
|
||||
for u in active_inspectors],
|
||||
key=lambda x: (-x['count'], x['name']),
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ def list_facilities():
|
||||
facilities = Facility.query.filter(
|
||||
Facility.id.in_(cids), Facility.active == True
|
||||
).order_by(Facility.name).all()
|
||||
elif current_user.role == 'inspector':
|
||||
elif current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user) or []
|
||||
facilities = Facility.query.filter(
|
||||
Facility.id.in_(fids), Facility.active == True
|
||||
@@ -210,7 +210,7 @@ def facility_qr_print_all():
|
||||
assigned facilities; managers see all active facilities.
|
||||
"""
|
||||
# QR management is not an inspector task.
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
abort(403)
|
||||
|
||||
contract_id = request.args.get('contract_id', type=int)
|
||||
@@ -279,7 +279,7 @@ def facility_qr_export_pdf():
|
||||
Scope is enforced per-id via the same helpers as the QR pages, so a
|
||||
customer can never export a code outside their assigned facilities.
|
||||
"""
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
abort(403)
|
||||
|
||||
facility_ids = request.form.getlist('facility_ids', type=int)
|
||||
|
||||
+25
-19
@@ -215,7 +215,7 @@ def index():
|
||||
joinedload(Inspection.area),
|
||||
).order_by(Inspection.inspection_date.desc())
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
if not fids:
|
||||
q = q.filter(False)
|
||||
@@ -284,12 +284,12 @@ def index():
|
||||
q = q.filter(Inspection.overall_score <= float(score_max_filter))
|
||||
except ValueError:
|
||||
score_max_filter = ''
|
||||
if inspector_filter.isdigit() and current_user.role != 'inspector':
|
||||
if inspector_filter.isdigit() and not current_user.is_inspector:
|
||||
q = q.filter(Inspection.inspector_id == int(inspector_filter))
|
||||
|
||||
inspections = q.paginate(page=page, per_page=20, error_out=False)
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user) or []
|
||||
_fq = Facility.query.filter(Facility.id.in_(fids), Facility.active == True)
|
||||
elif current_user.role == 'customer':
|
||||
@@ -316,9 +316,9 @@ def index():
|
||||
projects = Project.query.filter_by(active=True).order_by(Project.name).all()
|
||||
|
||||
# Inspector dropdown — shown to all roles except inspector (they only see their own)
|
||||
if current_user.role != 'inspector':
|
||||
if not current_user.is_inspector:
|
||||
inspectors = (User.query
|
||||
.filter(User.role == 'inspector', User.active == True)
|
||||
.filter(User.role.in_(User.INSPECTOR_ROLES), User.active == True)
|
||||
.order_by(User.full_name, User.username).all())
|
||||
else:
|
||||
inspectors = []
|
||||
@@ -352,7 +352,7 @@ def start():
|
||||
projects = Project.query.filter_by(active=True).order_by(Project.name).all()
|
||||
|
||||
# Scope projects to inspector's assigned contracts
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
from app.models.inspector_assignment import InspectorAssignment
|
||||
assigned_pids = {
|
||||
a.project_id for a in
|
||||
@@ -408,7 +408,7 @@ def start():
|
||||
|
||||
# Inspector facility scope check — prevent crafted POST from selecting
|
||||
# a facility outside their assigned contracts.
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
if not fids or form.facility_id.data not in fids:
|
||||
abort(403)
|
||||
@@ -472,7 +472,7 @@ def execute(inspection_id):
|
||||
if inspection is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('inspections.index'))
|
||||
|
||||
@@ -609,7 +609,8 @@ def execute(inspection_id):
|
||||
return redirect(url_for('inspections.execute', inspection_id=inspection_id))
|
||||
|
||||
staff_for_flag_issue = User.query.filter(
|
||||
User.role.in_(['director', 'inspector', 'project_manager', 'auditor']),
|
||||
User.role.in_(['director', 'inspector', 'external_inspector',
|
||||
'project_manager', 'auditor']),
|
||||
User.active == True,
|
||||
).order_by(User.full_name, User.username).all()
|
||||
|
||||
@@ -649,7 +650,7 @@ def save_draft_ajax(inspection_id):
|
||||
if inspection is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
return jsonify({'ok': False, 'error': 'Access denied'}), 403
|
||||
|
||||
if inspection.status == 'completed':
|
||||
@@ -688,7 +689,7 @@ def upload_photo_ajax(inspection_id):
|
||||
if inspection is None:
|
||||
return jsonify({'ok': False, 'error': 'Not found'}), 404
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
return jsonify({'ok': False, 'error': 'Access denied'}), 403
|
||||
|
||||
if inspection.status == 'completed':
|
||||
@@ -715,7 +716,7 @@ def view(inspection_id):
|
||||
if inspection is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('inspections.index'))
|
||||
if current_user.role == 'customer':
|
||||
@@ -929,15 +930,20 @@ def flag_issue(inspection_id):
|
||||
if inspection is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('inspections.index'))
|
||||
|
||||
form = IssueForm()
|
||||
staff = User.query.filter(User.role.in_(['director', 'inspector'])).order_by(User.username).all()
|
||||
staff = User.query.filter(
|
||||
User.role.in_(['director', 'inspector', 'external_inspector'])
|
||||
).order_by(User.username).all()
|
||||
|
||||
form.facility_id.choices = [(inspection.facility_id, inspection.facility.name)]
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [(u.id, u.username) for u in staff]
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [
|
||||
(u.id, u.username + (' (External)' if u.is_external_inspector else ''))
|
||||
for u in staff
|
||||
]
|
||||
|
||||
if form.validate_on_submit():
|
||||
photo_path = _save_photo(form.photo.data, subfolder='issue_photos')
|
||||
@@ -1019,7 +1025,7 @@ def export_list_pdf():
|
||||
joinedload(Inspection.area),
|
||||
).order_by(Inspection.inspection_date.desc())
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
if not fids:
|
||||
q = q.filter(False)
|
||||
@@ -1082,7 +1088,7 @@ def export_list_pdf():
|
||||
q = q.filter(Inspection.overall_score <= float(score_max_filter))
|
||||
except ValueError:
|
||||
pass
|
||||
if inspector_filter.isdigit() and current_user.role != 'inspector':
|
||||
if inspector_filter.isdigit() and not current_user.is_inspector:
|
||||
q = q.filter(Inspection.inspector_id == int(inspector_filter))
|
||||
|
||||
inspections = q.all()
|
||||
@@ -1112,7 +1118,7 @@ def export_list_pdf():
|
||||
filter_parts.append(f'Min score: {score_min_filter}%')
|
||||
if score_max_filter:
|
||||
filter_parts.append(f'Max score: {score_max_filter}%')
|
||||
if inspector_filter.isdigit() and current_user.role != 'inspector':
|
||||
if inspector_filter.isdigit() and not current_user.is_inspector:
|
||||
u = db.session.get(User, int(inspector_filter))
|
||||
if u:
|
||||
filter_parts.append(f'Inspector: {u.display_name}')
|
||||
@@ -1142,7 +1148,7 @@ def export_pdf(inspection_id):
|
||||
if inspection is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector' and inspection.inspector_id != current_user.id:
|
||||
if current_user.is_inspector and inspection.inspector_id != current_user.id:
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('inspections.index'))
|
||||
if current_user.role == 'customer':
|
||||
|
||||
+28
-10
@@ -83,6 +83,19 @@ class _SLAFilteredPage:
|
||||
return iter([1])
|
||||
|
||||
|
||||
|
||||
def _assignee_label(user):
|
||||
"""Dropdown label for an assignee.
|
||||
|
||||
phase49 — external (customer / third-party) inspectors are assignable just
|
||||
like our own crew, but are suffixed so whoever is triaging can see at a
|
||||
glance that the work is going outside the company. Display only; the
|
||||
stored value is still the user id.
|
||||
"""
|
||||
return (f'{user.display_name} (External)'
|
||||
if user.is_external_inspector else user.display_name)
|
||||
|
||||
|
||||
@bp.route('/export-list-pdf')
|
||||
@login_required
|
||||
def export_list_pdf():
|
||||
@@ -98,7 +111,7 @@ def export_list_pdf():
|
||||
.order_by(Issue.reported_at.desc())
|
||||
)
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
if not fids:
|
||||
q = q.filter(False)
|
||||
@@ -229,7 +242,7 @@ def index():
|
||||
.order_by(Issue.reported_at.desc())
|
||||
)
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
if not fids:
|
||||
q = q.filter(False)
|
||||
@@ -330,7 +343,7 @@ def index():
|
||||
|
||||
# Facilities for the filter dropdown — scoped for inspectors/customers,
|
||||
# then narrowed to the selected contract when contract_filter is active.
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user) or []
|
||||
_fq = Facility.query.filter(Facility.id.in_(fids), Facility.active == True)
|
||||
elif current_user.role == 'customer':
|
||||
@@ -358,7 +371,8 @@ def index():
|
||||
|
||||
# Staff for quick-assign dropdown — same roles as the full issue form
|
||||
staff = User.query.filter(
|
||||
User.role.in_(['director', 'inspector', 'auditor']), User.active == True
|
||||
User.role.in_(['director', 'inspector', 'external_inspector', 'auditor']),
|
||||
User.active == True
|
||||
).order_by(User.username).all()
|
||||
|
||||
# Reporters dropdown — users who have actually filed at least one issue
|
||||
@@ -396,7 +410,7 @@ def view(issue_id):
|
||||
if issue is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
facility = issue.resolved_facility
|
||||
if not fids or not facility or facility.id not in fids:
|
||||
@@ -433,7 +447,7 @@ def view(issue_id):
|
||||
return redirect(url_for('issues.view', issue_id=issue_id))
|
||||
|
||||
form = IssueUpdateForm(obj=issue)
|
||||
staff = User.query.filter(User.role.in_(['director', 'inspector', 'auditor'])).order_by(User.username).all()
|
||||
staff = User.query.filter(User.role.in_(['director', 'inspector', 'external_inspector', 'auditor'])).order_by(User.username).all()
|
||||
# Preserve any pre-existing assignee who is no longer in the assignable set
|
||||
# (e.g. an admin assigned before admins were removed from the dropdown) so
|
||||
# saving the form doesn't silently unassign them.
|
||||
@@ -441,7 +455,9 @@ def view(issue_id):
|
||||
current_assignee = db.session.get(User, issue.assigned_to)
|
||||
if current_assignee:
|
||||
staff.append(current_assignee)
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [(u.id, u.display_name) for u in staff]
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [
|
||||
(u.id, _assignee_label(u)) for u in staff
|
||||
]
|
||||
form.status.data = form.status.data or issue.status
|
||||
|
||||
if form.validate_on_submit():
|
||||
@@ -760,10 +776,12 @@ def create():
|
||||
else:
|
||||
facilities = Facility.query.filter_by(active=True).order_by(Facility.name).all()
|
||||
projects = Project.query.filter_by(active=True).order_by(Project.name).all()
|
||||
staff = User.query.filter(User.role.in_(['director', 'inspector', 'auditor'])).order_by(User.username).all()
|
||||
staff = User.query.filter(User.role.in_(['director', 'inspector', 'external_inspector', 'auditor'])).order_by(User.username).all()
|
||||
|
||||
form.facility_id.choices = [(f.id, f.name) for f in facilities]
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [(u.id, u.display_name) for u in staff]
|
||||
form.assigned_to.choices = [(0, '— Unassigned —')] + [
|
||||
(u.id, _assignee_label(u)) for u in staff
|
||||
]
|
||||
|
||||
# On POST validation error: identify which contract the submitted facility
|
||||
# belongs to so the contract selector can be restored on re-render.
|
||||
@@ -1142,7 +1160,7 @@ def export_pdf(issue_id):
|
||||
if issue is None:
|
||||
abort(404)
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
fids = get_inspector_scope(current_user)
|
||||
facility = issue.resolved_facility
|
||||
if not fids or not facility or facility.id not in fids:
|
||||
|
||||
+24
-12
@@ -57,7 +57,8 @@ def index():
|
||||
# Inspectors get a scoped view of their own inspections and related issues.
|
||||
# Customers get a facility-scoped view.
|
||||
# Internal management roles (director+) get the full unscoped view.
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector', 'customer']:
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector',
|
||||
'external_inspector', 'customer']:
|
||||
from flask import flash, redirect, url_for
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('dashboard.index'))
|
||||
@@ -66,7 +67,7 @@ def index():
|
||||
|
||||
# Resolve scoping for customers (facility list) and inspectors (inspector_id)
|
||||
customer_facility_ids = get_customer_scope(current_user) # None = unrestricted
|
||||
is_inspector = current_user.role == 'inspector'
|
||||
is_inspector = current_user.is_inspector
|
||||
|
||||
# Inspector filter — admin / director / project_manager only
|
||||
inspector_filter = None
|
||||
@@ -262,7 +263,8 @@ def index():
|
||||
|
||||
inspectors = []
|
||||
if current_user.role in ('admin', 'director', 'project_manager'):
|
||||
inspectors = User.query.filter_by(role='inspector', active=True)\
|
||||
inspectors = User.query.filter(User.role.in_(User.INSPECTOR_ROLES),
|
||||
User.active == True)\
|
||||
.order_by(User.full_name, User.username).all()
|
||||
|
||||
facility_scores_list = [{
|
||||
@@ -307,7 +309,8 @@ def index():
|
||||
@bp.route('/facility/<int:facility_id>')
|
||||
@login_required
|
||||
def facility_report(facility_id):
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector', 'customer']:
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector',
|
||||
'external_inspector', 'customer']:
|
||||
from flask import flash, redirect, url_for
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('dashboard.index'))
|
||||
@@ -320,7 +323,7 @@ def facility_report(facility_id):
|
||||
from flask import flash, redirect, url_for
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('reports.index'))
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
# Inspectors may only view the facility report for facilities where
|
||||
# they have personally conducted at least one inspection.
|
||||
has_access = Inspection.query.filter_by(
|
||||
@@ -369,7 +372,8 @@ def facility_report(facility_id):
|
||||
def facility_scorecard(facility_id):
|
||||
"""Comprehensive per-facility scorecard: score trend, SLA compliance,
|
||||
issue breakdown by severity, inspection frequency."""
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector', 'customer']:
|
||||
if current_user.role not in ['admin', 'director', 'project_manager', 'inspector',
|
||||
'external_inspector', 'customer']:
|
||||
from flask import flash, redirect, url_for
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('dashboard.index'))
|
||||
@@ -385,7 +389,7 @@ def facility_scorecard(facility_id):
|
||||
flash('Access denied.', 'danger')
|
||||
return redirect(url_for('reports.index'))
|
||||
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
has_access = Inspection.query.filter_by(
|
||||
facility_id=facility_id,
|
||||
inspector_id=current_user.id,
|
||||
@@ -701,7 +705,8 @@ def _build_inspector_stats(start, end):
|
||||
all_ids = set(total_map.keys())
|
||||
active_inspectors = (
|
||||
User.query
|
||||
.filter(User.id.in_(all_ids), User.active == True, User.role == 'inspector')
|
||||
.filter(User.id.in_(all_ids), User.active == True,
|
||||
User.role.in_(User.INSPECTOR_ROLES))
|
||||
.order_by(User.full_name, User.username)
|
||||
.all()
|
||||
) if all_ids else []
|
||||
@@ -717,6 +722,10 @@ def _build_inspector_stats(start, end):
|
||||
inspector_stats.append({
|
||||
'id': u.id,
|
||||
'display_name': u.display_name,
|
||||
# phase49 — customer / third-party inspectors appear in the same
|
||||
# table as our own crew, badged so the numbers can be read in
|
||||
# context. Consumed by the HTML table and the Excel export.
|
||||
'external': u.is_external_inspector,
|
||||
'total': tot,
|
||||
'completed': comp,
|
||||
'completion_rate': round(comp / tot * 100) if tot else 0,
|
||||
@@ -759,7 +768,7 @@ def inspector_performance():
|
||||
|
||||
if selected_id:
|
||||
selected_inspector = db.session.get(User, selected_id)
|
||||
if selected_inspector and selected_inspector.role == 'inspector':
|
||||
if selected_inspector and selected_inspector.is_inspector:
|
||||
selected_kpis = next((s for s in inspector_stats if s['id'] == selected_id), None)
|
||||
|
||||
trend_rows = db.session.query(
|
||||
@@ -857,7 +866,7 @@ def export_inspector_performance():
|
||||
.filter(
|
||||
Inspection.inspection_date >= start,
|
||||
Inspection.inspection_date <= end,
|
||||
User.role == 'inspector',
|
||||
User.role.in_(User.INSPECTOR_ROLES),
|
||||
)
|
||||
if selected_id:
|
||||
detail_q = detail_q.filter(Inspection.inspector_id == selected_id)
|
||||
@@ -931,7 +940,10 @@ def export_inspector_performance():
|
||||
for row_idx, s in enumerate(inspector_stats, start=3):
|
||||
stripe = sub_fill if row_idx % 2 == 0 else None
|
||||
row_data = [
|
||||
s['display_name'],
|
||||
# phase49 — external inspectors share this table with our own crew;
|
||||
# suffixed rather than given a column so the index-based styling
|
||||
# below (score = col 5, vs_avg = col 6, …) stays correct.
|
||||
s['display_name'] + (' (External)' if s.get('external') else ''),
|
||||
s['total'],
|
||||
s['completed'],
|
||||
s['completion_rate'],
|
||||
@@ -1616,7 +1628,7 @@ def facility_summary_pdf(facility_id):
|
||||
cids = get_customer_scope(current_user) or []
|
||||
if facility_id not in cids:
|
||||
abort(403)
|
||||
elif current_user.role == 'inspector':
|
||||
elif current_user.is_inspector:
|
||||
has = Inspection.query.filter_by(facility_id=facility_id,
|
||||
inspector_id=current_user.id).first()
|
||||
if not has:
|
||||
|
||||
@@ -82,7 +82,8 @@ def _populate_choices(form):
|
||||
facilities = Facility.query.filter_by(active=True).order_by(Facility.name).all()
|
||||
templates = (InspectionTemplate.query
|
||||
.filter_by(active=True).order_by(InspectionTemplate.name).all())
|
||||
inspectors = (User.query.filter_by(role='inspector', active=True)
|
||||
inspectors = (User.query.filter(User.role.in_(User.INSPECTOR_ROLES),
|
||||
User.active == True)
|
||||
.order_by(User.username).all())
|
||||
form.facility_id.choices = [(f.id, f.name) for f in facilities]
|
||||
form.template_id.choices = [(t.id, t.name) for t in templates]
|
||||
@@ -236,7 +237,7 @@ def index():
|
||||
base = ScheduledInspection.query
|
||||
|
||||
# Inspectors see only their own assignments; managers see everything.
|
||||
if current_user.role == 'inspector':
|
||||
if current_user.is_inspector:
|
||||
base = base.filter(ScheduledInspection.inspector_id == current_user.id)
|
||||
|
||||
pending_count = base.filter(ScheduledInspection.active.is_(True)).count()
|
||||
|
||||
Reference in New Issue
Block a user