{% extends "base.html" %} {% block title %}{{ title }}{% endblock %} {# Laid out to match the single-tenant scheduled-inspection form: one narrow card, Contract → Facility cascade at the top, then what/who, then when. MT keeps three fields ST does not have — the schedule NAME (required by inspection_schedules.name), the AREA (a schedule may target one area) and the auto/plan MODE. They are placed next to the field they qualify rather than in a block of their own. #} {# ── Sticky values ──────────────────────────────────────────────────────── This form is hand-built (no WTForms), so a re-render after a validation error would otherwise come back blank and the user would retype everything. On POST every field reads back from request.form; otherwise from the saved schedule (edit) or its default (create). ST gets this free from WTForms — this is the equivalent. #} {% set posted = request.form if request.method == 'POST' else None %} {% set v_name = posted.get('name') if posted else (schedule.name if schedule else '') %} {% set v_facility = (posted.get('facility_id')|int(0)) if posted else (schedule.facility_id if schedule else 0) %} {% set v_area = (posted.get('area_id')|int(0)) if posted else (schedule.area_id if schedule and schedule.area_id else 0) %} {% set v_template = (posted.get('template_id')|int(0)) if posted else (schedule.template_id if schedule else 0) %} {% set v_inspector = (posted.get('inspector_id')|int(0)) if posted else (schedule.inspector_id if schedule else 0) %} {% set v_frequency = posted.get('frequency') if posted else (schedule.frequency if schedule else 'weekly') %} {% set v_due = posted.get('next_due_date') if posted else (schedule.due_date.isoformat() if schedule and schedule.due_date else '') %} {% set v_end = posted.get('end_date') if posted else (schedule.end_date.isoformat() if schedule and schedule.end_date else '') %} {% set v_mode = posted.get('mode') if posted else (schedule.mode if schedule else 'auto') %} {% set v_notes = posted.get('notes') if posted else (schedule.notes if schedule and schedule.notes else '') %} {% set v_month_mode = posted.get('month_mode') if posted else (schedule.month_mode if schedule else 'day_of_month') %} {% set v_dom = posted.get('day_of_month') if posted else (schedule.day_of_month if schedule and schedule.day_of_month else '') %} {% set v_nth_week = (posted.get('nth_week')|int(0)) if posted else (schedule.nth_week if schedule and schedule.nth_week else 0) %} {% set v_nth_weekday = (posted.get('nth_weekday')|int(-1)) if posted else (schedule.nth_weekday if schedule and schedule.nth_weekday is not none else -1) %} {% set v_weekdays = (posted.getlist('weekdays')|map('int')|list) if posted else (schedule.weekday_list if schedule else []) %} {% set v_active = (posted.get('active') is not none) if posted else (schedule.active if schedule else True) %} {% block content %}
Recurring schedules automatically roll their due date forward each time the
inspection is completed. The assigned inspector is reminded the day before
and on the due date; managers are alerted if it becomes overdue.
{% if schedule %}
Current {{ 'due date' if schedule.mode == 'plan' else 'run' }}:
{{ schedule.next_run_at.strftime('%Y-%m-%d %H:%M') if schedule.next_run_at else '—' }}
{% if schedule.last_completed_at %}
· last completed {{ schedule.last_completed_at.strftime('%Y-%m-%d %H:%M') }}
{% endif %}
{% if schedule.end_date %}· ends {{ schedule.end_date.strftime('%Y-%m-%d') }}{% endif %}.
Reminders for this occurrence are only reset if the due date actually moves,
so renaming or re-noting a schedule will not re-send them.
{% endif %}