189 files
This commit is contained in:
@@ -82,6 +82,11 @@ class MaintenanceTask:
|
||||
# "m³", …). The value itself lives per completion in the history entry
|
||||
# (`reading_value`), so the unit is task-level config, not state.
|
||||
reading_unit: str | None = None
|
||||
# #161 phase 2: named reading slots [{id, name, unit}] — a task with
|
||||
# slots records `reading_values` (a per-slot snapshot) on each
|
||||
# completion instead of the single `reading_value` scalar. Shapes and
|
||||
# caps: helpers/reading_slots.py.
|
||||
readings: list[dict[str, Any]] = field(default_factory=list)
|
||||
|
||||
# --- Archive (v2.10.0) ---
|
||||
# archived_at is an ISO timestamp; None means active. When set, the task
|
||||
@@ -105,6 +110,10 @@ class MaintenanceTask:
|
||||
# --- History ---
|
||||
history: list[dict[str, Any]] = field(default_factory=list)
|
||||
|
||||
# #170: reference number within the object ("8.3" = object 8, task 3) —
|
||||
# assigned once by the coordinator's refresh, never reused.
|
||||
ref_no: int | None = None
|
||||
|
||||
# --- Runtime (not persisted) ---
|
||||
_trigger_active: bool = field(default=False, repr=False)
|
||||
_trigger_current_value: float | None = field(default=None, repr=False)
|
||||
@@ -353,8 +362,9 @@ class MaintenanceTask:
|
||||
checklist_state: dict[str, bool] | None = None,
|
||||
feedback: str | None = None,
|
||||
completed_by: str | None = None,
|
||||
photo_doc_id: str | None = None,
|
||||
photo_doc_ids: list[str] | None = None,
|
||||
reading_value: float | None = None,
|
||||
reading_values: list[dict[str, Any]] | None = None,
|
||||
used_parts: list[dict[str, Any]] | None = None,
|
||||
auto: bool = False,
|
||||
completed_at: datetime | None = None,
|
||||
@@ -429,8 +439,9 @@ class MaintenanceTask:
|
||||
checklist_state=checklist_state,
|
||||
feedback=feedback,
|
||||
completed_by=completed_by,
|
||||
photo_doc_id=photo_doc_id,
|
||||
photo_doc_ids=photo_doc_ids,
|
||||
reading_value=reading_value,
|
||||
reading_values=reading_values,
|
||||
used_parts=used_parts,
|
||||
auto=auto,
|
||||
timestamp=ts_iso,
|
||||
@@ -534,8 +545,9 @@ class MaintenanceTask:
|
||||
checklist_state: dict[str, bool] | None = None,
|
||||
feedback: str | None = None,
|
||||
completed_by: str | None = None,
|
||||
photo_doc_id: str | None = None,
|
||||
photo_doc_ids: list[str] | None = None,
|
||||
reading_value: float | None = None,
|
||||
reading_values: list[dict[str, Any]] | None = None,
|
||||
used_parts: list[dict[str, Any]] | None = None,
|
||||
auto: bool = False,
|
||||
timestamp: str | None = None,
|
||||
@@ -570,12 +582,19 @@ class MaintenanceTask:
|
||||
entry["feedback"] = feedback
|
||||
if completed_by is not None:
|
||||
entry["completed_by"] = completed_by
|
||||
if photo_doc_id is not None:
|
||||
entry["photo_doc_id"] = photo_doc_id
|
||||
# Completion photos (#161): a capped list of document ids. Entries
|
||||
# from before v2.75 carry a single `photo_doc_id` — readers accept
|
||||
# both via helpers.completion_photos.history_photo_ids.
|
||||
if photo_doc_ids:
|
||||
entry["photo_doc_ids"] = list(photo_doc_ids)
|
||||
# Meter readings (v2.20, #83): the recorded value rides on the
|
||||
# completion entry — the delta view derives from consecutive entries.
|
||||
if reading_value is not None:
|
||||
entry["reading_value"] = reading_value
|
||||
# #161 phase 2: per-slot snapshot [{id, name, unit, value}] — name and
|
||||
# unit copied so a later slot rename never rewrites old entries.
|
||||
if reading_values:
|
||||
entry["reading_values"] = [dict(v) for v in reading_values]
|
||||
if used_parts:
|
||||
# #99: the parts actually used on THIS completion ([{part_id,
|
||||
# name, quantity}]) — explicit per-completion consumption record.
|
||||
@@ -645,6 +664,8 @@ class MaintenanceTask:
|
||||
data["nfc_tag_id"] = self.nfc_tag_id
|
||||
if self.reading_unit is not None:
|
||||
data["reading_unit"] = self.reading_unit
|
||||
if self.readings:
|
||||
data["readings"] = self.readings
|
||||
# Only persist a non-default priority to keep stored dicts lean.
|
||||
if self.priority and self.priority != "normal":
|
||||
data["priority"] = self.priority
|
||||
@@ -652,6 +673,8 @@ class MaintenanceTask:
|
||||
data["labels"] = self.labels
|
||||
if self.earliest_completion_days is not None:
|
||||
data["earliest_completion_days"] = self.earliest_completion_days
|
||||
if self.ref_no is not None:
|
||||
data["ref_no"] = self.ref_no
|
||||
if self.archived_at is not None:
|
||||
data["archived_at"] = self.archived_at
|
||||
if self.archived_reason is not None:
|
||||
@@ -701,6 +724,7 @@ class MaintenanceTask:
|
||||
schedule_raw=data.get("schedule") if isinstance(data.get("schedule"), dict) else None,
|
||||
warning_days=data.get("warning_days", DEFAULT_WARNING_DAYS),
|
||||
earliest_completion_days=data.get("earliest_completion_days"),
|
||||
ref_no=data.get("ref_no"),
|
||||
last_performed=data.get("last_performed"),
|
||||
created_at=data.get("created_at"),
|
||||
interval_anchor=sched["interval_anchor"],
|
||||
@@ -713,6 +737,7 @@ class MaintenanceTask:
|
||||
custom_icon=data.get("custom_icon"),
|
||||
nfc_tag_id=data.get("nfc_tag_id"),
|
||||
reading_unit=data.get("reading_unit"),
|
||||
readings=data.get("readings") or [],
|
||||
priority=data.get("priority", "normal"),
|
||||
labels=data.get("labels", []),
|
||||
archived_at=data.get("archived_at"),
|
||||
|
||||
Reference in New Issue
Block a user