inventory/models/rooms.py

104 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Optional, TYPE_CHECKING, List
if TYPE_CHECKING:
from .areas import Area
from .room_functions import RoomFunction
from .inventory import Inventory
from .users import User
from sqlalchemy import ForeignKey, Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class Room(db.Model):
__tablename__ = 'Rooms'
id: Mapped[int] = mapped_column("ID", Integer, Identity(start=1, increment=1), primary_key=True)
name: Mapped[Optional[str]] = mapped_column("Room", Unicode(255), nullable=True)
area_id: Mapped[Optional[int]] = mapped_column("Area", Integer, ForeignKey("Areas.ID"))
function_id: Mapped[Optional[int]] = mapped_column("Function", Integer, ForeignKey("Room Functions.ID"))
area: Mapped[Optional['Area']] = relationship('Area', back_populates='rooms')
room_function: Mapped[Optional['RoomFunction']] = relationship('RoomFunction', back_populates='rooms')
inventory: Mapped[List['Inventory']] = relationship('Inventory', back_populates='location')
users: Mapped[List['User']] = relationship('User', back_populates='location')
def __init__(self, name: Optional[str] = None, area_id: Optional[int] = None, function_id: Optional[int] = None):
self.name = name
self.area_id = area_id
self.function_id = function_id
def __repr__(self):
return f"<Room(id={self.id}, room={repr(self.name)}, area_id={self.area_id}, function_id={self.function_id})>"
@property
def full_name(self):
name = self.name or ""
func = self.room_function.description if self.room_function else ""
return f"{name} - {func}".strip(" -")
def serialize(self):
return {
'id': self.id,
'name': self.name,
'area_id': self.area_id,
'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}")