diff --git a/server.py b/server.py index a88430c..d5044bb 100644 --- a/server.py +++ b/server.py @@ -1270,6 +1270,24 @@ def delete_asset(asset_id: int): conn.close() +@app.delete("/api/assets/{asset_id}/gps", status_code=204) +def clear_asset_gps(asset_id: int): + """Clear GPS coordinates from an asset (sets latitude/longitude to NULL).""" + conn = get_db() + existing = conn.execute("SELECT id, name FROM assets WHERE id = ?", (asset_id,)).fetchone() + if existing is None: + conn.close() + raise HTTPException(status_code=404, detail="Asset not found") + conn.execute( + "UPDATE assets SET latitude = NULL, longitude = NULL, updated_at = datetime('now') WHERE id = ?", + (asset_id,), + ) + _log_activity(conn, "updated", "asset", asset_id, + f"GPS data cleared for '{existing['name']}'") + conn.commit() + conn.close() + + # ─── Task 8: POST /api/checkins ───────────────────────────────────────────── diff --git a/static/index.html b/static/index.html index 508558d..813d5e9 100644 --- a/static/index.html +++ b/static/index.html @@ -1249,6 +1249,7 @@
+
@@ -3605,6 +3606,14 @@ navBtn.style.display = 'none'; } + // Clear GPS button — show when asset has GPS + const clearGpsBtn = document.getElementById('detailClearGpsBtn'); + if (a.latitude != null && a.longitude != null) { + clearGpsBtn.style.display = ''; + } else { + clearGpsBtn.style.display = 'none'; + } + // Keys + Badges const keys = a.keys || []; const badges = a.badges || (Array.isArray(a.badge_names) ? a.badge_names : []); @@ -3996,6 +4005,24 @@ } } + // ── Clear GPS ────────────────────────────────────────────────────────── + async function clearAssetGps() { + if (!AppState.currentAssetId) return; + const confirmed = await showModal( + 'Clear GPS Data', + 'Remove GPS coordinates from this asset?', + 'Clear GPS' + ); + if (!confirmed) return; + try { + await api('/api/assets/' + AppState.currentAssetId + '/gps', { method: 'DELETE' }); + showToast('GPS data cleared'); + viewAsset(AppState.currentAssetId); + } catch (e) { + showToast(e.message, true); + } + } + // ── Delete ──────────────────────────────────────────────────────────── async function deleteAsset() { if (!AppState.currentAssetId) return; diff --git a/tests/test_server.py b/tests/test_server.py index 262e933..1abedfd 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -432,6 +432,31 @@ class TestDeleteAsset: assert response.status_code == 404 +class TestClearAssetGps: + """Clear GPS endpoint.""" + + def test_clear_gps_returns_204(self, client): + """Clear GPS returns 204 and sets lat/lng to null.""" + r = client.post("/api/assets", json={ + "machine_id": "GPS001", "name": "Has GPS", + "latitude": 28.5, "longitude": -81.3 + }) + asset_id = r.json()["id"] + response = client.delete(f"/api/assets/{asset_id}/gps") + assert response.status_code == 204 + + # Verify lat/lng are cleared + r2 = client.get(f"/api/assets/{asset_id}") + assert r2.status_code == 200 + data = r2.json() + assert data["latitude"] is None + assert data["longitude"] is None + + def test_clear_gps_not_found_returns_404(self, client): + response = client.delete("/api/assets/99999/gps") + assert response.status_code == 404 + + # ─── Task 7: GET /api/assets/search?machine_id= ───────────────────────────