Esempio n. 1
0
    def handle(self, *args, form_slug, **options):
        now = timezone.now()
        form = PersonForm.objects.get(slug=form_slug)
        reunion_publique = EventSubtype.objects.get(label="reunion-publique")
        submissions = form.submissions.annotate(
            projet_cree=Exists(
                Projet.objects.annotate(
                    submission_id=Cast(
                        Func(
                            F("details"),
                            Value("submission_id"),
                            function="jsonb_extract_path_text",
                        ),
                        output_field=IntegerField(),
                    )
                ).filter(submission_id=OuterRef("id"))
            ),
            possible_date=Cast(
                Func(
                    F("data"),
                    Value("possible_date"),
                    function="jsonb_extract_path_text",
                ),
                output_field=DateTimeField(),
            ),
        ).filter(projet_cree=False, possible_date__gt=now)

        logger.info(f"Création de {submissions.count()} nouveaux projets")
        # créer les projets correspondants
        for s in submissions.filter(projet_cree=False):
            name = f'Réunion publique à {s.data["location_city"]}'
            date = parse_date(s.data["possible_date"])

            if s.data.get("organizer_group"):
                try:
                    group = SupportGroup.objects.get(id=s.data["organizer_group"])
                except SupportGroup.DoesNotExist:
                    group = None
            else:
                group = None

            logger.debug(f"Création projet et événement « {name} »")

            with transaction.atomic():
                event = Event.objects.create(
                    name=name[: Event._meta.get_field("name").max_length],
                    visibility=Event.VISIBILITY_ORGANIZER,
                    subtype=reunion_publique,
                    start_time=date,
                    end_time=date + timedelta(hours=2),
                    **{
                        k: v[: Event._meta.get_field(k).max_length]
                        for k, v in s.data.items()
                        if k
                        in [
                            "location_name",
                            "location_address1",
                            "location_zip",
                            "location_city",
                        ]
                    },
                )

                OrganizerConfig.objects.create(
                    event=event, person=s.person, as_group=group
                )

                Projet.objects.create(
                    titre=name[: Projet._meta.get_field("titre").max_length],
                    event=event,
                    type=TypeProjet.REUNION_PUBLIQUE_ORATEUR,
                    origine=Projet.Origin.REUNION_PUBLIQUE,
                    etat=Projet.Etat.CREE_PLATEFORME,
                    description=description_from_submission(s),
                    details={"submission_id": s.id},
                )

            geocode_event.delay(event.pk)
Esempio n. 2
0
def __is_reply_liked(outer_ref, request_user):
    """Check If Review is Liked by User"""
    return Exists(
        ReplyLike.objects.filter(
            reply_id=OuterRef(outer_ref),
            user_id=request_user.id if request_user else None))
Esempio n. 3
0
 def with_solved_by_user(self, user):
     return self.annotate(is_solved_by_user=Exists(
         self.filter(
             id=OuterRef('id'),
             solved_by=user.id or -1,
         ), ), )
Esempio n. 4
0
def index(request):
    query = (Evaluation.objects.annotate(participates_in=Exists(
        Evaluation.objects.filter(id=OuterRef("id"), participants=request.user)
    )).annotate(voted_for=Exists(
        Evaluation.objects.filter(id=OuterRef(
            "id"), voters=request.user))).filter(
                ~Q(state=Evaluation.State.NEW),
                course__evaluations__participants=request.user).exclude(
                    state=Evaluation.State.NEW).prefetch_related(
                        "course",
                        "course__semester",
                        "course__grade_documents",
                        "course__type",
                        "course__evaluations",
                        "course__responsibles",
                        "course__degrees",
                    ).distinct())
    query = Evaluation.annotate_with_participant_and_voter_counts(query)
    evaluations = [
        evaluation for evaluation in query
        if evaluation.can_be_seen_by(request.user)
    ]

    inner_evaluation_ids = [
        inner_evaluation.id for evaluation in evaluations
        for inner_evaluation in evaluation.course.evaluations.all()
    ]
    inner_evaluation_query = Evaluation.objects.filter(
        pk__in=inner_evaluation_ids)
    inner_evaluation_query = Evaluation.annotate_with_participant_and_voter_counts(
        inner_evaluation_query)

    evaluations_by_id = {
        evaluation["id"]: evaluation
        for evaluation in inner_evaluation_query.values()
    }

    for evaluation in evaluations:
        for inner_evaluation in evaluation.course.evaluations.all():
            inner_evaluation.num_voters = evaluations_by_id[
                inner_evaluation.id]["num_voters"]
            inner_evaluation.num_participants = evaluations_by_id[
                inner_evaluation.id]["num_participants"]

    annotate_distributions_and_grades(e for e in evaluations
                                      if e.state == Evaluation.State.PUBLISHED)
    evaluations = get_evaluations_with_course_result_attributes(evaluations)

    # evaluations must be sorted for regrouping them in the template
    evaluations.sort(
        key=lambda evaluation: (evaluation.course.name, evaluation.name))

    semesters = Semester.objects.all()
    semester_list = [
        dict(
            semester_name=semester.name,
            id=semester.id,
            results_are_archived=semester.results_are_archived,
            grade_documents_are_deleted=semester.grade_documents_are_deleted,
            evaluations=[
                evaluation for evaluation in evaluations
                if evaluation.course.semester_id == semester.id
            ],
        ) for semester in semesters
    ]

    unfinished_evaluations_query = (Evaluation.objects.filter(
        participants=request.user,
        state__in=[
            Evaluation.State.PREPARED,
            Evaluation.State.EDITOR_APPROVED,
            Evaluation.State.APPROVED,
            Evaluation.State.IN_EVALUATION,
        ],
    ).exclude(voters=request.user).prefetch_related("course__responsibles",
                                                    "course__type",
                                                    "course__semester"))

    unfinished_evaluations_query = Evaluation.annotate_with_participant_and_voter_counts(
        unfinished_evaluations_query)
    unfinished_evaluations = list(unfinished_evaluations_query)

    # available evaluations come first, ordered by time left for evaluation and the name
    # evaluations in other (visible) states follow by name
    def sorter(evaluation):
        return (
            evaluation.state != Evaluation.State.IN_EVALUATION,
            evaluation.vote_end_date
            if evaluation.state == Evaluation.State.IN_EVALUATION else None,
            evaluation.full_name,
        )

    unfinished_evaluations.sort(key=sorter)

    template_data = dict(
        semester_list=semester_list,
        can_download_grades=request.user.can_download_grades,
        unfinished_evaluations=unfinished_evaluations,
        evaluation_end_warning_period=settings.EVALUATION_END_WARNING_PERIOD,
    )

    return render(request, "student_index.html", template_data)
Esempio n. 5
0
def filter_products_by_categories(qs, category_ids):
    categories = Category.objects.filter(pk__in=category_ids)
    categories = Category.tree.get_queryset_descendants(
        categories, include_self=True).values("pk")
    return qs.filter(Exists(categories.filter(pk=OuterRef("category_id"))))
Esempio n. 6
0
 def test_dwithin_subquery(self):
     """dwithin lookup in a subquery using OuterRef as a parameter."""
     qs = CensusZipcode.objects.annotate(annotated_value=Exists(
         SouthTexasCity.objects.filter(point__dwithin=(
             OuterRef('poly'), D(m=10)), ))).filter(annotated_value=True)
     self.assertEqual(self.get_names(qs), ['77002', '77025', '77401'])
