Exemple #1
0
    def annotate_nested_names(cls, qs: QuerySet):
        """
        Include the nested name for each item in the queryset. Assumes the queryset is correctly
        ordered; uses the `name` field and saves to `nested_name` field.

        Args:
            qs (QuerySet): An ordered queryset, like from `get_assessment_qs`
        """
        # preconditions; check that we have a name attribute and we don't have a nested_name attribute
        el = qs.first()
        assert hasattr(el, "name")
        assert not hasattr(el, "nested_name")

        last_depth = -math.inf
        names: List[str] = []
        for node in qs:

            if node.depth == 1:
                node.nested_name = node.name
            else:
                if node.depth > last_depth:
                    pass
                else:
                    for i in range(last_depth - node.depth + 1):
                        names.pop()

                names.append(node.name)
                node.nested_name = "|".join(names)

            last_depth = node.depth
def test_professional_closed_period_manager_get_get_between_dates(
        professional_closed_periods: QuerySet):
    """Should return slots between the dates."""
    professional = professional_closed_periods.first().professional
    manager = ProfessionalClosedPeriod.objects
    start = arrow.utcnow().replace(
        hour=0,
        minute=0,
        second=0,
        microsecond=0,
    )
    end = start.shift(days=10)

    result = manager.get_between_dates(start, end, professional)
    assert result.count() == 2
    assert result.first().professional == professional

    assert manager.get_between_dates(
        start.shift(days=6),
        start.shift(days=15),
        professional,
    ).count() == 1

    assert manager.get_between_dates(
        start.shift(days=20),
        start.shift(days=30),
        professional,
    ).count() == 0
def test_service_closed_period_manager_get_get_between_dates(
        service_closed_periods: QuerySet):
    """Should return slots between the dates."""
    service = service_closed_periods.first().service
    manager = ServiceClosedPeriod.objects
    start = arrow.utcnow().replace(
        hour=0,
        minute=0,
        second=0,
        microsecond=0,
    )
    end = start.shift(days=10)

    result = manager.get_between_dates(start, end, service)
    assert result.count() == 2
    assert result.first().service == service

    assert manager.get_between_dates(
        start.shift(days=6),
        start.shift(days=15),
        service,
    ).count() == 1

    assert manager.get_between_dates(
        start.shift(days=20),
        start.shift(days=30),
        service,
    ).count() == 0
def test_validate_service_price(services: QuerySet):
    """Should validate a service price."""
    price = services.first().price
    price.is_price_fixed = True
    price.price = None
    with pytest.raises(ValidationError):
        validate_service_price(price)

    price.price = Money(0.34, EUR)
    validate_service_price(price)

    price.is_price_fixed = False
    price.start_price = None
    with pytest.raises(ValidationError):
        validate_service_price(price)

    price.start_price = Money(0.34, EUR)
    price.end_price = Money(1.5, USD)
    with pytest.raises(ValidationError):
        validate_service_price(price)

    price.start_price = Money(2.5, USD)
    with pytest.raises(ValidationError):
        validate_service_price(price)

    price.start_price = Money(0.5, USD)
    validate_service_price(price)
Exemple #5
0
def test_calculator_calc(services: QuerySet):
    """Should calc the order price."""
    order = Order()
    calc = Calculator()
    assert calc.calc(order) is None

    service = services.first()
    service.price.is_price_fixed = False
    order.service = service

    assert calc.calc(order) is None

    service.price.is_price_fixed = True
    service.price.price = Money(1, "USD")
    service.duration = 10

    now = arrow.utcnow()
    order.start_datetime = now.datetime
    order.end_datetime = now.shift(minutes=10).datetime

    assert calc.calc(order) == service.price.price

    order.start_datetime = now
    order.end_datetime = now.shift(minutes=30)

    assert calc.calc(order) == service.price.price * Decimal(3)
