Jul 8 - Update scheduled inspection 2
This commit is contained in:
@@ -23,6 +23,7 @@ from app import db
|
|||||||
from app.models.scheduled_inspection import ScheduledInspection
|
from app.models.scheduled_inspection import ScheduledInspection
|
||||||
from app.models.facility import Facility
|
from app.models.facility import Facility
|
||||||
from app.models.inspection import Inspection, InspectionTemplate
|
from app.models.inspection import Inspection, InspectionTemplate
|
||||||
|
from app.models.project import Project
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.utils.forms import ScheduledInspectionForm
|
from app.utils.forms import ScheduledInspectionForm
|
||||||
from app.utils.decorators import project_manager_required
|
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):
|
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()
|
facilities = Facility.query.filter_by(active=True).order_by(Facility.name).all()
|
||||||
templates = (InspectionTemplate.query
|
templates = (InspectionTemplate.query
|
||||||
.filter_by(active=True).order_by(InspectionTemplate.name).all())
|
.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]
|
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 ──────────────────────────────────────────────────────────────────────
|
# ── List ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@bp.route('/')
|
@bp.route('/')
|
||||||
@@ -103,7 +121,9 @@ def create():
|
|||||||
return redirect(url_for('scheduled_inspections.index'))
|
return redirect(url_for('scheduled_inspections.index'))
|
||||||
|
|
||||||
return render_template('scheduled_inspections/form.html',
|
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 ──────────────────────────────────────────────────────────────────────
|
# ── Edit ──────────────────────────────────────────────────────────────────────
|
||||||
@@ -133,8 +153,15 @@ def edit(schedule_id):
|
|||||||
flash('Scheduled inspection updated.', 'success')
|
flash('Scheduled inspection updated.', 'success')
|
||||||
return redirect(url_for('scheduled_inspections.index'))
|
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',
|
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 ────────────────────────────────────────────────────────────────────
|
# ── Delete ────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -10,9 +10,21 @@
|
|||||||
<form method="POST" novalidate>
|
<form method="POST" novalidate>
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
|
{# Contract selector — UI only; narrows the facility list via AJAX #}
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold" for="contract_select">Contract</label>
|
||||||
|
<select id="contract_select" class="form-select">
|
||||||
|
<option value="">— Select Contract —</option>
|
||||||
|
{% for p in projects %}
|
||||||
|
<option value="{{ p.id }}">{{ p.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Facility — populated by JS once a contract is chosen #}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
{{ form.facility_id.label(class="form-label fw-semibold") }}
|
{{ 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 %}<div class="text-danger small">{{ e }}</div>{% endfor %}
|
{% for e in form.facility_id.errors %}<div class="text-danger small">{{ e }}</div>{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -65,3 +77,57 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_js %}
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
var contractSel = document.getElementById('contract_select');
|
||||||
|
var facilitySel = document.getElementById('facility_id');
|
||||||
|
if (!contractSel || !facilitySel) { return; }
|
||||||
|
|
||||||
|
var FACILITIES_URL = '{{ url_for("inspections.facilities_for_project", project_id=0) }}'.replace('/0', '/');
|
||||||
|
var preProjectId = {{ selected_project_id | tojson }};
|
||||||
|
var preFacilityId = {{ form.facility_id.data | tojson }};
|
||||||
|
|
||||||
|
function setPlaceholder() {
|
||||||
|
facilitySel.innerHTML = '<option value="">— Select a Contract first —</option>';
|
||||||
|
facilitySel.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFacilities(projectId, restoreFacilityId) {
|
||||||
|
facilitySel.disabled = true;
|
||||||
|
facilitySel.innerHTML = '<option value="">Loading…</option>';
|
||||||
|
fetch(FACILITIES_URL + projectId)
|
||||||
|
.then(function (r) { return r.json(); })
|
||||||
|
.then(function (data) {
|
||||||
|
facilitySel.innerHTML = '<option value="">— Select Facility —</option>';
|
||||||
|
data.forEach(function (f) {
|
||||||
|
var opt = document.createElement('option');
|
||||||
|
opt.value = f.id;
|
||||||
|
opt.textContent = f.name;
|
||||||
|
if (restoreFacilityId && f.id === restoreFacilityId) { opt.selected = true; }
|
||||||
|
facilitySel.appendChild(opt);
|
||||||
|
});
|
||||||
|
facilitySel.disabled = false;
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
facilitySel.innerHTML = '<option value="">Could not load facilities</option>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
contractSel.addEventListener('change', function () {
|
||||||
|
if (this.value) { loadFacilities(this.value, null); }
|
||||||
|
else { setPlaceholder(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial state: restore the contract + facility on edit / validation error.
|
||||||
|
if (preProjectId) {
|
||||||
|
contractSel.value = String(preProjectId);
|
||||||
|
loadFacilities(preProjectId, preFacilityId);
|
||||||
|
} else {
|
||||||
|
setPlaceholder();
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user