Charge all batteries across sub-components from parent device

This commit is contained in:
2026-06-09 21:42:08 -05:00
parent 27ed4c9420
commit ab1340998e
3 changed files with 64 additions and 3 deletions
+8
View File
@@ -1139,6 +1139,14 @@ def create_app(config_object="config"):
return redirect(url_for("device_detail", device_id=device_id))
increment = 1 if request.form.get("increment_cycles") else 0
notes = request.form.get("notes", "").strip() or None
if device.has_children():
installed = [
b
for child in device.children
for b in child.batteries
if b.status == "installed"
]
else:
installed = [b for b in device.batteries if b.status == "installed"]
if not installed:
flash("No installed batteries to log.", "warning")
+26
View File
@@ -232,6 +232,32 @@
</div>
{% endif %}
{% if device.has_children() and flat_installed %}
<div class="card">
<h2>Charge All Installed Batteries</h2>
<form method="post" action="{{ url_for('device_charge_all', device_id=device.id) }}"
style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:flex-end;">
<div class="form-group" style="margin:0;flex:1;min-width:140px;">
<label>Date</label>
<input type="date" name="charged_date" required>
</div>
<div class="form-group" style="margin:0;align-self:flex-end;padding-bottom:1rem;">
<label style="display:flex;align-items:center;gap:0.4rem;font-weight:normal;cursor:pointer;">
<input type="checkbox" name="increment_cycles" value="1" checked>
Increment charge cycles
</label>
</div>
<div class="form-group" style="margin:0;flex:2;min-width:160px;">
<label>Notes (optional)</label>
<input type="text" name="notes" placeholder="e.g. overnight charge">
</div>
<div style="padding-bottom:1rem;">
<button class="btn btn-primary" type="submit">Log Charge for All</button>
</div>
</form>
</div>
{% endif %}
{% if not device.has_children() %}
<div class="card">
<h2>Install Batteries</h2>
+29 -2
View File
@@ -1066,5 +1066,32 @@ def test_parent_battery_summary_flat(client):
# Both child names linked in the component column
assert b"Sensor A" in resp.data
assert b"Sensor B" in resp.data
# Only one "Installed Batteries" heading
assert resp.data.count(b"Installed Batteries") == 1
# Flat table heading appears once (not duplicated per sub-component)
assert resp.data.count(b"<h2>Installed Batteries</h2>") == 1
def test_device_charge_all_parent(client):
_setup_parent_with_two_children(client)
client.post("/battery/add", data={"brand": "Eneloop", "label": "E001", "size": "AA"})
client.post("/battery/add", data={"brand": "Eneloop", "label": "E002", "size": "AA"})
client.post("/device/2/install-one", data={"battery_id": "1"})
client.post("/device/3/install-one", data={"battery_id": "2"})
resp = client.post(
"/device/1/charge-all",
data={"charged_date": "2025-06-01", "increment_cycles": "1"},
follow_redirects=True,
)
assert resp.status_code == 200
assert b"Logged charge for 2 batteri" in resp.data
assert b"+cycles" in resp.data
def test_device_charge_all_parent_no_installed(client):
_setup_parent_with_two_children(client)
resp = client.post(
"/device/1/charge-all",
data={"charged_date": "2025-06-01"},
follow_redirects=True,
)
assert resp.status_code == 200
assert b"No installed batteries" in resp.data