paperwork: Move mailing list api to Department model, add extra info

This commit is contained in:
Adam Goldsmith 2023-01-19 14:40:41 -05:00
parent a54c2bf909
commit ca43798ce6

View File

@ -22,6 +22,63 @@ class DepartmentViewSet(viewsets.ModelViewSet):
queryset = Department.objects.all()
serializer_class = DepartmentSerializer
@action(detail=False, methods=["get"])
def mailing_lists(self, request, format=None):
"""
Generate a mailing list for each department, containing all
certified users for tools in that department or child departments
"""
departments = self.queryset.prefetch_related(
"children",
"list_moderator_flag",
Prefetch(
"certificationdefinition_set__certificationversion_set__certification_set__member",
queryset=Member.objects.with_is_active(),
),
)
lists = {}
for department in departments:
if department.list_moderator_flag is not None:
moderator_emails = department.list_moderator_flag.members.values_list(
"email", flat=True
)
else:
moderator_emails = []
# TODO: this could be done in SQL instead if
# membershipworks was in the same database
active_certified_members = {
member_cert.member.sanitized_mailbox
for certification in department.certificationdefinition_set.all()
for version in certification.certificationversion_set.all()
for member_cert in version.certification_set.all()
if member_cert.member and member_cert.member.is_active
}
lists[department.list_name] = {
"real_name": department.list_name,
"moderator": moderator_emails,
"subject_prefix": f"[CMS {department.name}] ",
"reply_to_address": department.list_reply_to_address,
"members": active_certified_members,
}
# Add child departments' members to their parents
# TODO: this seems wildly inefficient
def recurse_children(department):
for child in department.children.all():
recurse_children(child)
lists[department.list_name]["members"] |= lists[child.list_name][
"members"
]
for department in departments:
if department.parent_id is None:
recurse_children(department)
return Response(lists)
class CertificationDefinitionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
@ -33,32 +90,6 @@ class CertificationDefinitionViewSet(viewsets.ModelViewSet):
queryset = CertificationDefinition.objects.all()
serializer_class = CertificationDefinitionSerializer
@action(detail=False, methods=["get"])
def mailing_lists(self, request, format=None):
"""
Generate a mailing list for each certification definition,
containing all certified users for that tool
"""
lists = {}
for definition in self.queryset.exclude(mailing_list="").prefetch_related(
Prefetch(
"certificationversion_set__certification_set__member",
queryset=Member.objects.with_is_active(),
),
):
if definition.mailing_list not in lists:
lists[definition.mailing_list] = set()
# TODO: this could be done in sql instead; was planning to
# maybe also filter to only active certs
for version in definition.certificationversion_set.all():
for cert in version.certification_set.all():
if cert.member and cert.member.is_active:
lists[definition.mailing_list].add(
cert.member.sanitized_mailbox
)
return Response(lists)
class CertificationVersionSerializer(serializers.HyperlinkedModelSerializer):
class Meta: