예제 #1
0
def check_expenses_limits(user: User, requested_amount: Decimal, offer: Offer) -> None:
    """Raise an error if the requested amount would exceed the user's
    expense limits.
    """
    domains_credit = get_domains_credit(user)
    deposit = user.deposit
    if not domains_credit or not deposit:
        raise exceptions.UserHasInsufficientFunds()

    if requested_amount > domains_credit.all.remaining:
        raise exceptions.UserHasInsufficientFunds()

    if (
        domains_credit.digital
        and deposit.specific_caps.digital_cap_applies(offer)
        and requested_amount > domains_credit.digital.remaining
    ):
        raise exceptions.DigitalExpenseLimitHasBeenReached(domains_credit.digital.initial)

    if (
        domains_credit.physical
        and deposit.specific_caps.physical_cap_applies(offer)
        and requested_amount > domains_credit.physical.remaining
    ):
        raise exceptions.PhysicalExpenseLimitHasBeenReached(domains_credit.physical.initial)
예제 #2
0
 def from_orm(cls, user: User):  # type: ignore
     user.show_eligible_card = cls._show_eligible_card(user)
     user.subscriptions = user.get_notification_subscriptions()
     user.domains_credit = get_domains_credit(user)
     user.booked_offers = cls._get_booked_offers(user)
     user.next_beneficiary_validation_step = get_next_beneficiary_validation_step(
         user)
     result = super().from_orm(user)
     result.subscriptionMessage = SubscriptionMessage.from_model(
         subscription_api.get_latest_subscription_message(user))
     # FIXME: (Lixxday) Remove after isBeneficiary column has been deleted
     result.isBeneficiary = user.is_beneficiary
     return result
예제 #3
0
def get_user_attributes(user: User) -> UserAttributes:
    from pcapi.core.users.api import get_domains_credit

    is_pro_user = user.has_pro_role or db.session.query(
        UserOfferer.query.filter_by(userId=user.id).exists()).scalar()
    user_bookings: List[Booking] = _get_user_bookings(
        user) if not is_pro_user else []
    last_favorite = (Favorite.query.filter_by(userId=user.id).order_by(
        Favorite.id.desc()).first() if not is_pro_user else None)
    domains_credit = get_domains_credit(
        user, user_bookings) if not is_pro_user else None
    booking_categories, booking_subcategories = _get_bookings_categories_and_subcategories(
        user_bookings)

    return UserAttributes(
        booking_categories=booking_categories,
        booking_count=len(user_bookings),
        booking_subcategories=booking_subcategories,
        date_created=user.dateCreated,
        date_of_birth=user.dateOfBirth,
        departement_code=user.departementCode,
        deposit_activation_date=user.deposit_activation_date,
        deposit_expiration_date=user.deposit_expiration_date,
        domains_credit=domains_credit,
        eligibility=user.eligibility,
        first_name=user.firstName,
        has_completed_id_check=user.hasCompletedIdCheck,
        user_id=user.id,
        is_beneficiary=user.has_beneficiary_role,
        is_eligible=user.is_eligible,
        is_email_validated=user.isEmailValidated,
        is_pro=is_pro_user,
        last_booking_date=user_bookings[0].dateCreated
        if user_bookings else None,
        last_favorite_creation_date=last_favorite.dateCreated
        if last_favorite else None,
        last_name=user.lastName,
        last_visit_date=user.lastConnectionDate,
        marketing_email_subscription=user.get_notification_subscriptions(
        ).marketing_email,
        marketing_push_subscription=user.get_notification_subscriptions().
        marketing_push,
        postal_code=user.postalCode,
        products_use_date={
            f"product_{TRACKED_PRODUCT_IDS[booking.stock.offer.productId]}_use":
            booking.dateUsed
            for booking in user_bookings if booking.dateUsed
            and booking.stock.offer.productId in TRACKED_PRODUCT_IDS
        },
    )
def _create_has_booked_some_bookings(bookings_by_name, offers_by_name, user,
                                     user_name):

    for (offer_index, (offer_name,
                       offer)) in enumerate(list(offers_by_name.items())):
        # FIXME (viconnex, 2020-12-22) trying to adapt previous code - not sure of the result and intention
        # FIXME (asaunier, 2021-01-22) UPDATE - We should replace the "ratio" mechanism by a more immutable data
        #  construction. We currently pick among the list of available offers that may change.
        if offer_index % OFFER_WITH_BOOKINGS_RATIO != 0:
            continue
        domains_credit = get_domains_credit(user)
        digital_credit = domains_credit.digital
        all_credit = domains_credit.all

        if digital_credit and digital_credit.remaining < MAX_RATIO_OF_INITIAL_CREDIT * float(
                digital_credit.initial):
            break

        if all_credit.remaining < MAX_RATIO_OF_INITIAL_CREDIT * float(
                all_credit.initial):
            break

        is_activation_offer = offer.product.subcategoryId in (
            subcategories.ACTIVATION_EVENT.id
            or subcategories.ACTIVATION_THING.id)

        stock = choice(offer.stocks)

        if is_activation_offer:
            is_used = True
        else:
            is_used = offer_index % BOOKINGS_USED_REMOVE_MODULO != 0

        if is_used:
            stock.beginningDatetime = datetime.now() - timedelta(days=2)
            stock.bookingLimitDatetime = datetime.now() - timedelta(days=5)
            repository.save(stock)

        booking = IndividualBookingFactory(
            individualBooking__user=user,
            isUsed=is_used,
            status=BookingStatus.USED if is_used else BookingStatus.CONFIRMED,
            stock=stock,
            dateUsed=datetime.now() - timedelta(days=2) if is_used else None,
        )
        booking_name = "{} / {} / {}".format(offer_name, user_name,
                                             booking.token)
        bookings_by_name[booking_name] = booking
예제 #5
0
 def from_orm(cls, user: User):  # type: ignore
     user.pk = user.id
     user.domainsCredit = get_domains_credit(user)
     result = super().from_orm(user)
     result.isBeneficiary = user.is_beneficiary
     return result