Jul 26 - Update scheduled inspection settings (weekly/monthly)
This commit is contained in:
@@ -22,7 +22,8 @@ from flask import (Blueprint, render_template, redirect, url_for, flash,
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
from app import db
|
||||
from app.models.scheduled_inspection import ScheduledInspection
|
||||
from app.models.scheduled_inspection import (ScheduledInspection,
|
||||
MONTH_MODE_DAY, MONTH_MODE_NTH)
|
||||
from app.models.facility import Facility
|
||||
from app.models.inspection import Inspection, InspectionTemplate
|
||||
from app.models.project import Project
|
||||
@@ -79,6 +80,50 @@ def _notify_assignee(sched, reassigned=False):
|
||||
)
|
||||
|
||||
|
||||
def _apply_recurrence(sched, form):
|
||||
"""Copy the recurrence block for the chosen frequency onto *sched* and
|
||||
clear the blocks that no longer apply, then snap next_due_date onto the
|
||||
rule. Keeping the unused columns NULL means `recurrence_label` and the
|
||||
date math never read stale settings after a frequency change."""
|
||||
sched.frequency = form.frequency.data
|
||||
|
||||
if sched.frequency == 'weekly':
|
||||
sched.set_weekdays(form.weekdays.data)
|
||||
else:
|
||||
sched.weekdays = None
|
||||
|
||||
if sched.frequency == 'monthly':
|
||||
sched.month_mode = form.month_mode.data or MONTH_MODE_DAY
|
||||
if sched.month_mode == MONTH_MODE_NTH:
|
||||
sched.day_of_month = None
|
||||
sched.nth_week = form.nth_week.data
|
||||
sched.nth_weekday = form.nth_weekday.data
|
||||
else:
|
||||
sched.day_of_month = form.day_of_month.data
|
||||
sched.nth_week = None
|
||||
sched.nth_weekday = None
|
||||
else:
|
||||
sched.month_mode = sched.day_of_month = None
|
||||
sched.nth_week = sched.nth_weekday = None
|
||||
|
||||
# Snap the picked date forward onto the first matching occurrence.
|
||||
sched.next_due_date = sched.align_due_date(form.next_due_date.data)
|
||||
|
||||
|
||||
def _open_inspection_ids(schedules):
|
||||
"""{schedule_id: inspection_id} for schedules with an inspection already
|
||||
in progress, so the UI offers Continue instead of a duplicate Start."""
|
||||
ids = [s.id for s in schedules if s.id]
|
||||
if not ids:
|
||||
return {}
|
||||
rows = (Inspection.query
|
||||
.filter(Inspection.scheduled_inspection_id.in_(ids),
|
||||
Inspection.status == 'in_progress')
|
||||
.order_by(Inspection.id.desc())
|
||||
.all())
|
||||
return {r.scheduled_inspection_id: r.id for r in rows}
|
||||
|
||||
|
||||
def _selected_project_id(form):
|
||||
"""Contract of the submitted facility (for restoring the selector on
|
||||
re-render), or None."""
|
||||
@@ -110,7 +155,8 @@ def index():
|
||||
).all()
|
||||
|
||||
return render_template('scheduled_inspections/list.html',
|
||||
schedules=schedules, today=today)
|
||||
schedules=schedules, today=today,
|
||||
open_inspections=_open_inspection_ids(schedules))
|
||||
|
||||
|
||||
# ── Create ──────────────────────────────────────────────────────────────────
|
||||
@@ -129,17 +175,18 @@ def create():
|
||||
facility_id = form.facility_id.data,
|
||||
template_id = form.template_id.data,
|
||||
inspector_id = form.inspector_id.data,
|
||||
frequency = form.frequency.data,
|
||||
next_due_date = form.next_due_date.data,
|
||||
notes = (form.notes.data or '').strip() or None,
|
||||
active = form.active.data,
|
||||
created_by = current_user.id,
|
||||
)
|
||||
_apply_recurrence(sched, form)
|
||||
db.session.add(sched)
|
||||
db.session.commit()
|
||||
log_action(ACTION_CREATE, 'ScheduledInspection', sched.id,
|
||||
f'{sched.template.name} @ {sched.facility.name}',
|
||||
f'freq={sched.frequency}; due={sched.next_due_date}; inspector={sched.inspector_id}')
|
||||
f'freq={sched.recurrence_label}; due={sched.next_due_date}; '
|
||||
f'inspector={sched.inspector_id}')
|
||||
logger.info('SCHED INSP | create | by=%s | id=%s', current_user.username, sched.id)
|
||||
|
||||
# Notify the assigned inspector immediately.
|
||||
@@ -166,20 +213,25 @@ def edit(schedule_id):
|
||||
abort(404)
|
||||
form = ScheduledInspectionForm(obj=sched)
|
||||
_populate_choices(form)
|
||||
if request.method == 'GET':
|
||||
# obj= copies the raw CSV column into a multi-select field; hand it the
|
||||
# parsed int list instead so the checkboxes pre-tick correctly.
|
||||
form.weekdays.data = sched.weekday_list
|
||||
form.month_mode.data = sched.month_mode or MONTH_MODE_DAY
|
||||
|
||||
if form.validate_on_submit():
|
||||
old_inspector_id = sched.inspector_id
|
||||
sched.facility_id = form.facility_id.data
|
||||
sched.template_id = form.template_id.data
|
||||
sched.inspector_id = form.inspector_id.data
|
||||
sched.frequency = form.frequency.data
|
||||
sched.next_due_date = form.next_due_date.data
|
||||
sched.notes = (form.notes.data or '').strip() or None
|
||||
sched.active = form.active.data
|
||||
_apply_recurrence(sched, form)
|
||||
db.session.commit()
|
||||
log_action(ACTION_UPDATE, 'ScheduledInspection', sched.id,
|
||||
f'{sched.template.name} @ {sched.facility.name}',
|
||||
f'freq={sched.frequency}; due={sched.next_due_date}; active={sched.active}')
|
||||
f'freq={sched.recurrence_label}; due={sched.next_due_date}; '
|
||||
f'active={sched.active}')
|
||||
|
||||
# Notify the inspector if the assignment changed to them.
|
||||
if sched.active and sched.inspector_id and sched.inspector_id != old_inspector_id:
|
||||
@@ -242,6 +294,16 @@ def start(schedule_id):
|
||||
flash('The template for this schedule has no form fields yet.', 'warning')
|
||||
return redirect(url_for('scheduled_inspections.index'))
|
||||
|
||||
# Already started but not submitted? Resume it rather than opening a second
|
||||
# inspection against the same occurrence.
|
||||
existing = (Inspection.query
|
||||
.filter_by(scheduled_inspection_id=sched.id, status='in_progress')
|
||||
.order_by(Inspection.id.desc())
|
||||
.first())
|
||||
if existing is not None:
|
||||
flash('Resuming the inspection you already started for this schedule.', 'info')
|
||||
return redirect(url_for('inspections.execute', inspection_id=existing.id))
|
||||
|
||||
inspection = Inspection(
|
||||
template_id = sched.template_id,
|
||||
facility_id = sched.facility_id,
|
||||
|
||||
Reference in New Issue
Block a user