Implement sync_from_state method for Area, Brand, Item, RoomFunction, and Room models; streamline entity management in settings

This commit is contained in:
Yaro Kasear 2025-06-24 13:09:41 -05:00
parent 87fa623cde
commit 8a5c5db9e0
11 changed files with 204 additions and 70 deletions

View file

@ -26,3 +26,33 @@ class Area(db.Model):
'id': self.id,
'name': self.name
}
@classmethod
def sync_from_state(cls, submitted_items: list[dict]):
"""
Syncs the Area table with the provided list of dictionaries.
Adds new areas and removes areas that are not in the list.
"""
submitted = {
str(item.get("name", "")).strip()
for item in submitted_items
if isinstance(item, dict) and str(item.get("name", "")).strip()
}
existing_query = db.session.query(cls)
existing = {area.name: area for area in existing_query.all()}
existing_names = set(existing.keys())
print(f"Existing areas: {existing_names}")
print(f"Submitted areas: {submitted}")
print(f"Areas to add: {submitted - existing_names}")
print(f"Areas to remove: {existing_names - submitted}")
for name in submitted - existing_names:
db.session.add(cls(name=name))
print(f" Adding area: {name}")
for name in existing_names - submitted:
db.session.delete(existing[name])
print(f"🗑️ Removing area: {name}")

View file

@ -25,4 +25,34 @@ class Brand(db.Model):
return {
'id': self.id,
'name': self.name
}
}
@classmethod
def sync_from_state(cls, submitted_items: list[dict]):
"""
Syncs the Brand table with the provided list of dictionaries.
Adds new brands and removes brands that are not in the list.
"""
submitted = {
str(item.get("name", "")).strip()
for item in submitted_items
if isinstance(item, dict) and str(item.get("name", "")).strip()
}
existing_query = db.session.query(cls)
existing = {brand.name: brand for brand in existing_query.all()}
existing_names = set(existing.keys())
print(f"Existing brands: {existing_names}")
print(f"Submitted brands: {submitted}")
print(f"Brands to add: {submitted - existing_names}")
print(f"Brands to remove: {existing_names - submitted}")
for name in submitted - existing_names:
db.session.add(cls(name=name))
print(f" Adding brand: {name}")
for name in existing_names - submitted:
db.session.delete(existing[name])
print(f"🗑️ Removing brand: {name}")

View file

@ -28,4 +28,34 @@ class Item(db.Model):
'id': self.id,
'name': self.description,
'category': self.category
}
}
@classmethod
def sync_from_state(cls, submitted_items: list[dict]):
"""
Syncs the Items table with the provided list of dictionaries.
Adds new items and removes items that are not in the list.
"""
submitted = {
str(item.get("name", "")).strip()
for item in submitted_items
if isinstance(item, dict) and str(item.get("name", "")).strip()
}
existing_query = db.session.query(cls)
existing = {item.description: item for item in existing_query.all()}
existing_descriptions = set(existing.keys())
print(f"Existing items: {existing_descriptions}")
print(f"Submitted items: {submitted}")
print(f"items to add: {submitted - existing_descriptions}")
print(f"items to remove: {existing_descriptions - submitted}")
for description in submitted - existing_descriptions:
db.session.add(cls(description=description))
print(f" Adding item: {description}")
for description in existing_descriptions - submitted:
db.session.delete(existing[description])
print(f"🗑️ Removing item: {description}")

View file

@ -25,4 +25,34 @@ class RoomFunction(db.Model):
return {
'id': self.id,
'name': self.description
}
}
@classmethod
def sync_from_state(cls, submitted_items: list[dict]):
"""
Syncs the functions table with the provided list of dictionaries.
Adds new functions and removes functions that are not in the list.
"""
submitted = {
str(item.get("name", "")).strip()
for item in submitted_items
if isinstance(item, dict) and str(item.get("name", "")).strip()
}
existing_query = db.session.query(cls)
existing = {item.description: item for item in existing_query.all()}
existing_descriptions = set(existing.keys())
print(f"Existing functions: {existing_descriptions}")
print(f"Submitted functions: {submitted}")
print(f"Functions to add: {submitted - existing_descriptions}")
print(f"Functions to remove: {existing_descriptions - submitted}")
for description in submitted - existing_descriptions:
db.session.add(cls(description=description))
print(f" Adding item: {description}")
for description in existing_descriptions - submitted:
db.session.delete(existing[description])
print(f"🗑️ Removing item: {description}")

View file

@ -45,3 +45,60 @@ class Room(db.Model):
'function_id': self.function_id
}
@classmethod
def sync_from_state(cls, submitted_rooms: list[dict], section_map: dict, function_map: dict, section_fallbacks: list, function_fallbacks: list):
"""
Syncs the Rooms table with the submitted room list.
Resolves foreign keys using section_map and function_map.
"""
def resolve_id(raw_id, fallback_list, id_map, label):
try:
resolved = int(raw_id)
if resolved >= 0:
if resolved in id_map.values():
return resolved
raise ValueError(f"ID {resolved} not found in {label}.")
except Exception:
pass
index = abs(resolved + 1)
try:
entry = fallback_list[index]
key = entry.get("name") if isinstance(entry, dict) else str(entry).strip()
final_id = id_map.get(key)
if final_id is None:
raise ValueError(f"ID for {key} not found in {label}.")
return final_id
except Exception as e:
raise ValueError(f"Failed to resolve {label} ID: {e}") from e
existing_query = db.session.query(cls)
existing = {room.name: room for room in existing_query.all()}
submitted = {
str(room.get("name", "")).strip(): room
for room in submitted_rooms
if isinstance(room, dict) and str(room.get("name", "")).strip()
}
existing_names = set(existing.keys())
submitted_names = set(submitted.keys())
print(f"Existing rooms: {existing_names}")
print(f"Submitted rooms: {submitted_names}")
print(f"Rooms to add: {submitted_names - existing_names}")
print(f"Rooms to remove: {existing_names - submitted_names}")
for name in submitted_names - existing_names:
room_data = submitted[name]
area_id = resolve_id(room_data.get("section_id", -1), section_fallbacks, section_map, "section") if room_data.get("section_id") is not None else None
function_id = resolve_id(room_data.get("function_id", -1), function_fallbacks, function_map, "function") if room_data.get("function_id") is not None else None
new_room = cls(name=name, area_id=area_id, function_id=function_id)
db.session.add(new_room)
print(f" Adding room: {new_room}")
for name in existing_names - submitted_names:
room_to_remove = existing[name]
db.session.delete(room_to_remove)
print(f"🗑️ Removing room: {room_to_remove}")