def test_availability_slot_manager_get_get_between_dates(
        availability_slots: QuerySet):
    """Should return slots between the dates."""
    professional = availability_slots.first().professional
    service = availability_slots.exclude(service__isnull=True).first().service
    manager: AvailabilitySlotManager = AvailabilitySlot.objects
    start = arrow.utcnow().replace(
        hour=0,
        minute=0,
        second=0,
        microsecond=0,
    )
    end = start.shift(days=10)

    result = manager.get_between_dates(start, end, professional)
    assert result.count() == 10
    assert result.first().professional == professional

    result = manager.get_between_dates(
        start,
        end,
        service.professional,
        service,
    )
    assert result.count() == 10
    assert result.first().service == service

    end = start.shift(days=100)
    result = manager.get_between_dates(start, end, professional)
    assert result.count() == 61
Exemple #7
0
    def get_budget_stats(qs: QuerySet) -> list:
        if len(qs) == 0:
            return []

        budgets = Budget.objects.filter(
            id__in=set(qs.values_list("budget", flat=True)))
        start_date = qs.last().date
        end_date = qs.first().date
        date_range = (start_date, end_date)

        stats = []
        for budget in budgets:
            budget_stats = {
                "id":
                budget.id,
                "name":
                budget.name,
                "initial_balance":
                budget.balance(Q(date__lt=start_date)),
                "final_balance":
                budget.balance(Q(date__lte=end_date)),
                "income":
                Transaction.objects.filter(
                    budget=budget, date__range=date_range,
                    income=True).aggregate(total=Sum("amount"))["total"] or 0,
                "outcome":
                Transaction.objects.filter(
                    budget=budget, date__range=date_range,
                    income=False).aggregate(total=Sum("amount"))["total"] or 0,
            }
            budget_stats["difference"] = (budget_stats["income"] +
                                          budget_stats["outcome"])
            stats.append(budget_stats)

        return stats
Exemple #8
0
def get_indexable_content(results: QuerySet):
    if not results:
        return []
    # Only use the first method available
    res, method = results.first(), results.first().extractor
    if method not in ('readability', 'singlefile', 'dom', 'wget'):
        return []
    # This should come from a plugin interface

    if method == 'readability':
        return get_file_result_content(res, 'content.txt')
    elif method == 'singlefile':
        return get_file_result_content(res, '')
    elif method == 'dom':
        return get_file_result_content(res,'',use_pwd=True)
    elif method == 'wget':
        return get_file_result_content(res,'',use_pwd=True)
def test_service_schedule_manager_get_by_days(service_schedules: QuerySet):
    """Should return schedules combined by weekdays."""
    service = service_schedules.first().service
    schedules = ServiceSchedule.objects.get_by_days(service)
    assert len(schedules[0]) == 2
    assert len(schedules[6]) == 0
    for schedule in schedules[1]:
        assert schedule.day_of_week == 1
def test_professional_schedule_manager_get_by_days(
        professional_schedules: QuerySet):
    """Should return schedules combined by weekdays."""
    professional = professional_schedules.first().professional
    schedules = ProfessionalSchedule.objects.get_by_days(professional)
    assert len(schedules[0]) == 2
    assert len(schedules[6]) == 0
    for schedule in schedules[1]:
        assert schedule.day_of_week == 1
def test_availability_slot_manager_get_overlapping_entries(
        availability_slots: QuerySet):
    """Should return overlapping slots."""
    manager: AvailabilitySlotManager = AvailabilitySlot.objects
    slot = availability_slots.first()
    assert not manager.get_overlapping_entries(slot).count()
    slot.start_datetime = arrow.utcnow().datetime
    slot.end_datetime = arrow.utcnow().shift(days=10).datetime
    assert manager.get_overlapping_entries(slot).count()
def test_service_schedule_manager_get_overlapping_entries(
        service_schedules: QuerySet):
    """Should return overlapping schedules."""
    manager = ServiceSchedule.objects
    schedule = service_schedules.first()
    assert not manager.get_overlapping_entries(schedule).count()
    schedule.start_time = time(3)
    schedule.end_time = time(23)
    assert manager.get_overlapping_entries(schedule).count()
Exemple #13
0
 def add_users(self, users_qs: QuerySet) -> None:
     assert isinstance(users_qs.first(),
                       User), f"{users_qs.first()} is given"
     if users_qs.exists():
         not_added_users_id_qs = users_qs.exclude(
             id__in=self.users.values_list("id", flat=True)).values("id")
         UserTeam.objects.bulk_create([
             UserTeam(user_id=user_id["id"], team_id=self.id)
             for user_id in list(not_added_users_id_qs)
         ])
