Skip to content

spp.group.membership: archiving via active is inconsistent — set only by a UI onchange, never when the clock crosses ended_date #420

Description

@gonzalesedwin1123

Follow-up to #417 / #418, deliberately left out of that fix's scope.

Summary

spp.group.membership.active has the same clock-staleness disease that #417 fixed for status/is_ended, plus a delivery-channel inconsistency:

  • _onchange_ended_date (spp_registry/models/group_membership.py) sets active = False when a past ended_date is entered — but onchange only fires in the UI. Memberships ended via API, imports, or code keep active = True.
  • Nothing ever archives a membership when the clock crosses a future ended_date. The fix(registry): cron-repair stored membership status/is_ended that go stale with the clock #418 cron repairs status/is_ended but deliberately does not touch active (see its docstring), because archiving changes record visibility everywhere and deserves its own decision.

Consequences

Two memberships with identical data end up in different states depending on how and when the end date was recorded:

  • Entered retroactively in the UI → archived, drops out of group.group_membership_ids (the x2many filters on active), invisible in default searches.
  • Entered ahead of time (or via API) → stays unarchived forever, keeps inflating unfiltered counts such as spp_change_request_v2/models/res_partner.py:53 (len(partner.group_membership_ids)).

The reverse also holds: a membership whose end date is later cleared/pushed forward stays archived.

Decision needed

Pick one consistent semantic:

  1. active mirrors is_ended — archive on end, unarchive on reactivation, enforced in write()/the cron rather than an onchange. Every consumer of group_membership_ids then sees only current members, which is a behavior change for any consumer relying on ended-but-unarchived rows.
  2. active is manual-only — remove the onchange auto-archiving so active becomes a purely operator-controlled flag, and consumers filter on is_ended/status (now reliable after fix(registry): cron-repair stored membership status/is_ended that go stale with the clock #418).

Either way the onchange-only channel should go — model-level behavior must not depend on which client wrote the record.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions