0.2.34: manage exited status from the Capital Accounts view

The eNAV keeps listing exited members each quarter, so the admin needs
the exit control where the statements live:
- Capital Accounts table gains a Status column with the same
  Exited-badge / mark / undo flow as the Partners tab (keyed per
  investor+fund pair — marking any statement row marks them all)
- set_partner_exited now creates the access row (flag set) when a
  manually-entered investor has statements but no roster entry yet;
  clearing a never-set exit stays 404

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jonathan Kirkwood
2026-07-03 09:03:49 -05:00
co-authored by Claude Opus 4.8
parent a639ba14cf
commit 6313d781b4
8 changed files with 115 additions and 15 deletions
+14 -4
View File
@@ -171,16 +171,26 @@ def set_partner_exited(
Their statements and documents stay; the portal shows an Exited badge instead of a
phantom -100% and drops the position from portfolio and fund committed totals.
"""
if session.get(Entity, entity_id) is None:
raise HTTPException(status_code=404, detail="Entity not found")
member = session.get(User, user_id)
if member is None or member.role != UserRole.investor:
raise HTTPException(status_code=400, detail="Only investor members can be marked exited")
access = session.exec(
select(EntityAccess).where(
EntityAccess.entity_id == entity_id, EntityAccess.user_id == user_id
)
).first()
if access is None:
raise HTTPException(status_code=404, detail="That member has no access to this fund")
member = session.get(User, user_id)
if member is None or member.role != UserRole.investor:
raise HTTPException(status_code=400, detail="Only investor members can be marked exited")
# A manually-entered investor may have statements without an access grant yet
# (e.g. from the Capital Accounts screen). Marking them exited creates the roster
# row with the flag set; clearing an exit that doesn't exist stays a 404.
if body.exited_on is None:
raise HTTPException(status_code=404, detail="That member has no access to this fund")
access = EntityAccess(user_id=user_id, entity_id=entity_id)
session.add(access)
session.flush()
access.exited_on = body.exited_on
session.add(access)