Exemple #14
0
def test_availability_slot_admin_list_filter(
    professionals: QuerySet,
    admin_client: Client,
):
    """Should set the professional filter."""
    response = admin_client.get(
        reverse("admin:schedule_availabilityslot_changelist"))
    assert response.status_code == 200
    assert response.wsgi_request.GET.get(
        "professional__pk__exact") == professionals.first().pk
def test_schedule_save(professionals: QuerySet):
    """Should set a timezone during saving."""
    schedule = ProfessionalSchedule()
    schedule.professional = professionals.first()
    schedule.day_of_week = 0  # type: ignore
    schedule.start_time = arrow.utcnow().datetime
    schedule.end_time = arrow.utcnow().shift(days=1).datetime
    schedule.save()

    assert schedule.timezone == get_current_timezone()
Exemple #16
0
def test_order_save(user: User, services: QuerySet, mocker: MockFixture):
    """Should run the filler."""
    order = Order()
    order.validators = []
    order.service = services.first()
    order.client = user
    order.start_datetime = arrow.utcnow().shift(hours=2).datetime
    order.end_datetime = arrow.utcnow().shift(hours=4).datetime
    order.filler = mocker.MagicMock()
    order.save()
    order.filler.assert_called_once()
def test_availability_slot_save(services: QuerySet, professionals: QuerySet):
    """Should set a professional during saving."""
    service = services.first()
    slot = AvailabilitySlot()
    slot.service = service
    slot.professional = professionals.exclude(
        pk=service.professional.pk).first()
    slot.start_datetime = arrow.utcnow().datetime
    slot.end_datetime = arrow.utcnow().shift(days=1).datetime
    slot.save()

    assert slot.professional == service.professional
def test_professional_closed_periods_manager_get_overlapping_entries(
        professional_closed_periods: QuerySet):
    """Should return overlapping closed periods."""
    manager = ProfessionalClosedPeriod.objects
    period = professional_closed_periods.first()
    assert not manager.get_overlapping_entries(period).count()
    period.start_datetime = arrow.utcnow().shift(days=+1).datetime
    period.end_datetime = arrow.utcnow().shift(days=+15).datetime
    assert manager.get_overlapping_entries(period).count()

    period.start_datetime = arrow.utcnow().shift(days=+6).datetime
    period.end_datetime = arrow.utcnow().shift(days=+12).datetime
    assert manager.get_overlapping_entries(period).count()
Exemple #19
0
    def add_reference_to_field_on_related_model(cls, qs: QuerySet, **kwargs):
        cls.assert_is_proxy(qs)

        modified_qs = qs.all()

        if qs.order_by('related_model_name').distinct('related_model_name').count() == 1:
            related_model_name = qs.first().related_model_name
            modified_qs = modified_qs.annotate(**{
                key: F('{}__{}'.format(related_model_name, value))
                for key, value in kwargs.items()
            })

        return modified_qs
    def make_accepted(self: "RenewAdmin", request: WSGIRequest,
                      queryset: QuerySet) -> None:
        """Custom action that update the status of renew to Accepted."""
        renew_request = queryset.first()

        user = renew_request.user

        user.expired_at = renew_request.create_at + timezone.timedelta(
            days=365)

        user.save()

        queryset.update(status="Accepted")
def test_professional_schedule_manager_get_overlapping_entries(
        professional_schedules: QuerySet):
    """Should return overlapping schedules."""
    manager = ProfessionalSchedule.objects
    schedule = professional_schedules.first()
    assert not manager.get_overlapping_entries(schedule).count()
    schedule.start_time = time(3)
    schedule.end_time = time(23)
    assert manager.get_overlapping_entries(schedule).count()

    schedule.start_time = time(16)
    schedule.end_time = time(23)
    assert manager.get_overlapping_entries(schedule).count()
