Scope device uniqueness per parent, null type/location for sub-components, hide sub-components from list, flat battery summary for parent devices
This commit is contained in:
@@ -650,7 +650,7 @@ def create_app(config_object="config"):
|
||||
|
||||
@app.route("/device/")
|
||||
def device_list():
|
||||
devices = db.query(Device).order_by(Device.name).all()
|
||||
devices = db.query(Device).filter(Device.parent_id == None).order_by(Device.name).all()
|
||||
device_types = sorted({d.device_type for d in devices if d.device_type})
|
||||
device_locations = sorted({d.location for d in devices if d.location})
|
||||
device_battery_sizes = sorted({d.battery_size for d in devices if d.battery_size})
|
||||
@@ -733,8 +733,11 @@ def create_app(config_object="config"):
|
||||
form_device_type=request.form.get("device_type", ""),
|
||||
prefill_parent=parent_device), 400
|
||||
|
||||
if db.query(Device).filter_by(name=name).first():
|
||||
flash(f"A device named '{name}' already exists.", "error")
|
||||
parent_key_val = parent_device.id if parent_device else -1
|
||||
if db.query(Device).filter(
|
||||
Device.parent_key == parent_key_val, Device.name == name
|
||||
).first():
|
||||
flash(f"A device named '{name}' already exists here.", "error")
|
||||
return render_template("device_add.html",
|
||||
device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
@@ -744,10 +747,13 @@ def create_app(config_object="config"):
|
||||
form_device_type=request.form.get("device_type", ""),
|
||||
prefill_parent=parent_device), 400
|
||||
|
||||
is_sub = parent_device is not None
|
||||
device = Device(name=name, battery_slots=slots, notes=notes,
|
||||
device_type=device_type, battery_size=battery_size,
|
||||
location=location,
|
||||
parent_id=parent_device.id if parent_device else None)
|
||||
device_type=None if is_sub else device_type,
|
||||
battery_size=battery_size,
|
||||
location=None if is_sub else location,
|
||||
parent_id=parent_device.id if parent_device else None,
|
||||
parent_key=parent_key_val)
|
||||
db.add(device)
|
||||
db.commit()
|
||||
flash(f"Device '{name}' added.", "success")
|
||||
@@ -758,9 +764,7 @@ def create_app(config_object="config"):
|
||||
return render_template("device_add.html", device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes,
|
||||
prefill_parent=prefill_parent,
|
||||
form_device_type=prefill_parent.device_type if prefill_parent else None,
|
||||
form_location=prefill_parent.location if prefill_parent else None)
|
||||
prefill_parent=prefill_parent)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Devices — detail
|
||||
@@ -804,6 +808,12 @@ def create_app(config_object="config"):
|
||||
changed = True
|
||||
if changed:
|
||||
db.commit()
|
||||
flat_installed = []
|
||||
if device.has_children():
|
||||
for child in device.children:
|
||||
for b in child.batteries:
|
||||
if b.status == "installed":
|
||||
flat_installed.append((b, child.name, child.id))
|
||||
return render_template("device_detail.html", device=device, brands=brands,
|
||||
available_batteries=available_batteries,
|
||||
device_types=device_types,
|
||||
@@ -812,7 +822,8 @@ def create_app(config_object="config"):
|
||||
device_list_all=all_devices,
|
||||
ha_enabled=ha_client.enabled,
|
||||
ha_live_pct=ha_live_pct,
|
||||
logbook_entries=device.logbook_entries)
|
||||
logbook_entries=device.logbook_entries,
|
||||
flat_installed=flat_installed)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Devices — edit
|
||||
@@ -840,13 +851,20 @@ def create_app(config_object="config"):
|
||||
except ValueError:
|
||||
flash("Battery slots must be a positive integer.", "error")
|
||||
return redirect(url_for("device_detail", device_id=device_id))
|
||||
existing = db.query(Device).filter_by(name=name).first()
|
||||
if existing and existing.id != device_id:
|
||||
flash(f"A device named '{name}' already exists.", "error")
|
||||
# Determine new parent key for scoped uniqueness check
|
||||
parent_id_raw = request.form.get("parent_id", "").strip()
|
||||
new_parent_key_val = int(parent_id_raw) if (parent_id_raw and parent_id_raw.isdigit()) else -1
|
||||
|
||||
existing = db.query(Device).filter(
|
||||
Device.parent_key == new_parent_key_val,
|
||||
Device.name == name,
|
||||
Device.id != device_id,
|
||||
).first()
|
||||
if existing:
|
||||
flash(f"A device named '{name}' already exists here.", "error")
|
||||
return redirect(url_for("device_detail", device_id=device_id))
|
||||
|
||||
# Validate parent_id change
|
||||
parent_id_raw = request.form.get("parent_id", "").strip()
|
||||
if parent_id_raw and parent_id_raw.isdigit():
|
||||
new_parent = db.get(Device, int(parent_id_raw))
|
||||
if not new_parent:
|
||||
@@ -866,12 +884,19 @@ def create_app(config_object="config"):
|
||||
)
|
||||
return redirect(url_for("device_detail", device_id=device_id))
|
||||
device.parent_id = new_parent.id
|
||||
device.parent_key = new_parent.id
|
||||
else:
|
||||
device.parent_id = None
|
||||
device.parent_key = -1
|
||||
|
||||
device.name = name
|
||||
device.notes = notes
|
||||
device.device_type = device_type
|
||||
if device.is_subcomponent():
|
||||
device.device_type = None
|
||||
device.location = None
|
||||
else:
|
||||
device.device_type = device_type
|
||||
device.location = request.form.get("location", "").strip() or None
|
||||
if device.has_children():
|
||||
device.battery_slots = 0
|
||||
device.battery_size = None
|
||||
@@ -880,7 +905,6 @@ def create_app(config_object="config"):
|
||||
new_battery_size = request.form.get("battery_size", "").strip() or None
|
||||
if new_battery_size is not None:
|
||||
device.battery_size = new_battery_size
|
||||
device.location = request.form.get("location", "").strip() or None
|
||||
device.ha_entity_id = request.form.get("ha_entity_id", "").strip() or None
|
||||
db.commit()
|
||||
flash("Device updated.", "success")
|
||||
@@ -1327,7 +1351,9 @@ def create_app(config_object="config"):
|
||||
if not name:
|
||||
devices_skipped += 1
|
||||
continue
|
||||
existing = db.query(Device).filter_by(name=name).first()
|
||||
existing = db.query(Device).filter(
|
||||
Device.parent_key == -1, Device.name == name
|
||||
).first()
|
||||
if existing:
|
||||
if old_id is not None:
|
||||
device_id_map[old_id] = existing.id
|
||||
@@ -1341,6 +1367,7 @@ def create_app(config_object="config"):
|
||||
location = d.get("location") or None,
|
||||
ha_entity_id = d.get("ha_entity_id") or None,
|
||||
notes = d.get("notes") or None,
|
||||
parent_key = -1,
|
||||
)
|
||||
db.add(new_dev)
|
||||
db.flush()
|
||||
|
||||
Reference in New Issue
Block a user