Esempio n. 7
0
def index(request):
    user = request.user
    show_delegated = get_parameter_from_url_or_session(request, "show_delegated", True)

    represented_proxy_users = user.represented_users.filter(is_proxy_user=True)
    contributor_visible_states = [
        Evaluation.State.PREPARED,
        Evaluation.State.EDITOR_APPROVED,
        Evaluation.State.APPROVED,
        Evaluation.State.IN_EVALUATION,
        Evaluation.State.EVALUATED,
        Evaluation.State.REVIEWED,
        Evaluation.State.PUBLISHED,
    ]
    own_courses = Course.objects.filter(
        Q(evaluations__state__in=contributor_visible_states)
        & (
            Q(responsibles=user)
            | Q(evaluations__contributions__contributor=user)
            | Q(evaluations__contributions__contributor__in=represented_proxy_users)
            | Q(responsibles__in=represented_proxy_users)
        )
    )

    own_evaluations = (
        Evaluation.objects.filter(course__in=own_courses)
        .annotate(contributes_to=Exists(Evaluation.objects.filter(id=OuterRef("id"), contributions__contributor=user)))
        .prefetch_related("course", "course__evaluations", "course__degrees", "course__type", "course__semester")
    )
    own_evaluations = [evaluation for evaluation in own_evaluations if evaluation.can_be_seen_by(user)]

    displayed_evaluations = own_evaluations
    if show_delegated:
        represented_users = user.represented_users.exclude(is_proxy_user=True)
        delegated_courses = Course.objects.filter(
            Q(evaluations__state__in=contributor_visible_states)
            & (
                Q(responsibles__in=represented_users)
                | Q(
                    evaluations__contributions__role=Contribution.Role.EDITOR,
                    evaluations__contributions__contributor__in=represented_users,
                )
            )
        )
        delegated_evaluations = Evaluation.objects.filter(course__in=delegated_courses).prefetch_related(
            "course", "course__evaluations", "course__degrees", "course__type", "course__semester"
        )
        delegated_evaluations = [evaluation for evaluation in delegated_evaluations if evaluation.can_be_seen_by(user)]
        for evaluation in delegated_evaluations:
            evaluation.delegated_evaluation = True
        displayed_evaluations += set(delegated_evaluations) - set(displayed_evaluations)

    displayed_evaluations.sort(
        key=lambda evaluation: (evaluation.course.name, evaluation.name)
    )  # evaluations must be sorted for regrouping them in the template

    annotate_distributions_and_grades(e for e in displayed_evaluations if e.state == Evaluation.State.PUBLISHED)
    displayed_evaluations = get_evaluations_with_course_result_attributes(displayed_evaluations)

    semesters = Semester.objects.all()
    semester_list = [
        dict(
            semester_name=semester.name,
            id=semester.id,
            is_active=semester.is_active,
            evaluations=[
                evaluation for evaluation in displayed_evaluations if evaluation.course.semester_id == semester.id
            ],
        )
        for semester in semesters
    ]

    template_data = dict(
        semester_list=semester_list,
        show_delegated=show_delegated,
        delegate_selection_form=DelegateSelectionForm(),
    )
    return render(request, "contributor_index.html", template_data)
Esempio n. 8
0
def filter_tags_list(qs, _, value):
    if not value:
        return qs
    tags = models.GiftCardTag.objects.filter(name__in=value)
    return qs.filter(Exists(tags.filter(pk=OuterRef("tags__id"))))
Esempio n. 9
0
    def total_queryset(self):

        cte_filters = [
            Q(treasury_account__isnull=False),
            self.all_closed_defc_submissions,
            self.is_in_provided_def_codes,
            self.is_non_zero_total_spending,
        ]

        cte_annotations = {
            "funding_toptier_agency_id":
            F("treasury_account__funding_toptier_agency_id"),
            "obligation":
            Coalesce(
                Sum(
                    Case(
                        When(
                            self.final_period_submission_query_filters,
                            then=
                            F("obligations_incurred_by_program_object_class_cpe"
                              ),
                        ),
                        default=Value(0),
                    )),
                0,
            ),
            "outlay":
            Coalesce(
                Sum(
                    Case(
                        When(
                            self.final_period_submission_query_filters,
                            then=
                            F("gross_outlay_amount_by_program_object_class_cpe"
                              ),
                        ),
                        default=Value(0),
                    )),
                0,
            ),
        }

        cte = With(
            FinancialAccountsByProgramActivityObjectClass.objects.filter(
                *cte_filters).values(
                    "treasury_account__funding_toptier_agency_id").annotate(
                        **cte_annotations).values(*cte_annotations))

        annotations = {
            "id":
            Subquery(
                Agency.objects.filter(
                    toptier_agency_id=OuterRef("toptier_agency_id")).order_by(
                        "-toptier_flag", "id").values("id")[:1]),
            "code":
            F("toptier_code"),
            "description":
            F("name"),
            # Currently, this endpoint can never have children w/o type = `award` & `award_type_codes`
            "children":
            Value([], output_field=ArrayField(IntegerField())),
            "award_count":
            Value(None, output_field=IntegerField()),
            "obligation":
            cte.col.obligation,
            "outlay":
            cte.col.outlay,
            "total_budgetary_resources":
            Coalesce(
                Subquery(
                    latest_gtas_of_each_year_queryset().filter(
                        disaster_emergency_fund_code__in=self.def_codes,
                        treasury_account_identifier__funding_toptier_agency_id=
                        OuterRef("toptier_agency_id"),
                    ).annotate(
                        amount=Func("total_budgetary_resources_cpe",
                                    function="Sum"),
                        unobligated_balance=Func(
                            "budget_authority_unobligated_balance_brought_forward_cpe",
                            function="Sum"),
                    ).annotate(total_budget_authority=F("amount") -
                               F("unobligated_balance")).values(
                                   "total_budget_authority"),
                    output_field=DecimalField(),
                ),
                0,
            ),
            "link":
            Exists(
                SubmissionAttributes.objects.filter(
                    toptier_code=OuterRef("toptier_code"))),
        }

        return (cte.join(
            ToptierAgency,
            toptier_agency_id=cte.col.funding_toptier_agency_id).with_cte(
                cte).annotate(**annotations).values(*annotations))
Esempio n. 10
0
def filter_gift_cards_by_products(qs, product_ids):
    products = product_models.Product.objects.filter(pk__in=product_ids)
    return qs.filter(Exists(products.filter(pk=OuterRef("product_id"))))
Esempio n. 11
0
def filter_gift_cards_by_used_by_user(qs, user_pks):
    users = account_models.User.objects.filter(pk__in=user_pks)
    return qs.filter(Exists(users.filter(pk=OuterRef("used_by_id"))))
Esempio n. 12
0
 def batch_load(self, keys):
     orders = Order.objects.filter(channel=OuterRef("pk"))
     channels = Channel.objects.annotate(
         has_orders=Exists(orders)).in_bulk(keys)
     return [channels.get(channel_id) for channel_id in keys]
Esempio n. 13
0
 def annotate_like(self, user):
     return self.annotate(liked=Exists(
         Like.objects.filter(user=user.id, post_id=OuterRef('id')).only(
             'id')))
Esempio n. 14
0
def filter_gift_card(qs, _, value):
    product_types = ProductType.objects.filter(kind=ProductTypeKind.GIFT_CARD)
    lookup = Exists(product_types.filter(id=OuterRef("product_type_id")))
    return qs.filter(lookup) if value is True else qs.exclude(lookup)
