Fix retirement propagation and task counts
This commit is contained in:
@@ -109,6 +109,29 @@ def firm_task_hash(target: FirmServiceTaskTemplate) -> str:
|
||||
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _legacy_retirement_equivalent(
|
||||
source: ServiceDefaultTaskTemplate,
|
||||
target: FirmServiceTaskTemplate,
|
||||
) -> bool:
|
||||
"""Return True when a legacy firm row differs only because the system row was retired.
|
||||
|
||||
Full-sync retirement moves omitted system rows into a high temporary sequence range
|
||||
before setting is_active=False. Legacy firm rows created before provenance tracking still
|
||||
carry their old active flag and old sequence. Those two differences must not make an
|
||||
otherwise inherited task look like a deliberate firm customization.
|
||||
|
||||
Any substantive field difference still protects the firm row as customized.
|
||||
"""
|
||||
source_snapshot = _snapshot_dict(source)
|
||||
target_snapshot = _snapshot_dict(target)
|
||||
source_snapshot.pop("is_active", None)
|
||||
target_snapshot.pop("is_active", None)
|
||||
if int(getattr(source, "sequence_no", 0) or 0) >= 100000:
|
||||
source_snapshot.pop("sequence_no", None)
|
||||
target_snapshot.pop("sequence_no", None)
|
||||
return source_snapshot == target_snapshot
|
||||
|
||||
|
||||
def system_task_diff(source: ServiceDefaultTaskTemplate, target: FirmServiceTaskTemplate) -> list[dict[str, Any]]:
|
||||
labels = {
|
||||
"task_name": "Task name",
|
||||
@@ -367,11 +390,31 @@ def sync_firm_tasks_from_system_defaults(
|
||||
# For legacy rows with no inheritance history, infer whether they were
|
||||
# already firm-customized by comparing the full portable snapshot.
|
||||
if linked_from_legacy and target.last_synced_system_hash is None:
|
||||
target.is_customized = firm_task_hash(target) != latest_hash
|
||||
if not source.is_active and _legacy_retirement_equivalent(source, target):
|
||||
# This was an inherited legacy row whose system source has just been
|
||||
# retired by Full Synchronization. Do not misclassify the active/old
|
||||
# sequence difference as a firm customization; allow normal retirement
|
||||
# propagation below.
|
||||
target.is_customized = False
|
||||
else:
|
||||
target.is_customized = firm_task_hash(target) != latest_hash
|
||||
if not target.is_customized:
|
||||
target.last_synced_system_hash = latest_hash
|
||||
target.last_reviewed_system_hash = latest_hash
|
||||
|
||||
# Repair rows linked by an earlier rollout where retirement-only differences
|
||||
# were incorrectly interpreted as customization. This is deliberately limited
|
||||
# to rows that have never had a successful inherited snapshot recorded.
|
||||
if (
|
||||
not source.is_active
|
||||
and target.is_customized
|
||||
and target.last_synced_system_hash is None
|
||||
and _legacy_retirement_equivalent(source, target)
|
||||
):
|
||||
target.is_customized = False
|
||||
target.system_update_available = False
|
||||
target.system_update_detected_at_utc = None
|
||||
|
||||
# Detect out-of-band edits to a linked inherited row as customization.
|
||||
if (
|
||||
not target.is_customized
|
||||
|
||||
Reference in New Issue
Block a user