From 3cee604abfe7b0baecabb412722c2d923f2a1652 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Wed, 8 Jul 2026 15:51:18 -0400 Subject: [PATCH] Jul 8 - Update scheduled inspection 2 --- app/routes/scheduled_inspections.py | 31 ++++++++- app/templates/scheduled_inspections/form.html | 68 ++++++++++++++++++- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/app/routes/scheduled_inspections.py b/app/routes/scheduled_inspections.py index 606c1c9..ee89c1f 100644 --- a/app/routes/scheduled_inspections.py +++ b/app/routes/scheduled_inspections.py @@ -23,6 +23,7 @@ from app import db from app.models.scheduled_inspection import ScheduledInspection from app.models.facility import Facility from app.models.inspection import Inspection, InspectionTemplate +from app.models.project import Project from app.models.user import User from app.utils.forms import ScheduledInspectionForm from app.utils.decorators import project_manager_required @@ -37,6 +38,9 @@ bp = Blueprint('scheduled_inspections', __name__, url_prefix='/scheduled-inspect def _populate_choices(form): + # facility_id choices are ALL active facilities so POST validation passes + # regardless of which contract the UI-only contract selector had chosen + # (CLAUDE.md rule 61). The contract selector narrows the list client-side. facilities = Facility.query.filter_by(active=True).order_by(Facility.name).all() templates = (InspectionTemplate.query .filter_by(active=True).order_by(InspectionTemplate.name).all()) @@ -47,6 +51,20 @@ def _populate_choices(form): form.inspector_id.choices = [(u.id, u.display_name) for u in inspectors] +def _active_contracts(): + return Project.query.filter_by(active=True).order_by(Project.name).all() + + +def _selected_project_id(form): + """Contract of the submitted facility (for restoring the selector on + re-render), or None.""" + if form.facility_id.data: + fac = db.session.get(Facility, form.facility_id.data) + if fac: + return fac.project_id + return None + + # ── List ────────────────────────────────────────────────────────────────────── @bp.route('/') @@ -103,7 +121,9 @@ def create(): return redirect(url_for('scheduled_inspections.index')) return render_template('scheduled_inspections/form.html', - form=form, title='New Scheduled Inspection') + form=form, title='New Scheduled Inspection', + projects=_active_contracts(), + selected_project_id=_selected_project_id(form)) # ── Edit ────────────────────────────────────────────────────────────────────── @@ -133,8 +153,15 @@ def edit(schedule_id): flash('Scheduled inspection updated.', 'success') return redirect(url_for('scheduled_inspections.index')) + # Restore the contract selector: submitted facility's contract on error, + # otherwise the schedule's current facility's contract. + sel_pid = _selected_project_id(form) + if sel_pid is None and sched.facility: + sel_pid = sched.facility.project_id return render_template('scheduled_inspections/form.html', - form=form, title='Edit Scheduled Inspection', schedule=sched) + form=form, title='Edit Scheduled Inspection', schedule=sched, + projects=_active_contracts(), + selected_project_id=sel_pid) # ── Delete ──────────────────────────────────────────────────────────────────── diff --git a/app/templates/scheduled_inspections/form.html b/app/templates/scheduled_inspections/form.html index dd7ac5d..410e35d 100644 --- a/app/templates/scheduled_inspections/form.html +++ b/app/templates/scheduled_inspections/form.html @@ -10,9 +10,21 @@
{{ form.hidden_tag() }} + {# Contract selector — UI only; narrows the facility list via AJAX #} +
+ + +
+ + {# Facility — populated by JS once a contract is chosen #}
{{ form.facility_id.label(class="form-label fw-semibold") }} - {{ form.facility_id(class="form-select") }} + {{ form.facility_id(class="form-select", id="facility_id") }} {% for e in form.facility_id.errors %}
{{ e }}
{% endfor %}
@@ -65,3 +77,57 @@ {% endblock %} + +{% block extra_js %} + +{% endblock %}