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)
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
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
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