From a1d3f580811608c8155b0b2a66cf568316c1901e Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Mon, 7 Jul 2025 08:11:30 -0500 Subject: [PATCH] Enhance Room model and settings form: improve foreign key validation and handle potential duplicates in deletion logic --- models/rooms.py | 40 +++++++++++++++++++++++++++++----------- templates/settings.html | 6 +++--- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/models/rooms.py b/models/rooms.py index a14b0f0..3038e59 100644 --- a/models/rooms.py +++ b/models/rooms.py @@ -56,7 +56,6 @@ class Room(ValidatableMixin, db.Model): Supports add, update, and delete. """ def resolve_fk(key, fk_map, label): - # Print the fucking map so we can see what we're working with print(f"Resolving {label} ID: {key} using map: {fk_map}") if key is None: return None @@ -141,12 +140,27 @@ class Room(ValidatableMixin, db.Model): print(f"✅ No changes to room {room.id}") for existing_id in existing_ids - seen_ids: - room = existing_by_id[existing_id] + room = existing_by_id.get(existing_id) + if not room: + continue + + # Skip if a newly added room matches this one — likely duplicate + if any( + r["name"] == room.name and + resolve_fk(r["section_id"], section_map, "section") == room.area_id and + resolve_fk(r["function_id"], function_map, "function") == room.function_id + for r in submitted_clean + if r.get("id") is None or str(r.get("id")).startswith("room-") + ): + print(f"⚠️ Skipping deletion of likely duplicate: {room}") + continue + db.session.delete(room) - print(f"🗑️ Removing room: {room.name}") - + print(f"🗑️ Removing room: {room}") + @classmethod def validate_state(cls, submitted_items: list[dict]) -> list[str]: + print("VALIDATING") errors = [] for index, item in enumerate(submitted_items): @@ -171,11 +185,15 @@ class Room(ValidatableMixin, db.Model): # These fields are FK IDs, so we're just checking for valid formats here. for fk_field, fk_label in [("section_id", "Section"), ("function_id", "Function")]: fk_val = item.get(fk_field) - if fk_val is not None: - try: - _ = int(fk_val) - except (ValueError, TypeError): - if not isinstance(fk_val, str) or not fk_val.startswith("temp-"): - errors.append(f"{label} has invalid {fk_label} ID: {fk_val}") - + + if fk_val is None: + continue # Let the DB enforce nullability + + try: + _ = int(fk_val) + except (ValueError, TypeError): + fk_val_str = str(fk_val) + if not fk_val_str.startswith("temp-"): + errors.append(f"{label} has invalid {fk_label} ID: {fk_val}") + return errors diff --git a/templates/settings.html b/templates/settings.html index 4a350f0..c6c62d6 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -163,7 +163,7 @@ } function sanitizeFk(val) { - if (val && val !== "null" && val !== "") { + if (val && val !== "null" && val !== "" && val !== "None") { return /^\d+$/.test(val) ? parseInt(val, 10) : val; } return null; @@ -180,8 +180,8 @@ const result = { name, ...(id ? { id } : {}), - ...(sectionId ? { section_id: sectionId } : {}), - ...(functionId ? { function_id: functionId } : {}) + section_id: sectionId, + function_id: functionId }; return result;