Charge all batteries across sub-components from parent device
This commit is contained in:
@@ -1139,7 +1139,15 @@ 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
|
||||
installed = [b for b in device.batteries if b.status == "installed"]
|
||||
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")
|
||||
return redirect(url_for("device_detail", device_id=device_id))
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user