Esempio n. 15
0
 def for_user(self, user):
     return Comment.objects\
         .filter(Q(Exists(GroupMember.objects.only('id').filter(group=OuterRef('post__group'), user=user))) | Q(post__group__group_type=Group.OPEN))\
         .filter(is_deleted=False)
Esempio n. 16
0
def get_grouped_items(event,
                      subevent=None,
                      voucher=None,
                      channel='web',
                      require_seat=0,
                      base_qs=None,
                      allow_addons=False,
                      quota_cache=None,
                      filter_items=None,
                      filter_categories=None):
    base_qs_set = base_qs is not None
    base_qs = base_qs if base_qs is not None else event.items

    requires_seat = Exists(
        SeatCategoryMapping.objects.filter(product_id=OuterRef('pk'),
                                           subevent=subevent))
    if not event.settings.seating_choice:
        requires_seat = Value(0, output_field=IntegerField())

    items = base_qs.using(settings.DATABASE_REPLICA).filter_available(
        channel=channel, voucher=voucher,
        allow_addons=allow_addons).select_related(
            'category',
            'tax_rule',  # for re-grouping
            'hidden_if_available',
        ).prefetch_related(
            Prefetch('quotas',
                     to_attr='_subevent_quotas',
                     queryset=event.quotas.using(
                         settings.DATABASE_REPLICA).filter(subevent=subevent)),
            Prefetch(
                'bundles',
                queryset=ItemBundle.objects.using(
                    settings.DATABASE_REPLICA).prefetch_related(
                        Prefetch('bundled_item',
                                 queryset=event.items.using(
                                     settings.DATABASE_REPLICA).
                                 select_related('tax_rule').prefetch_related(
                                     Prefetch(
                                         'quotas',
                                         to_attr='_subevent_quotas',
                                         queryset=event.quotas.using(
                                             settings.DATABASE_REPLICA).filter(
                                                 subevent=subevent)), )),
                        Prefetch(
                            'bundled_variation',
                            queryset=ItemVariation.objects.using(
                                settings.DATABASE_REPLICA).select_related(
                                    'item', 'item__tax_rule').
                            filter(item__event=event).prefetch_related(
                                Prefetch('quotas',
                                         to_attr='_subevent_quotas',
                                         queryset=event.quotas.using(
                                             settings.DATABASE_REPLICA).filter(
                                                 subevent=subevent)), )),
                    )),
            Prefetch(
                'variations',
                to_attr='available_variations',
                queryset=ItemVariation.objects.using(
                    settings.DATABASE_REPLICA).annotate(
                        subevent_disabled=Exists(
                            SubEventItemVariation.objects.filter(
                                Q(disabled=True) | Q(available_from__gt=now())
                                | Q(available_until__lt=now()),
                                variation_id=OuterRef('pk'),
                                subevent=subevent,
                            )),
                    ).filter(active=True,
                             quotas__isnull=False,
                             subevent_disabled=False).prefetch_related(
                                 Prefetch(
                                     'quotas',
                                     to_attr='_subevent_quotas',
                                     queryset=event.quotas.using(
                                         settings.DATABASE_REPLICA).filter(
                                             subevent=subevent))).distinct()),
        ).annotate(
            quotac=Count('quotas'),
            has_variations=Count('variations'),
            subevent_disabled=Exists(
                SubEventItem.objects.filter(
                    Q(disabled=True) | Q(available_from__gt=now())
                    | Q(available_until__lt=now()),
                    item_id=OuterRef('pk'),
                    subevent=subevent,
                )),
            requires_seat=requires_seat,
        ).filter(
            quotac__gt=0,
            subevent_disabled=False,
        ).order_by('category__position', 'category_id', 'position', 'name')
    if require_seat:
        items = items.filter(requires_seat__gt=0)
    else:
        items = items.filter(requires_seat=0)

    if filter_items:
        items = items.filter(pk__in=[a for a in filter_items if a.isdigit()])
    if filter_categories:
        items = items.filter(
            category_id__in=[a for a in filter_categories if a.isdigit()])

    display_add_to_cart = False
    quota_cache_key = f'item_quota_cache:{subevent.id if subevent else 0}:{channel}:{bool(require_seat)}'
    quota_cache = quota_cache or event.cache.get(quota_cache_key) or {}
    quota_cache_existed = bool(quota_cache)

    if subevent:
        item_price_override = subevent.item_price_overrides
        var_price_override = subevent.var_price_overrides
    else:
        item_price_override = {}
        var_price_override = {}

    restrict_vars = set()
    if voucher and voucher.quota_id:
        # If a voucher is set to a specific quota, we need to filter out on that level
        restrict_vars = set(voucher.quota.variations.all())

    quotas_to_compute = []
    for item in items:
        if item.has_variations:
            for v in item.available_variations:
                for q in v._subevent_quotas:
                    if q.pk not in quota_cache:
                        quotas_to_compute.append(q)
        else:
            for q in item._subevent_quotas:
                if q.pk not in quota_cache:
                    quotas_to_compute.append(q)

    if quotas_to_compute:
        qa = QuotaAvailability()
        qa.queue(*quotas_to_compute)
        qa.compute()
        quota_cache.update({q.pk: r for q, r in qa.results.items()})

    for item in items:
        if voucher and voucher.item_id and voucher.variation_id:
            # Restrict variations if the voucher only allows one
            item.available_variations = [
                v for v in item.available_variations
                if v.pk == voucher.variation_id
            ]

        if get_all_sales_channels()[channel].unlimited_items_per_order:
            max_per_order = sys.maxsize
        else:
            max_per_order = item.max_per_order or int(
                event.settings.max_items_per_order)

        if item.hidden_if_available:
            q = item.hidden_if_available.availability(_cache=quota_cache)
            if q[0] == Quota.AVAILABILITY_OK:
                item._remove = True
                continue

        item.description = str(item.description)
        for recv, resp in item_description.send(sender=event,
                                                item=item,
                                                variation=None):
            if resp:
                item.description += ("<br/>"
                                     if item.description else "") + resp

        if not item.has_variations:
            item._remove = False
            if not bool(item._subevent_quotas):
                item._remove = True
                continue

            if voucher and (voucher.allow_ignore_quota or voucher.block_quota):
                item.cached_availability = (Quota.AVAILABILITY_OK,
                                            voucher.max_usages -
                                            voucher.redeemed)
            else:
                item.cached_availability = list(
                    item.check_quotas(subevent=subevent,
                                      _cache=quota_cache,
                                      include_bundled=True))

            if event.settings.hide_sold_out and item.cached_availability[
                    0] < Quota.AVAILABILITY_RESERVED:
                item._remove = True
                continue

            item.order_max = min(
                item.cached_availability[1] if item.cached_availability[1]
                is not None else sys.maxsize, max_per_order)

            original_price = item_price_override.get(item.pk,
                                                     item.default_price)
            if voucher:
                price = voucher.calculate_price(original_price)
            else:
                price = original_price

            item.display_price = item.tax(price,
                                          currency=event.currency,
                                          include_bundled=True)

            if price != original_price:
                item.original_price = item.tax(original_price,
                                               currency=event.currency,
                                               include_bundled=True)
            else:
                item.original_price = (
                    item.tax(item.original_price,
                             currency=event.currency,
                             include_bundled=True,
                             base_price_is='net'
                             if event.settings.display_net_prices else
                             'gross')  # backwards-compat
                    if item.original_price else None)

            display_add_to_cart = display_add_to_cart or item.order_max > 0
        else:
            for var in item.available_variations:
                var.description = str(var.description)
                for recv, resp in item_description.send(sender=event,
                                                        item=item,
                                                        variation=var):
                    if resp:
                        var.description += ("<br/>"
                                            if var.description else "") + resp

                if voucher and (voucher.allow_ignore_quota
                                or voucher.block_quota):
                    var.cached_availability = (Quota.AVAILABILITY_OK,
                                               voucher.max_usages -
                                               voucher.redeemed)
                else:
                    var.cached_availability = list(
                        var.check_quotas(subevent=subevent,
                                         _cache=quota_cache,
                                         include_bundled=True))

                var.order_max = min(
                    var.cached_availability[1] if var.cached_availability[1]
                    is not None else sys.maxsize, max_per_order)

                original_price = var_price_override.get(var.pk, var.price)
                if voucher:
                    price = voucher.calculate_price(original_price)
                else:
                    price = original_price

                var.display_price = var.tax(price,
                                            currency=event.currency,
                                            include_bundled=True)

                if price != original_price:
                    var.original_price = var.tax(original_price,
                                                 currency=event.currency,
                                                 include_bundled=True)
                else:
                    var.original_price = (
                        var.tax(var.original_price or item.original_price,
                                currency=event.currency,
                                include_bundled=True,
                                base_price_is='net'
                                if event.settings.display_net_prices else
                                'gross')  # backwards-compat
                    ) if var.original_price or item.original_price else None

                display_add_to_cart = display_add_to_cart or var.order_max > 0

            item.original_price = (
                item.tax(
                    item.original_price,
                    currency=event.currency,
                    include_bundled=True,
                    base_price_is='net' if event.settings.display_net_prices
                    else 'gross')  # backwards-compat
                if item.original_price else None)

            item.available_variations = [
                v for v in item.available_variations
                if v._subevent_quotas and (
                    not voucher or not voucher.quota_id or v in restrict_vars)
            ]

            if event.settings.hide_sold_out:
                item.available_variations = [
                    v for v in item.available_variations
                    if v.cached_availability[0] >= Quota.AVAILABILITY_RESERVED
                ]

            if voucher and voucher.variation_id:
                item.available_variations = [
                    v for v in item.available_variations
                    if v.pk == voucher.variation_id
                ]

            if len(item.available_variations) > 0:
                item.min_price = min([
                    v.display_price.net if event.settings.display_net_prices
                    else v.display_price.gross
                    for v in item.available_variations
                ])
                item.max_price = max([
                    v.display_price.net if event.settings.display_net_prices
                    else v.display_price.gross
                    for v in item.available_variations
                ])

            item._remove = not bool(item.available_variations)

    if not quota_cache_existed and not voucher and not allow_addons and not base_qs_set and not filter_items and not filter_categories:
        event.cache.set(quota_cache_key, quota_cache, 5)
    items = [
        item for item in items
        if (len(item.available_variations) > 0 or not item.has_variations)
        and not item._remove
    ]
    return items, display_add_to_cart
