fix(api): map new Mitieng CSV columns in tracksolid_update_v2

Switches column references from the old title-case logistics CSV
(IMEI, Device Name, License Plate No., Telephone, Fuel/100km, ...) to
the snake_case Mitieng export shipped on 2026-04-27 (imei, device_name,
vehicle_number, driver_phone, fuel_100km, ...). Without this, the bulk
device-update API tool fails with KeyError: 'IMEI' on the new CSV.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
David Kiania 2026-04-27 23:42:20 +03:00
parent 0b45f8d0f7
commit 5418fc48c5

View file

@ -220,18 +220,18 @@ def clean(val) -> str | None:
def row_to_fields(row: pd.Series) -> dict: def row_to_fields(row: pd.Series) -> dict:
"""Map one CSV row to local field names used by update_vehicle().""" """Map one CSV row to local field names used by update_vehicle()."""
return { return {
"device_name": clean(row.get("Device Name")), "device_name": clean(row.get("device_name")),
"vehicle_name": clean(row.get("Vehicle Name")), "vehicle_name": clean(row.get("vehicle_name")),
"vehicle_icon": clean(row.get("Vehicle Icon")), "vehicle_icon": clean(row.get("vehicle_icon")),
"license_plate": clean(row.get("License Plate No.")), "license_plate": clean(row.get("vehicle_number")),
"vehicle_model": clean(row.get("Vehicle Model")), "vehicle_model": clean(row.get("vehicle_models")),
"driver_name": clean(row.get("Driver Name")), "driver_name": clean(row.get("driver_name")),
"driver_phone": clean(row.get("Telephone")), "driver_phone": clean(row.get("driver_phone")),
"sim": clean(row.get("SIM")), "sim": clean(row.get("sim")),
"vin": clean(row.get("VIN")), "vin": clean(row.get("vin")),
"engine_number": clean(row.get("Engine Number")), "engine_number": clean(row.get("engine_number")),
"fuel_per_100": clean(row.get("Fuel/100km")), "fuel_per_100": clean(row.get("fuel_100km")),
"remarks": clean(row.get("Remarks")), "remarks": clean(row.get("remarks")),
} }
@ -263,14 +263,14 @@ def main():
log.error("CSV file not found: %s", csv_file) log.error("CSV file not found: %s", csv_file)
sys.exit(1) sys.exit(1)
df = pd.read_csv(csv_file, dtype={"IMEI": str}) df = pd.read_csv(csv_file, dtype={"imei": str})
log.info("Loaded %d rows from %s", len(df), csv_file) log.info("Loaded %d rows from %s", len(df), csv_file)
if args.limit: if args.limit:
df = df.head(args.limit) df = df.head(args.limit)
log.info("Limiting to first %d rows.", args.limit) log.info("Limiting to first %d rows.", args.limit)
df = df[df["IMEI"].notna() & (df["IMEI"].str.strip() != "")] df = df[df["imei"].notna() & (df["imei"].str.strip() != "")]
log.info("%d rows have a valid IMEI.", len(df)) log.info("%d rows have a valid IMEI.", len(df))
if df.empty: if df.empty:
@ -295,7 +295,7 @@ def main():
skipped = 0 skipped = 0
for idx, row in df.iterrows(): for idx, row in df.iterrows():
imei = str(row["IMEI"]).strip() imei = str(row["imei"]).strip()
fields = row_to_fields(row) fields = row_to_fields(row)
# Skip rows where every updatable field is empty # Skip rows where every updatable field is empty