Exemple #22
0
def _daily_count(subjects_queryset: QuerySet):

    dates = []
    men_count = []
    women_count = []

    if subjects_queryset.count():
        subjects_queryset = subjects_queryset.order_by('faces__created_at')
        oldest_subject = subjects_queryset.first()
        newest_subject = subjects_queryset.last()

        lower_timestamp = min(
            [face.created_at for face in oldest_subject.faces.all()])
        upper_timestamp = max(
            [face.created_at for face in newest_subject.faces.all()])

        lower_date = timezone.localtime(lower_timestamp).date()
        upper_date = timezone.localtime(upper_timestamp).date()

        curr_date = lower_date
        ind = 0

        while curr_date <= upper_date:
            next_date = curr_date + datetime.timedelta(days=1)

            subjects = subjects_queryset.filter(
                faces__created_at__date__gte=curr_date,
                faces__created_at__date__lt=next_date)
            men_count.append(
                len(
                    set([
                        subject.id for subject in subjects
                        if subject.pred_sex == Subject.SEX_MAN
                    ])))
            women_count.append(
                len(
                    set([
                        subject.id for subject in subjects
                        if subject.pred_sex == Subject.SEX_WOMAN
                    ])))

            dates.append(str(curr_date))
            curr_date = next_date
            ind += 1

    return {
        'dates': dates,
        'men_count': men_count,
        'women_count': women_count,
    }
Exemple #23
0
def test_closed_periods_restriction_get_closed_periods_for_slot(
    professional_closed_periods: QuerySet,
    service_closed_periods: QuerySet,
):
    """Should lazy load closed periods for the slot."""
    professional = professional_closed_periods.first().professional
    service = service_closed_periods.first().service
    service.is_base_schedule = False

    slot = AvailabilitySlot()
    slot.professional = professional
    request = Request()
    start = arrow.utcnow().replace(
        hour=0,
        minute=0,
        second=0,
        microsecond=0,
    )
    request.start_datetime = start
    request.end_datetime = start.shift(days=20)
    restriction = ClosedPeriodsRestriction()
    restriction.set_request(request)

    assert restriction.professionals_periods is None
    assert restriction.service_periods is None

    result = restriction._get_closed_periods_for_slot(slot)
    assert len(result) == 2
    assert isinstance(result[0], ProfessionalClosedPeriod)
    assert result == restriction.professionals_periods
    assert restriction.service_periods is None

    slot.service = service
    assert len(result) == 2
    result = restriction._get_closed_periods_for_slot(slot)
    assert isinstance(result[0], ServiceClosedPeriod)
    assert result == restriction.service_periods
Exemple #24
0
    def add_reference_to_field_on_related_model(cls, qs: QuerySet, **kwargs):
        cls.assert_is_proxy(qs)

        modified_qs = qs.all()

        if qs.order_by('related_model_name').distinct(
                'related_model_name').count() == 1:
            related_model_name = qs.first().related_model_name
            modified_qs = modified_qs.annotate(
                **{
                    key: F('{}__{}'.format(related_model_name, value))
                    for key, value in kwargs.items()
                })

        return modified_qs
def test_order_auto_filler_set_end_datetime(services: QuerySet):
    """Should set the order end."""
    service = services.first()
    service.duration = 60
    now = arrow.utcnow()
    order = Order()
    order.start_datetime = now.datetime
    order.service = service
    OrderAutoFiller(order)._set_end_datetime()

    assert order.end_datetime == now.shift(minutes=60).datetime

    end = now.shift(days=2).datetime
    order.end_datetime = end
    OrderAutoFiller(order)._set_end_datetime()
    assert order.end_datetime == end
Exemple #26
0
    def get_tag_stats(qs: QuerySet) -> list:
        stats = []
        if len(qs) == 0:
            return stats

        tags = Tag.objects.filter(user=qs.first().budget.user)
        for tag in tags:
            transactions_with_tag = qs.filter(tags=tag)
            if len(transactions_with_tag) == 0:
                continue
            total = transactions_with_tag.aggregate(
                total=Sum("amount"))["total"]
            stats.append({"name": tag.name, "total": total})

        stats.sort(key=operator.itemgetter("total"), reverse=True)
        return stats