Esempio n. 17
0
def get_authorized_findings(permission, queryset=None, user=None):

    if user is None:
        user = get_current_user()

    if user is None:
        return Finding.objects.none()

    if queryset is None:
        findings = Finding.objects.all()
    else:
        findings = queryset

    if user.is_superuser:
        return findings

    if settings.FEATURE_AUTHORIZATION_V2:
        if user.is_staff and settings.AUTHORIZATION_STAFF_OVERRIDE:
            return findings

        if hasattr(
                user, 'global_role'
        ) and user.global_role.role is not None and role_has_permission(
                user.global_role.role.id, permission):
            return findings

        for group in get_groups(user):
            if hasattr(
                    group, 'global_role'
            ) and group.global_role.role is not None and role_has_permission(
                    group.global_role.role.id, permission):
                return findings

        roles = get_roles_for_permission(permission)
        authorized_product_type_roles = Product_Type_Member.objects.filter(
            product_type=OuterRef('test__engagement__product__prod_type_id'),
            user=user,
            role__in=roles)
        authorized_product_roles = Product_Member.objects.filter(
            product=OuterRef('test__engagement__product_id'),
            user=user,
            role__in=roles)
        authorized_product_type_groups = Product_Type_Group.objects.filter(
            product_type=OuterRef('test__engagement__product__prod_type_id'),
            group__users=user,
            role__in=roles)
        authorized_product_groups = Product_Group.objects.filter(
            product=OuterRef('test__engagement__product_id'),
            group__users=user,
            role__in=roles)
        findings = findings.annotate(
            test__engagement__product__prod_type__member=Exists(
                authorized_product_type_roles),
            test__engagement__product__member=Exists(authorized_product_roles),
            test__engagement__product__prod_type__authorized_group=Exists(
                authorized_product_type_groups),
            test__engagement__product__authorized_group=Exists(
                authorized_product_groups))
        findings = findings.filter(
            Q(test__engagement__product__prod_type__member=True)
            | Q(test__engagement__product__member=True)
            | Q(test__engagement__product__prod_type__authorized_group=True)
            | Q(test__engagement__product__authorized_group=True))
    else:
        if not user.is_staff:
            findings = findings.filter(
                Q(test__engagement__product__authorized_users__in=[user]) |
                Q(test__engagement__product__prod_type__authorized_users__in=[
                    user
                ]))
    return findings
