def group_has_pending_audit_members(session: Session, group: Group) -> bool: """Check if a group still has memberships with "pending" audit status.""" members_edge_ids = {member.edge_id for member in group.my_members().values()} audit_members_statuses = session.query(AuditMember.status).filter( AuditMember.audit_id == group.audit_id, AuditMember.status == "pending", # only those members who have not left the group after the audit started AuditMember.edge_id.in_(members_edge_ids), ) return audit_members_statuses.count()
def get_group_audit_members_infos(session: Session, group: Group) -> List[AuditMemberInfo]: """Get audit information about the members of a group. Note that only current members of the group are relevant, i.e., members of the group at the time the current audit was started but are no longer part of the group are excluded, as are members of the group added after the audit was started. """ members_edge_ids = {member.edge_id for member in group.my_members().values()} user_members = ( session.query(AuditMember, GroupEdge._role, User) .filter( AuditMember.audit_id == group.audit_id, AuditMember.edge_id == GroupEdge.id, GroupEdge.member_type == OBJ_TYPES["User"], GroupEdge.member_pk == User.id, # only those members who have not left the group after the audit started AuditMember.edge_id.in_(members_edge_ids), ) .all() ) group_members = ( session.query(AuditMember, GroupEdge._role, Group) .filter( AuditMember.audit_id == group.audit_id, AuditMember.edge_id == GroupEdge.id, GroupEdge.member_type == OBJ_TYPES["Group"], GroupEdge.member_pk == Group.id, # only those members who have not left the group after the audit started AuditMember.edge_id.in_(members_edge_ids), ) .all() ) return [ AuditMemberInfo(audit_member, audit_member_role, member_obj) for audit_member, audit_member_role, member_obj in itertools.chain( user_members, group_members ) ]