def get_recipients()

in pontoon/messaging/views.py [0:0]


def get_recipients(form):
    recipients = User.objects.none()

    """
    Filter recipients by user role, locale and project:
    - Contributors of selected Locales and Projects
    - Managers of selected Locales
    - Translators of selected Locales
    """
    locale_ids = sorted(split_ints(form.cleaned_data.get("locales")))
    project_ids = form.cleaned_data.get("projects")

    translations = Translation.objects.filter(
        locale_id__in=locale_ids,
        entity__resource__project_id__in=project_ids,
    )

    locales = Locale.objects.filter(pk__in=locale_ids)
    manager_ids = (
        locales.exclude(managers_group__user__isnull=True)
        .values("managers_group__user")
        .distinct()
    )
    translator_ids = (
        locales.exclude(translators_group__user__isnull=True)
        .values("translators_group__user")
        .distinct()
    )

    if form.cleaned_data.get("contributors"):
        contributors = translations.values("user").distinct()
        recipients = recipients | User.objects.filter(pk__in=contributors)

    if form.cleaned_data.get("managers"):
        recipients = recipients | User.objects.filter(pk__in=manager_ids)

    if form.cleaned_data.get("translators"):
        recipients = recipients | User.objects.filter(pk__in=translator_ids)

    """
    Filter recipients by login date:
    - Logged in after provided From date
    - Logged in before provided To date
    """
    login_from = form.cleaned_data.get("login_from")
    login_to = form.cleaned_data.get("login_to")

    if login_from:
        recipients = recipients.filter(last_login__gte=login_from)

    if login_to:
        recipients = recipients.filter(last_login__lte=login_to)

    """
    Filter recipients by translation submissions:
    - Submitted more than provided Minimum translations
    - Submitted less than provided Maximum translations
    - Submitted translations after provided From date
    - Submitted translations before provided To date
    """
    translation_minimum = form.cleaned_data.get("translation_minimum")
    translation_maximum = form.cleaned_data.get("translation_maximum")
    translation_from = form.cleaned_data.get("translation_from")
    translation_to = form.cleaned_data.get("translation_to")

    submitted = translations

    if translation_from:
        submitted = submitted.filter(date__gte=translation_from)

    if translation_to:
        submitted = submitted.filter(date__lte=translation_to)

    # For the Minimum count, no value is the same as 0
    # For the Maximum count, distinguish between no value and 0
    if translation_minimum or translation_maximum is not None:
        submitted = submitted.values("user").annotate(count=Count("user"))

    if translation_minimum:
        submitted = submitted.filter(count__gte=translation_minimum)

    if translation_maximum is not None:
        submitted = submitted.filter(count__lte=translation_maximum)

    """
    Filter recipients by reviews performed:
    - Reviewed more than provided Minimum translations
    - Reviewed less than provided Maximum translations
    - Reviewed translations after provided From date
    - Reviewed translations before provided To date
    """
    review_minimum = form.cleaned_data.get("review_minimum")
    review_maximum = form.cleaned_data.get("review_maximum")
    review_from = form.cleaned_data.get("review_from")
    review_to = form.cleaned_data.get("review_to")

    approved = translations.filter(approved_user__isnull=False).exclude(
        user=F("approved_user")
    )
    rejected = translations.filter(rejected_user__isnull=False).exclude(
        user=F("rejected_user")
    )

    if review_from:
        approved = approved.filter(approved_date__gte=review_from)
        rejected = rejected.filter(rejected_date__gte=review_from)

    if review_to:
        approved = approved.filter(approved_date__lte=review_to)
        rejected = rejected.filter(rejected_date__lte=review_to)

    # For the Minimum count, no value is the same as 0
    # For the Maximum count, distinguish between no value and 0
    if review_minimum or review_maximum is not None:
        approved = approved.values("approved_user").annotate(
            count=Count("approved_user")
        )
        rejected = rejected.values("rejected_user").annotate(
            count=Count("rejected_user")
        )

    if review_minimum:
        approved = approved.filter(count__gte=review_minimum)
        rejected = rejected.filter(count__gte=review_minimum)

    if review_maximum is not None:
        approved = approved.filter(count__lte=review_maximum)
        rejected = rejected.filter(count__lte=review_maximum)

    if (
        translation_from
        or translation_to
        or translation_minimum
        or translation_maximum is not None
    ):
        submission_filters = submitted.values_list("user", flat=True).distinct()
        recipients = recipients.filter(pk__in=submission_filters)

    if review_from or review_to or review_minimum or review_maximum is not None:
        approved_filters = approved.values_list("approved_user", flat=True).distinct()
        rejected_filters = rejected.values_list("rejected_user", flat=True).distinct()
        review_filters = approved_filters.union(rejected_filters)
        recipients = recipients.filter(pk__in=review_filters)

    return recipients