def cancel_event(self,
                 event: Event,
                 subevent: int,
                 auto_refund: bool,
                 keep_fee_fixed: str,
                 keep_fee_per_ticket: str,
                 keep_fee_percentage: str,
                 keep_fees: list = None,
                 manual_refund: bool = False,
                 send: bool = False,
                 send_subject: dict = None,
                 send_message: dict = None,
                 send_waitinglist: bool = False,
                 send_waitinglist_subject: dict = {},
                 send_waitinglist_message: dict = {},
                 user: int = None,
                 refund_as_giftcard: bool = False,
                 giftcard_expires=None,
                 giftcard_conditions=None,
                 subevents_from: str = None,
                 subevents_to: str = None):
    send_subject = LazyI18nString(send_subject)
    send_message = LazyI18nString(send_message)
    send_waitinglist_subject = LazyI18nString(send_waitinglist_subject)
    send_waitinglist_message = LazyI18nString(send_waitinglist_message)
    if user:
        user = User.objects.get(pk=user)

    s = OrderPosition.objects.filter(
        order=OuterRef('pk')).order_by().values('order').annotate(
            k=Count('id')).values('k')
    orders_to_cancel = event.orders.annotate(
        pcnt=Subquery(s, output_field=IntegerField())).filter(
            status__in=[
                Order.STATUS_PAID, Order.STATUS_PENDING, Order.STATUS_EXPIRED
            ],
            pcnt__gt=0).all()

    if subevent or subevents_from:
        if subevent:
            subevents = event.subevents.filter(pk=subevent)
            subevent = subevents.first()
            subevent_ids = {subevent.pk}
        else:
            subevents = event.subevents.filter(date_from__gte=subevents_from,
                                               date_from__lt=subevents_to)
            subevent_ids = set(subevents.values_list('id', flat=True))

        has_subevent = OrderPosition.objects.filter(
            order_id=OuterRef('pk')).filter(subevent__in=subevents)
        has_other_subevent = OrderPosition.objects.filter(
            order_id=OuterRef('pk')).exclude(subevent__in=subevents)
        orders_to_change = orders_to_cancel.annotate(
            has_subevent=Exists(has_subevent),
            has_other_subevent=Exists(has_other_subevent),
        ).filter(has_subevent=True, has_other_subevent=True)
        orders_to_cancel = orders_to_cancel.annotate(
            has_subevent=Exists(has_subevent),
            has_other_subevent=Exists(has_other_subevent),
        ).filter(has_subevent=True, has_other_subevent=False)

        for se in subevents:
            se.log_action(
                'pretix.subevent.canceled',
                user=user,
            )
            se.active = False
            se.save(update_fields=['active'])
            se.log_action('pretix.subevent.changed',
                          user=user,
                          data={
                              'active': False,
                              '_source': 'cancel_event'
                          })
    else:
        subevents = None
        subevent_ids = set()
        orders_to_change = event.orders.none()
        event.log_action(
            'pretix.event.canceled',
            user=user,
        )

        for i in event.items.filter(active=True):
            i.active = False
            i.save(update_fields=['active'])
            i.log_action('pretix.event.item.changed',
                         user=user,
                         data={
                             'active': False,
                             '_source': 'cancel_event'
                         })
    failed = 0
    total = orders_to_cancel.count() + orders_to_change.count()
    qs_wl = event.waitinglistentries.filter(
        voucher__isnull=True).select_related('subevent')
    if subevents:
        qs_wl = qs_wl.filter(subevent__in=subevents)
    if send_waitinglist:
        total += qs_wl.count()
    counter = 0
    self.update_state(state='PROGRESS', meta={'value': 0})

    for o in orders_to_cancel.only('id', 'total').iterator():
        try:
            fee = Decimal('0.00')
            fee_sum = Decimal('0.00')
            keep_fee_objects = []
            if keep_fees:
                for f in o.fees.all():
                    if f.fee_type in keep_fees:
                        fee += f.value
                        keep_fee_objects.append(f)
                    fee_sum += f.value
            if keep_fee_percentage:
                fee += Decimal(keep_fee_percentage) / Decimal('100.00') * (
                    o.total - fee_sum)
            if keep_fee_fixed:
                fee += Decimal(keep_fee_fixed)
            if keep_fee_per_ticket:
                for p in o.positions.all():
                    if p.addon_to_id is None:
                        fee += min(p.price, Decimal(keep_fee_per_ticket))
            fee = round_decimal(min(fee, o.payment_refund_sum), event.currency)

            _cancel_order(o.pk,
                          user,
                          send_mail=False,
                          cancellation_fee=fee,
                          keep_fees=keep_fee_objects)
            refund_amount = o.payment_refund_sum

            try:
                if auto_refund:
                    _try_auto_refund(o.pk,
                                     manual_refund=manual_refund,
                                     allow_partial=True,
                                     source=OrderRefund.REFUND_SOURCE_ADMIN,
                                     refund_as_giftcard=refund_as_giftcard,
                                     giftcard_expires=giftcard_expires,
                                     giftcard_conditions=giftcard_conditions)
            finally:
                if send:
                    _send_mail(o, send_subject, send_message, subevent,
                               refund_amount, user, o.positions.all())

            counter += 1
            if not self.request.called_directly and counter % max(
                    10, total // 100) == 0:
                self.update_state(
                    state='PROGRESS',
                    meta={'value': round(counter / total * 100, 2)})
        except LockTimeoutException:
            logger.exception("Could not cancel order")
            failed += 1
        except OrderError:
            logger.exception("Could not cancel order")
            failed += 1

    for o in orders_to_change.values_list('id', flat=True).iterator():
        with transaction.atomic():
            o = event.orders.select_for_update().get(pk=o)
            total = Decimal('0.00')
            fee = Decimal('0.00')
            positions = []

            ocm = OrderChangeManager(o, user=user, notify=False)
            for p in o.positions.all():
                if p.subevent_id in subevent_ids:
                    total += p.price
                    ocm.cancel(p)
                    positions.append(p)

                    if keep_fee_per_ticket:
                        if p.addon_to_id is None:
                            fee += min(p.price, Decimal(keep_fee_per_ticket))

            if keep_fee_fixed:
                fee += Decimal(keep_fee_fixed)
            if keep_fee_percentage:
                fee += Decimal(keep_fee_percentage) / Decimal('100.00') * total
            fee = round_decimal(min(fee, o.payment_refund_sum), event.currency)
            if fee:
                f = OrderFee(
                    fee_type=OrderFee.FEE_TYPE_CANCELLATION,
                    value=fee,
                    order=o,
                    tax_rule=o.event.settings.tax_rate_default,
                )
                f._calculate_tax()
                ocm.add_fee(f)

            ocm.commit()
            refund_amount = o.payment_refund_sum - o.total

            if auto_refund:
                _try_auto_refund(o.pk,
                                 manual_refund=manual_refund,
                                 allow_partial=True,
                                 source=OrderRefund.REFUND_SOURCE_ADMIN,
                                 refund_as_giftcard=refund_as_giftcard,
                                 giftcard_expires=giftcard_expires,
                                 giftcard_conditions=giftcard_conditions)

            if send:
                _send_mail(o, send_subject, send_message, subevent,
                           refund_amount, user, positions)

            counter += 1
            if not self.request.called_directly and counter % max(
                    10, total // 100) == 0:
                self.update_state(
                    state='PROGRESS',
                    meta={'value': round(counter / total * 100, 2)})

    if send_waitinglist:
        for wle in qs_wl:
            _send_wle_mail(wle, send_waitinglist_subject,
                           send_waitinglist_message, wle.subevent)

            counter += 1
            if not self.request.called_directly and counter % max(
                    10, total // 100) == 0:
                self.update_state(
                    state='PROGRESS',
                    meta={'value': round(counter / total * 100, 2)})
    return failed
Esempio n. 19
0
def service_vehicles_history(request, slug):
    service = get_object_or_404(Service, slug=slug)
    date = request.GET.get('date')
    if date:
        try:
            date = ciso8601.parse_datetime(date).date()
        except ValueError:
            date = None
    journeys = service.vehiclejourney_set
    dates = journeys.values_list('datetime__date', flat=True).distinct().order_by('datetime__date')
    if not date:
        date = dates.last()
        if not date:
            raise Http404()
    locations = VehicleLocation.objects.filter(journey=OuterRef('pk'))
    journeys = journeys.filter(datetime__date=date).select_related('vehicle').annotate(locations=Exists(locations))
    operator = service.operator.select_related('region').first()
    return render(request, 'vehicles/vehicle_detail.html', {
        'breadcrumb': [operator.region, operator, service],
        'date': date,
        'dates': dates,
        'object': service,
        'journeys': journeys,
    })
Esempio n. 20
0
def index(request):
    query = (Evaluation.objects.annotate(participates_in=Exists(
        Evaluation.objects.filter(id=OuterRef('id'), participants=request.user)
    )).annotate(voted_for=Exists(
        Evaluation.objects.filter(id=OuterRef(
            'id'), voters=request.user))).filter(
                ~Q(state="new"),
                course__evaluations__participants=request.user).exclude(
                    state="new").prefetch_related(
                        'course',
                        'course__semester',
                        'course__grade_documents',
                        'course__type',
                        'course__evaluations',
                        'course__responsibles',
                        'course__degrees',
                    ).distinct())
    query = Evaluation.annotate_with_participant_and_voter_counts(query)
    evaluations = [
        evaluation for evaluation in query
        if evaluation.can_be_seen_by(request.user)
    ]

    inner_evaluation_ids = [
        inner_evaluation.id for evaluation in evaluations
        for inner_evaluation in evaluation.course.evaluations.all()
    ]
    inner_evaluation_query = Evaluation.objects.filter(
        pk__in=inner_evaluation_ids)
    inner_evaluation_query = Evaluation.annotate_with_participant_and_voter_counts(
        inner_evaluation_query)

    evaluations_by_id = {
        evaluation['id']: evaluation
        for evaluation in inner_evaluation_query.values()
    }

    for evaluation in evaluations:
        for inner_evaluation in evaluation.course.evaluations.all():
            inner_evaluation.num_voters = evaluations_by_id[
                inner_evaluation.id]['num_voters']
            inner_evaluation.num_participants = evaluations_by_id[
                inner_evaluation.id]['num_participants']

    for evaluation in evaluations:
        if evaluation.state == "published":
            if not evaluation.is_single_result:
                evaluation.distribution = calculate_average_distribution(
                    evaluation)
            else:
                evaluation.single_result_rating_result = get_single_result_rating_result(
                    evaluation)
                evaluation.distribution = normalized_distribution(
                    evaluation.single_result_rating_result.counts)
            evaluation.avg_grade = distribution_to_grade(
                evaluation.distribution)
    evaluations = get_evaluations_with_course_result_attributes(evaluations)

    # evaluations must be sorted for regrouping them in the template
    evaluations.sort(
        key=lambda evaluation: (evaluation.course.name, evaluation.name))

    semesters = Semester.objects.all()
    semester_list = [
        dict(semester_name=semester.name,
             id=semester.id,
             results_are_archived=semester.results_are_archived,
             grade_documents_are_deleted=semester.grade_documents_are_deleted,
             evaluations=[
                 evaluation for evaluation in evaluations
                 if evaluation.course.semester_id == semester.id
             ]) for semester in semesters
    ]

    unfinished_evaluations_query = (Evaluation.objects.filter(
        participants=request.user,
        state__in=['prepared', 'editor_approved', 'approved', 'in_evaluation'
                   ]).exclude(voters=request.user).prefetch_related(
                       'course__responsibles', 'course__type',
                       'course__semester'))

    unfinished_evaluations_query = Evaluation.annotate_with_participant_and_voter_counts(
        unfinished_evaluations_query)
    unfinished_evaluations = list(unfinished_evaluations_query)

    # available evaluations come first, ordered by time left for evaluation and the name
    # evaluations in other (visible) states follow by name
    def sorter(evaluation):
        return (evaluation.state != 'in_evaluation', evaluation.vote_end_date
                if evaluation.state == 'in_evaluation' else None,
                evaluation.full_name)

    unfinished_evaluations.sort(key=sorter)

    template_data = dict(
        semester_list=semester_list,
        can_download_grades=request.user.can_download_grades,
        unfinished_evaluations=unfinished_evaluations,
        evaluation_end_warning_period=settings.EVALUATION_END_WARNING_PERIOD,
    )

    return render(request, "student_index.html", template_data)
Esempio n. 21
0
def projects(request:HttpRequest) -> JsonResponse:
    """ List projects visible to the requesting user.
    ---
    models:
      project_api_stack_element:
        id: project_api_stack_element
        properties:
          id:
            type: integer
            description: Stack ID
            required: true
          title:
            type: string
            description: Stack title
            required: true
          comment:
            type: string
            description: Comment on stack
            required: true
      project_api_stackgroup_element:
        id: project_api_stackgroup_element
        properties:
          id:
            type: integer
            description: Stack group ID
            required: true
          title:
            type: string
            description: Stack group title
            required: true
          comment:
            type: string
            description: Comment on stack group
            required: true
      project_api_element:
        id: project_api_element
        properties:
          id:
            type: integer
            description: Project ID
            required: true
          title:
            type: string
            description: Project title
            required: true
          stacks:
            type: array
            items:
              $ref: project_api_stack_element
            required: true
          stackgroups:
            type: array
            items:
              $ref: project_api_stackgroup_element
            required: true
    parameters:
    - name: has_tracing_data
      description: Return only projects that have tracing data
      required: false
      defaultValue: falese
      type: boolean
    type:
      projects:
        type: array
        items:
          $ref: project_api_element
        required: true
    """

    # Get all projects that are visisble for the current user
    projects = get_project_qs_for_user(request.user).order_by('title')
    has_tracing_data = get_request_bool(request.GET, 'has_tracing_data', False)

    if has_tracing_data:
        projects = projects.annotate(
            no_locations=~Exists(Location.objects.filter(project=OuterRef('pk')))
        ).filter(
            no_locations=False
        )

    if 0 == len(projects):
        return JsonResponse([], safe=False)

    cursor = connection.cursor()
    user_project_ids = [p.id for p in projects]

    tracing_data_join = ''
    extra_where = []
    if has_tracing_data:
        tracing_data_join = '''
            INNER JOIN LATERAL (
                SELECT EXISTS (SELECT 1 FROM location WHERE project_id = ps.project_id)
            ) sub(has_tracing_data)
                ON TRUE
        '''
        extra_where.append('''
            sub.has_tracing_data = True
        ''')

    project_stack_mapping:Dict = dict()
    cursor.execute("""
        SELECT DISTINCT ON (ps.project_id, ps.stack_id) ps.project_id, ps.stack_id, s.title, s.comment
        FROM project_stack ps
        JOIN UNNEST(%(user_project_ids)s::integer[]) user_project(id)
            ON ps.project_id = user_project.id
        JOIN stack s
            ON ps.stack_id = s.id
    """, {
        'user_project_ids': user_project_ids,
    })
    for row in cursor.fetchall():
        stacks = project_stack_mapping.get(row[0])
        if not stacks:
            stacks = []
            project_stack_mapping[row[0]] = stacks
        stacks.append({
            'id': row[1],
            'title': row[2],
            'comment': row[3]
        })

    # Get all stack groups for this project
    project_stack_groups:Dict = dict()
    cursor.execute("""
        SELECT DISTINCT ps.project_id, sg.id, sg.title, sg.comment
        FROM stack_group sg
        JOIN stack_stack_group ssg
          ON ssg.stack_group_id = sg.id
        JOIN project_stack ps
          ON ps.stack_id = ssg.stack_id
        INNER JOIN UNNEST(%(user_project_ids)s::integer[]) user_project(id)
          ON ps.project_id = user_project.id
    """, {
        'user_project_ids': user_project_ids,
    })
    for row in cursor.fetchall():
        groups = project_stack_groups.get(row[0])
        if not groups:
            groups = []
            project_stack_groups[row[0]] = groups
        groups.append({
            'id': row[1],
            'title': row[2],
            'comment': row[3],
        })

    result:List = []
    empty_tuple:Tuple = tuple()
    for p in projects:
        stacks = project_stack_mapping.get(p.id, empty_tuple)
        stackgroups = project_stack_groups.get(p.id, empty_tuple)

        result.append({
            'id': p.id,
            'title': p.title,
            'stacks': stacks,
            'stackgroups': stackgroups
        })

    return JsonResponse(result, safe=False, json_dumps_params={
        'sort_keys': True,
        'indent': 4
    })
Esempio n. 22
0
def entry_prefetch(queryset, user, comments=False):
    """
    Given an entry queryset, optimize it to be shown in templates (entry.html).
    :param queryset: Entry queryset.
    :param user: User who requests the queryset.
    :param comments: Set true to also prefetch comments.
    """
    prefetch = [Prefetch("favorited_by", queryset=Author.objects.only("id"))]

    if comments:
        comments_qs = (
            Comment.objects.annotate(rating=Count("upvoted_by", distinct=True) - Count("downvoted_by", distinct=True))
            .select_related("author")
            .only(
                "id",
                "entry_id",
                "content",
                "date_created",
                "date_edited",
                "author_id",
                "author__slug",
                "author__first_name",
                "author__last_name",
                "author__username",
            )
        )

        if user.is_authenticated:
            vote_states = dict(
                zip(
                    ("is_upvoted", "is_downvoted"),
                    (
                        Exists(model.objects.filter(author=user, comment=OuterRef("pk")))
                        for model in (Comment.upvoted_by.through, Comment.downvoted_by.through)
                    ),
                )
            )
            comments_qs = comments_qs.annotate(**vote_states)

        prefetch.append(Prefetch("comments", queryset=comments_qs))

    base = (
        queryset.select_related("author", "topic")
        .prefetch_related(*prefetch)
        .only(
            "id",
            "content",
            "date_created",
            "date_edited",
            "topic_id",
            "author_id",
            "author__slug",
            "author__username",
            "author__is_private",
            "author__is_novice",
            "topic_id",
            "topic__title",
            "topic__slug",
        )
    )

    if user.is_authenticated:
        vote_states = dict(
            zip(
                ("is_upvoted", "is_downvoted", "is_favorited"),
                (
                    Exists(model.objects.filter(author=user, entry=OuterRef("pk")))
                    for model in (UpvotedEntries, DownvotedEntries, EntryFavorites)
                ),
            )
        )

        return base.annotate(**vote_states)

    return base
Esempio n. 23
0
    def changelist_view(self, request, extra_context=None):
        response = super().changelist_view(
            request,
            extra_context=extra_context,
        )
        try:
            qs = response.context_data['cl'].queryset
        except (AttributeError, KeyError):
            return response
        """
        issues with multisection
        """
        multisectionExists = qs.filter(course_requested=OuterRef('pk'),
                                       additional_sections__isnull=False)

        metrics = {
            'total':
            Count('course_requested', distinct=True),
            'ares':
            Count('reserves', filter=Q(reserves=True)),
            'multisection':
            Sum(Exists(multisectionExists), output_field=IntegerField()),
            #F('additional_sections'),#Sum(Case(When(~Q(additional_sections=None), then=Value(1)),default=0,output_field=IntegerField(),distinct=True)),
            'content_copy':
            Count(
                'copy_from_course', filter=~Q(copy_from_course='')
            ),  # ,filter=~Q(copy_from_course='None')&~Q(copy_from_course='')),
            'not_completed':
            Count(
                'status',
                filter=Q(status__in=[
                    'IN_PROCESS', 'CANCELED', 'APPROVED', 'SUBMITTED', 'LOCKED'
                ])
            ),  #Sum(Case(When(~Q(status='COMPLETED'), then=1),output_field=IntegerField(),)),
            #'total_requests': Sum(''),
            #'multisection':Count(F('additional_sections'),filter=Q(additional_sections__isnull=False)),
            #filter=Q(additional_sections__isnull=True),distinct=True),#/Count('additional_sections', distinct=True)),
        }

        #
        response.context_data['summary'] = list(
            qs.values('course_requested__course_schools__abbreviation'
                      )  #'course_requested','status',)#,'course_requested')
            .annotate(**metrics)
            #.annotate(multisection=Case(When(mutlisection_count__gt=0,then=Value(1)),default=Value(0),output_field=IntegerField()))
            .order_by('course_requested__course_schools__abbreviation')
            #.annotate(multisection=Count('additional_sections',filter=Q(additional_sections__isnull=False),distinct=True))
        )

        ##### LAST ROW  #####
        #metrics = metrics.pop('multisection')

        response.context_data['summary_total'] = dict(qs.aggregate(**metrics))

        ##### BAR CHART #####
        period = get_next_in_date_hierarchy(
            request,
            self.date_hierarchy,
        )
        response.context_data['period'] = period
        summary_over_time = qs.annotate(period=Trunc(
            'created',
            period,
            output_field=DateTimeField(),
        ), ).values('period').annotate(
            total=Count('course_requested')).order_by('period')

        summary_range = summary_over_time.aggregate(
            low=Min('total'),
            high=Max('total'),
        )
        high = summary_range.get('high', 0)
        low = summary_range.get('low', 0)
        response.context_data['summary_over_time'] = [{
            'period': x['period'],
            'total': x['total'] or 0,
            'pct': \
               ((x['total'] or 0) - low) / (high - low) * 100
               if high > low else 0,
        } for x in summary_over_time]

        return response
Esempio n. 24
0
 def queryset(self, request, queryset):
     if self.value() in ['yes', 'no']:
         logins = Login.objects.filter(team=OuterRef('pk'), stage=OuterRef('status'))
         queryset = queryset.annotate(has_login=Exists(logins))
         queryset = queryset.filter(has_login=self.value() == 'yes')
     return queryset
Esempio n. 25
0
def filter_products_by_collections(qs, collection_pks):
    collection_products = CollectionProduct.objects.filter(
        collection_id__in=collection_pks).values("product_id")
    return qs.filter(
        Exists(collection_products.filter(product_id=OuterRef("pk"))))
    def get(self, request, course_key):
        """
        Returns a gradebook entry/entries (i.e. both course and subsection-level grade data)
        for all users enrolled in a course, or a single user enrolled in a course
        if a `username` parameter is provided.

        Args:
            request: A Django request object.
            course_key: The edx course opaque key of a course object.
        """
        course = get_course_by_id(course_key, depth=None)

        # We fetch the entire course structure up-front, and use this when iterating
        # over users to determine their subsection grades.  We purposely avoid fetching
        # the user-specific course structure for each user, because that is very expensive.
        course_data = CourseData(user=None, course=course)
        graded_subsections = list(grades_context.graded_subsections_for_course(course_data.collected_structure))

        if request.GET.get('username'):
            with self._get_user_or_raise(request, course_key) as grade_user:
                course_grade = CourseGradeFactory().read(grade_user, course)

            entry = self._gradebook_entry(grade_user, course, graded_subsections, course_grade)
            serializer = StudentGradebookEntrySerializer(entry)
            return Response(serializer.data)
        else:
            q_objects = []
            annotations = {}
            if request.GET.get('user_contains'):
                search_term = request.GET.get('user_contains')
                q_objects.append(
                    Q(user__username__icontains=search_term) |
                    Q(programcourseenrollment__program_enrollment__external_user_key__icontains=search_term) |
                    Q(user__email__icontains=search_term)
                )
            if request.GET.get('username_contains'):
                q_objects.append(Q(user__username__icontains=request.GET.get('username_contains')))
            if request.GET.get('cohort_id'):
                cohort = cohorts.get_cohort_by_id(course_key, request.GET.get('cohort_id'))
                if cohort:
                    q_objects.append(Q(user__in=cohort.users.all()))
                else:
                    q_objects.append(Q(user__in=[]))
            if request.GET.get('enrollment_mode'):
                q_objects.append(Q(mode=request.GET.get('enrollment_mode')))
            if request.GET.get('assignment') and (
                    request.GET.get('assignment_grade_max')
                    or request.GET.get('assignment_grade_min')):
                subqueryset = PersistentSubsectionGrade.objects.annotate(
                    effective_grade_percentage=Case(
                        When(override__isnull=False,
                             then=(
                                 F('override__earned_graded_override')
                                 / F('override__possible_graded_override')
                             ) * 100),
                        default=(F('earned_graded') / F('possible_graded')) * 100
                    )
                )
                grade_conditions = {
                    'effective_grade_percentage__range': (
                        request.GET.get('assignment_grade_min', 0),
                        request.GET.get('assignment_grade_max', 100)
                    )
                }
                annotations['selected_assignment_grade_in_range'] = Exists(
                    subqueryset.filter(
                        course_id=OuterRef('course'),
                        user_id=OuterRef('user'),
                        usage_key=UsageKey.from_string(request.GET.get('assignment')),
                        **grade_conditions
                    )
                )
                q_objects.append(Q(selected_assignment_grade_in_range=True))
            if request.GET.get('course_grade_min') or request.GET.get('course_grade_max'):
                grade_conditions = {}
                q_object = Q()
                course_grade_min = request.GET.get('course_grade_min')
                if course_grade_min:
                    course_grade_min = float(request.GET.get('course_grade_min')) / 100
                    grade_conditions['percent_grade__gte'] = course_grade_min

                if request.GET.get('course_grade_max'):
                    course_grade_max = float(request.GET.get('course_grade_max')) / 100
                    grade_conditions['percent_grade__lte'] = course_grade_max

                if not course_grade_min or course_grade_min == 0:
                    subquery_grade_absent = ~Exists(
                        PersistentCourseGrade.objects.filter(
                            course_id=OuterRef('course'),
                            user_id=OuterRef('user_id'),
                        )
                    )

                    annotations['course_grade_absent'] = subquery_grade_absent
                    q_object |= Q(course_grade_absent=True)

                subquery_grade_in_range = Exists(
                    PersistentCourseGrade.objects.filter(
                        course_id=OuterRef('course'),
                        user_id=OuterRef('user_id'),
                        **grade_conditions
                    )
                )
                annotations['course_grade_in_range'] = subquery_grade_in_range
                q_object |= Q(course_grade_in_range=True)

                q_objects.append(q_object)

            entries = []
            related_models = ['user']
            users = self._paginate_users(course_key, q_objects, related_models, annotations=annotations)

            users_counts = self._get_users_counts(course_key, q_objects, annotations=annotations)

            with bulk_gradebook_view_context(course_key, users):
                for user, course_grade, exc in CourseGradeFactory().iter(
                    users, course_key=course_key, collected_block_structure=course_data.collected_structure
                ):
                    if not exc:
                        entry = self._gradebook_entry(user, course, graded_subsections, course_grade)
                        entries.append(entry)

            serializer = StudentGradebookEntrySerializer(entries, many=True)
            return self.get_paginated_response(serializer.data, **users_counts)
Esempio n. 27
0
class OCPTagQueryHandler(TagQueryHandler):
    """Handles tag queries and responses for OCP."""

    provider = Provider.PROVIDER_OCP
    enabled = OCPEnabledTagKeys.objects.filter(key=OuterRef("key"))
    data_sources = [
        {
            "db_table": OCPUsagePodLabelSummary,
            "db_column_period": "report_period__report_period",
            "type": "pod",
            "annotations": {
                "enabled": Exists(enabled)
            },
        },
        {
            "db_table": OCPStorageVolumeLabelSummary,
            "db_column_period": "report_period__report_period",
            "type": "storage",
            "annotations": {
                "enabled": Exists(enabled)
            },
        },
    ]
    TAGS_VALUES_SOURCE = [{
        "db_table":
        OCPTagsValues,
        "fields":
        ["ocpusagepodlabelsummary__key", "ocpstoragevolumelabelsummary__key"]
    }]
    SUPPORTED_FILTERS = TagQueryHandler.SUPPORTED_FILTERS + [
        "project", "enabled", "cluster"
    ]
    FILTER_MAP = deepcopy(TagQueryHandler.FILTER_MAP)
    FILTER_MAP.update({
        "project": {
            "field": "namespace",
            "operation": "icontains"
        },
        "enabled": {
            "field": "enabled",
            "operation": "exact",
            "parameter": True
        },
        "cluster": [
            {
                "field": "report_period__cluster_id",
                "operation": "icontains",
                "composition_key": "cluster_filter"
            },
            {
                "field": "report_period__cluster_alias",
                "operation": "icontains",
                "composition_key": "cluster_filter",
            },
        ],
    })

    def __init__(self, parameters):
        """Establish AWS report query handler.

        Args:
            parameters    (QueryParameters): parameter object for query

        """
        if not hasattr(self, "_mapper"):
            self._mapper = OCPProviderMap(provider=self.provider,
                                          report_type=parameters.report_type)

        if parameters.get_filter("enabled") is None:
            parameters.set_filter(**{"enabled": True})
        # super() needs to be called after _mapper is set
        super().__init__(parameters)
Esempio n. 28
0
 def for_user(self, user):
     # Return a queryset that only returns groups the user has access to
     return Group.objects\
         .filter(Q(Exists(GroupMember.objects.only('id').filter(group=OuterRef('pk'), user=user))) | Q(group_type=Group.OPEN))\
         .filter(is_deleted=False)
Esempio n. 29
0
 def answered(self):
     return self.topic.entries.filter(Exists(Comment.objects.filter(entry=OuterRef("pk"))))
Esempio n. 30
0
def filter_qs_by_attr(qs, request):
    """
    We'll allow to filter the event list using attributes defined in the event meta data
    models in the format ?attr[meta_name]=meta_value
    """
    attrs = {}
    for i, item in enumerate(request.GET.items()):
        k, v = item
        if k.startswith("attr[") and k.endswith("]"):
            attrs[k[5:-1]] = v

    skey = 'filter_qs_by_attr_{}_{}'.format(
        request.organizer.pk,
        request.event.pk if hasattr(request, 'event') else '')
    if request.GET.get('attr_persist'):
        request.session[skey] = attrs
    elif skey in request.session:
        attrs = request.session[skey]

    props = {
        p.name: p
        for p in request.organizer.meta_properties.filter(
            name__in=attrs.keys())
    }

    for i, item in enumerate(attrs.items()):
        attr, v = item
        emv_with_value = EventMetaValue.objects.filter(
            event=OuterRef('event' if qs.model == SubEvent else 'pk'),
            property__name=attr,
            value=v)
        emv_with_any_value = EventMetaValue.objects.filter(
            event=OuterRef('event' if qs.model == SubEvent else 'pk'),
            property__name=attr,
        )
        if qs.model == SubEvent:
            semv_with_value = SubEventMetaValue.objects.filter(
                subevent=OuterRef('pk'), property__name=attr, value=v)
            semv_with_any_value = SubEventMetaValue.objects.filter(
                subevent=OuterRef('pk'),
                property__name=attr,
            )

        prop = props.get(attr)
        if not prop:
            continue
        annotations = {'attr_{}'.format(i): Exists(emv_with_value)}
        if qs.model == SubEvent:
            annotations['attr_{}_sub'.format(i)] = Exists(semv_with_value)
            annotations['attr_{}_sub_any'.format(i)] = Exists(
                semv_with_any_value)
            filters = Q(**{'attr_{}_sub'.format(i): True})
            filters |= Q(
                Q(**{'attr_{}_sub_any'.format(i): False})
                & Q(**{'attr_{}'.format(i): True}))
            if prop.default == v:
                annotations['attr_{}_any'.format(i)] = Exists(
                    emv_with_any_value)
                filters |= Q(
                    Q(**{'attr_{}_sub_any'.format(i): False})
                    & Q(**{'attr_{}_any'.format(i): False}))
        else:
            filters = Q(**{'attr_{}'.format(i): True})
            if prop.default == v:
                annotations['attr_{}_any'.format(i)] = Exists(
                    emv_with_any_value)
                filters |= Q(**{'attr_{}_any'.format(i): False})

        qs = qs.annotate(**annotations).filter(filters)
    return qs