Aug 3 - Update scheduled task acknowledged

This commit is contained in:
2026-08-03 12:51:01 -04:00
parent 6513e6b4f6
commit 38acb6a52e
8 changed files with 182 additions and 4 deletions
+59
View File
@@ -80,6 +80,28 @@ def _notify_assignee(sched, reassigned=False):
)
def _notify_creator_acknowledged(sched):
"""Notify the schedule's creator that the assigned inspector has confirmed
receipt of the request. No-op when there is no creator, the creator is
inactive, or the creator IS the inspector (self-assigned). Caller commits."""
creator = sched.creator
if not creator or not creator.active or creator.id == sched.inspector_id:
return
fac = sched.facility.name if sched.facility else ''
tpl = sched.template.name if sched.template else ''
who = sched.inspector.display_name if sched.inspector else 'The inspector'
notify(
recipient = creator,
title = f'Inspector confirmed receipt — {fac}',
body = (f'{who} confirmed receipt of the "{tpl}" scheduled '
f'inspection at {fac} ({sched.frequency_label.lower()}), '
f'due {sched.next_due_date:%b %d, %Y}.'),
link = url_for('scheduled_inspections.index'),
event_type = EVENT_SCHEDULED_INSPECTION,
send_email = True,
)
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
@@ -260,6 +282,10 @@ def edit(schedule_id):
sched.inspector_id = form.inspector_id.data
sched.notes = (form.notes.data or '').strip() or None
sched.active = form.active.data
# Reassigning to a different inspector invalidates any prior confirmation
# — the new assignee has not yet acknowledged the request (phase47).
if sched.inspector_id != old_inspector_id:
sched.acknowledged_at = None
_apply_recurrence(sched, form)
if _reject_if_past_end_date(sched, form):
# sched is a persistent object and has already been mutated — discard
@@ -374,6 +400,39 @@ def start(schedule_id):
return redirect(url_for('inspections.execute', inspection_id=inspection.id))
# ── Acknowledge (inspector confirms receipt of the request) ───────────────────
@bp.route('/<int:schedule_id>/acknowledge', methods=['POST'])
@login_required
def acknowledge(schedule_id):
"""The assigned inspector confirms they have received the scheduled request.
Assignee-only (like Start): a manager cannot confirm on someone's behalf.
Idempotent — confirming an already-confirmed schedule is a no-op. On the
first confirmation the schedule's creator is notified."""
sched = db.session.get(ScheduledInspection, schedule_id)
if sched is None:
abort(404)
if not sched.inspector_id or sched.inspector_id != current_user.id:
abort(403)
if sched.acknowledged_at is None:
sched.acknowledged_at = now_eastern()
db.session.commit()
log_action(ACTION_UPDATE, 'ScheduledInspection', sched.id,
f'{sched.template.name if sched.template else "?"} @ '
f'{sched.facility.name if sched.facility else "?"}',
'inspector confirmed receipt')
logger.info('SCHED INSP | acknowledge | schedule=%s | by=%s',
sched.id, current_user.username)
_notify_creator_acknowledged(sched)
db.session.commit()
flash('You have confirmed receipt of this scheduled inspection.', 'success')
else:
flash('You have already confirmed this scheduled inspection.', 'info')
return redirect(url_for('scheduled_inspections.index'))
# ── Cron: reminders (advance / due / overdue) ─────────────────────────────────
@bp.route('/run', methods=['POST'])