Exemple #27
0
def test_availability_slot_admin_weekday(professionals: QuerySet):
    """Should return a weekday for an object."""
    slot = AvailabilitySlot()
    slot.professional = professionals.first()
    now = arrow.utcnow()
    tomorrow = now.shift(days=1)
    slot.start_datetime = now.datetime
    slot.end_datetime = now.shift(hours=1).datetime
    admin = AvailabilitySlotAdmin(
        model=AvailabilitySlot,
        admin_site=AdminSite(),
    )
    assert admin.weekday(slot) == now.format("dddd")
    slot.end_datetime = tomorrow.datetime

    assert admin.weekday(
        slot) == f"{now.format('dddd')} - {tomorrow.format('dddd')}"
Exemple #28
0
def test_order_restriction_get_orders(orders: QuerySet):
    """Should return the orders."""
    order = orders.first()
    restriction = OrderRestriction()
    request = Request()
    request.start_datetime = arrow.utcnow()
    request.end_datetime = arrow.utcnow().shift(days=2)
    request.professional = order.service.professional
    request.service = order.service

    result = restriction.set_request(request)._get_orders()
    assert len(result) == 1

    request.service = None
    restriction.orders = None
    result = restriction.set_request(request)._get_orders()
    assert len(result) == 2
def test_order_auto_filler_set_status(services: QuerySet):
    """Should set the order status."""
    service = services.first()
    service.is_auto_order_confirmation = False
    order = Order()
    order.service = service
    OrderAutoFiller(order)._set_status()

    assert order.status == order.STATUS_NOT_CONFIRMED

    service.is_auto_order_confirmation = True
    OrderAutoFiller(order)._set_status()
    assert order.status == order.STATUS_CONFIRMED

    order.pk = 1
    order.status = order.STATUS_PAID
    OrderAutoFiller(order)._set_status()

    assert order.status == order.STATUS_PAID
Exemple #30
0
def attribute_class_filter(queryset: QuerySet,
                           user: User = None) -> Tuple[QuerySet, QuerySet]:

    if not user:
        return queryset, []

    # Get all of the classes that we aren't in.
    restricted_attribute_classes = AttributeClass.objects.exclude(users=user)
    attribute_class_queries = {
        "ExportRun": {
            "data_provider_task_records__provider__attribute_class__in":
            restricted_attribute_classes
        },
        "RunZipFile": {
            "data_provider_task_records__provider__attribute_class__in":
            restricted_attribute_classes
        },
        "Job": {
            "data_provider_tasks__provider__attribute_class__in":
            restricted_attribute_classes
        },
        "DataProvider": {
            "attribute_class__in": restricted_attribute_classes
        },
        "DataProviderTask": {
            "provider__attribute_class__in": restricted_attribute_classes
        },
        "DataProviderTaskRecord": {
            "provider__attribute_class__in": restricted_attribute_classes
        },
    }
    item = queryset.first()
    attribute_class_query = {}

    if item:
        # Get all of the objects that don't include attribute classes that we aren't in.
        attribute_class_query = attribute_class_queries.get(
            type(item).__name__, {})
    filtered = queryset.filter(**attribute_class_query).distinct()
    queryset = queryset.exclude(**attribute_class_query).distinct()
    return queryset, filtered
Exemple #31
0
def _check_auction_post_request_cash_requirements(auction: Auction,
                                                  user_query: QuerySet,
                                                  bid_value: int) -> Tuple:
    """
    Check if auction post request requirements are fulfilled, but focus only on cash requirements.

    Requirements:

        - user must have enough cash for bid
        - bid must be greater than last bid value and auction starting price

    :param auction: aimed auction
    :param user_query: query of users with special uuid
    :param bid_value: value of new bid (try)
    :return: response status and information about occurred error
    """
    data, status = {}, 0
    user = user_query.first()
    # check user cash in wallet
    if user.cash < bid_value:
        data["summary"] = "User has not enough cash for this bet."
        data["userCash"] = user.cash
        data["bidValue"] = bid_value
        data["errorMessage"] = "User has less cash than minimal bid value."
        return data, 400

    last_bid = auction.last_bid_value
    # check bid value correctness
    if (last_bid is not None
            and bid_value <= last_bid) or bid_value <= auction.starting_price:
        data["summary"] = "Wrong bid value."
        data["auctionStartingPrice"] = auction.starting_price
        data["auctionLastBidValue"] = auction.last_bid_value
        data["bidValue"] = bid_value
        data[
            "errorMessage"] = "Bid must be greater than starting price and last bid value."
        return data, 400

    return data, status