06/12 Add features: 1. Vendor/Contractor assignment 2. Period-over-period comparison 3. Trend Alerts (cron)

This commit is contained in:
2026-06-12 16:27:09 -04:00
parent cf22fe87fe
commit 0fe5954794
12 changed files with 447 additions and 2 deletions
+36 -1
View File
@@ -162,6 +162,35 @@ def index():
facility_scores = fac_score_q.group_by(Facility.id, Facility.name)\
.order_by(func.avg(Inspection.overall_score).desc()).all()
# Prior-period facility scores for period-over-period delta badges
period_len = end - start
prior_end = start
prior_start = start - period_len
prior_fac_q = db.session.query(
Facility.name,
func.avg(Inspection.overall_score).label('avg_score'),
).join(Inspection, Facility.id == Inspection.facility_id)\
.filter(
Inspection.inspection_date >= prior_start,
Inspection.inspection_date <= prior_end,
Inspection.status == 'completed',
Inspection.overall_score.isnot(None),
)
if inspector_filter:
prior_fac_q = prior_fac_q.filter(Inspection.inspector_id == inspector_filter)
if customer_facility_ids is not None:
prior_fac_q = prior_fac_q.filter(
Facility.id.in_(customer_facility_ids) if customer_facility_ids else False
)
prior_scores_raw = prior_fac_q.group_by(Facility.id, Facility.name).all()
prior_scores_map = {r.name: round(float(r.avg_score), 2) for r in prior_scores_raw}
# Build delta map keyed by facility name: positive = improved, negative = declined
facility_deltas = {}
for row in facility_scores:
prior = prior_scores_map.get(row.name)
if prior is not None:
facility_deltas[row.name] = round(float(row.avg_score) - prior, 1)
# Score trend — daily averages (line chart)
daily_q = db.session.query(
func.date(Inspection.inspection_date).label('day'),
@@ -226,13 +255,19 @@ def index():
inspectors = User.query.filter_by(role='inspector', active=True)\
.order_by(User.full_name, User.username).all()
facility_scores_list = [{'name': r.name, 'avg_score': round(float(r.avg_score), 2), 'count': r.count} for r in facility_scores]
# Attach prior avg and delta to each facility score dict for the template table
for row in facility_scores_list:
row['prior_avg'] = prior_scores_map.get(row['name'])
row['delta'] = facility_deltas.get(row['name'])
return render_template('reports/index.html',
start=start, end=end,
total_inspections=total_inspections,
completed=completed,
flagged=flagged,
avg_score=round(float(avg_score), 2) if avg_score else None,
facility_scores=[{'name': r.name, 'avg_score': round(float(r.avg_score), 2), 'count': r.count} for r in facility_scores],
facility_scores=facility_scores_list,
daily_scores=[{'day': str(r.day), 'avg': round(float(r.avg), 2), 'count': r.count} for r in daily_scores],
issue_severity=[{'severity': r.severity, 'count': r.count} for r in issue_severity],
issue_status=[{'status': r.status, 'count': r.count} for r in issue_status],