fix(portal): fallback to existing Date fields when stage Datetime is null
Records created before Task 16 (per-stage Datetime fields + write
snapshot hook) have NULL for received_at/shipped_at/etc. SQL backfill
copies received_date -> received_at; this commit adds a runtime
fallback so if any record slips through (manual edits, future
imports) the timeline still surfaces what's available.
Also render date-only ('May 16, 2026') when the timestamp has no
time component, so backfilled-from-Date records don't show the
misleading 'may 16 · 12:00a' fake time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -155,10 +155,25 @@ class FpCustomerPortal(CustomerPortal):
|
|||||||
else:
|
else:
|
||||||
status = 'pending'
|
status = 'pending'
|
||||||
ts = job[ts_field] if hasattr(job, ts_field) else None
|
ts = job[ts_field] if hasattr(job, ts_field) else None
|
||||||
|
# Belt-and-suspenders fallback to existing Date fields for records
|
||||||
|
# that pre-date the Datetime columns (Task 16). SQL backfill copies
|
||||||
|
# received_date -> received_at, but if that's bypassed somehow
|
||||||
|
# we still surface what data we have.
|
||||||
|
if not ts and status in ('done', 'active'):
|
||||||
|
if ts_field == 'received_at' and job.received_date:
|
||||||
|
ts = job.received_date
|
||||||
|
elif ts_field == 'shipped_at' and job.actual_ship_date:
|
||||||
|
ts = job.actual_ship_date
|
||||||
time_label = ''
|
time_label = ''
|
||||||
if ts and status in ('done', 'active'):
|
if ts and status in ('done', 'active'):
|
||||||
# "Mar 14 · 8:00a" — lowercase am/pm + truncated to single letter.
|
# If the timestamp has no time component (likely backfilled
|
||||||
|
# from a Date field), render date-only. Otherwise render
|
||||||
|
# "May 14 · 8:00a" with lowercase am/pm truncated to single letter.
|
||||||
|
has_time = hasattr(ts, 'hour') and (ts.hour or ts.minute or getattr(ts, 'second', 0))
|
||||||
|
if has_time:
|
||||||
time_label = ts.strftime('%b %d · %-I:%M%p').lower().replace('am', 'a').replace('pm', 'p')
|
time_label = ts.strftime('%b %d · %-I:%M%p').lower().replace('am', 'a').replace('pm', 'p')
|
||||||
|
else:
|
||||||
|
time_label = ts.strftime('%b %d, %Y')
|
||||||
elif status == 'pending' and label == 'Shipped' and job.target_ship_date:
|
elif status == 'pending' and label == 'Shipped' and job.target_ship_date:
|
||||||
time_label = 'est. ' + job.target_ship_date.strftime('%b %d')
|
time_label = 'est. ' + job.target_ship_date.strftime('%b %d')
|
||||||
out.append({
|
out.append({
|
||||||
|
|||||||
Reference in New Issue
Block a user