feat(cantaloupe_sync): add dex_report_date, deployed, pulled_date column handling

- Add heuristic entries: dex_report_date, deployed, pulled_date
- Include in COMPARE_FIELDS for diff detection
- Add to approve_batch() UPDATE field_map and INSERT statement
- Add v4 DB migration for three new TEXT columns
- Datetime serialization already handled by parse_excel()

Kanban: t_3bef3c9c
This commit is contained in:
Leo
2026-05-23 17:30:09 -04:00
parent 4070214fe7
commit f8fad7ac14
2 changed files with 19 additions and 3 deletions
+6 -1
View File
@@ -330,9 +330,14 @@ def init_db(conn: sqlite3.Connection):
conn.execute("ALTER TABLE assets ADD COLUMN longitude REAL DEFAULT NULL") conn.execute("ALTER TABLE assets ADD COLUMN longitude REAL DEFAULT NULL")
if "geofence_radius_meters" not in asset_cols: if "geofence_radius_meters" not in asset_cols:
conn.execute("ALTER TABLE assets ADD COLUMN geofence_radius_meters INTEGER DEFAULT 50") conn.execute("ALTER TABLE assets ADD COLUMN geofence_radius_meters INTEGER DEFAULT 50")
# v5 migration: dex_report_date + install_date # v4 migration: dex_report_date, deployed, pulled_date
if "dex_report_date" not in asset_cols: if "dex_report_date" not in asset_cols:
conn.execute("ALTER TABLE assets ADD COLUMN dex_report_date TEXT DEFAULT NULL") conn.execute("ALTER TABLE assets ADD COLUMN dex_report_date TEXT DEFAULT NULL")
if "deployed" not in asset_cols:
conn.execute("ALTER TABLE assets ADD COLUMN deployed TEXT DEFAULT NULL")
if "pulled_date" not in asset_cols:
conn.execute("ALTER TABLE assets ADD COLUMN pulled_date TEXT DEFAULT NULL")
# v5 migration: install_date
if "install_date" not in asset_cols: if "install_date" not in asset_cols:
conn.execute("ALTER TABLE assets ADD COLUMN install_date TEXT DEFAULT NULL") conn.execute("ALTER TABLE assets ADD COLUMN install_date TEXT DEFAULT NULL")
cursor = conn.execute("PRAGMA table_info(locations)") cursor = conn.execute("PRAGMA table_info(locations)")
+13 -2
View File
@@ -119,6 +119,9 @@ COLUMN_HEURISTICS = [
(["geofence radius", "geofence_radius", "geo radius"], "geofence_radius_meters"), (["geofence radius", "geofence_radius", "geo radius"], "geofence_radius_meters"),
(["gps lat", "lat"], "latitude"), (["gps lat", "lat"], "latitude"),
(["gps lng", "gps long", "long", "lng", "lon"], "longitude"), (["gps lng", "gps long", "long", "lng", "lon"], "longitude"),
(["last dex report time", "dex report time", "last dex", "dex report", "dex time"], "dex_report_date"),
(["deployed"], "deployed"),
(["pulled date", "pulled", "removal date"], "pulled_date"),
# Single-word/generic heuristics (last, after specific multi-word ones) # Single-word/generic heuristics (last, after specific multi-word ones)
(["serial", "s/n"], "serial_number"), (["serial", "s/n"], "serial_number"),
(["category", "type", "asset type", "equipment type", "class"], "category"), (["category", "type", "asset type", "equipment type", "class"], "category"),
@@ -305,6 +308,7 @@ def compute_diff(imported_rows: list[dict], live_data: dict) -> dict:
"floor", "room", "trailer_number", "walking_directions", "map_link", "floor", "room", "trailer_number", "walking_directions", "map_link",
"parking_location", "photo_path", "latitude", "longitude", "parking_location", "photo_path", "latitude", "longitude",
"geofence_radius_meters", "geofence_radius_meters",
"dex_report_date", "deployed", "pulled_date",
] ]
for row in imported_rows: for row in imported_rows:
@@ -680,6 +684,9 @@ def approve_batch(batch_id: int, request: Request):
"map_link": "map_link", "map_link": "map_link",
"parking_location": "parking_location", "parking_location": "parking_location",
"photo_path": "photo_path", "photo_path": "photo_path",
"dex_report_date": "dex_report_date",
"deployed": "deployed",
"pulled_date": "pulled_date",
} }
for import_key, db_col in field_map.items(): for import_key, db_col in field_map.items():
val = item.get(import_key) val = item.get(import_key)
@@ -740,8 +747,9 @@ def approve_batch(batch_id: int, request: Request):
floor, room, trailer_number, walking_directions, map_link, floor, room, trailer_number, walking_directions, map_link,
parking_location, photo_path, parking_location, photo_path,
customer_id, location_id, is_disney, customer_id, location_id, is_disney,
latitude, longitude, geofence_radius_meters) latitude, longitude, geofence_radius_meters,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", dex_report_date, deployed, pulled_date)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
( (
machine_id, machine_id,
str(item.get("serial_number", "")).strip() or "", str(item.get("serial_number", "")).strip() or "",
@@ -767,6 +775,9 @@ def approve_batch(batch_id: int, request: Request):
_safe_float(item.get("latitude")), _safe_float(item.get("latitude")),
_safe_float(item.get("longitude")), _safe_float(item.get("longitude")),
_safe_int(item.get("geofence_radius_meters"), 50), _safe_int(item.get("geofence_radius_meters"), 50),
str(item.get("dex_report_date", "")).strip() or "",
str(item.get("deployed", "")).strip() or "",
str(item.get("pulled_date", "")).strip() or "",
), ),
) )