def should_book_an_offer_even_if_physical_offer_capping_is_exeeded(
            self, mocked_redis, app):
        # Given
        product = offers_factories.DigitalProductFactory()
        stock1 = offers_factories.StockFactory(
            price=200,
            offer__type=str(ThingType.AUDIOVISUEL),
            offer__product=product,
        )
        booking = bookings_factories.BookingFactory(stock=stock1)
        user = booking.user
        stock2 = offers_factories.StockFactory(
            price=200,
            offer__type=str(ThingType.AUDIOVISUEL),
            offer__product=product,
        )

        # When
        create_booking_for_user_on_specific_stock_bypassing_capping_limits(
            user.id, stock2.id)

        # Then
        assert Booking.query.filter_by(stockId=stock2.id).one() is not None
        mocked_redis.add_offer_id.assert_called_once_with(
            client=app.redis_client, offer_id=stock2.offer.id)
    def test_no_need_when_booking_is_autovalidated(self):
        # Given
        offer = offers_factories.OfferFactory(
            venue__name="Lieu de l'offreur",
            venue__managingOfferer__name="Théâtre du coin",
            product=offers_factories.DigitalProductFactory(
                name="Super événement", url="http://example.com"),
        )
        digital_stock = offers_factories.StockWithActivationCodesFactory()
        first_activation_code = digital_stock.activationCodes[0]
        booking = bookings_factories.UsedIndividualBookingFactory(
            individualBooking__user__email="*****@*****.**",
            individualBooking__user__firstName="John",
            individualBooking__user__lastName="Doe",
            stock__offer=offer,
            activationCode=first_activation_code,
            dateCreated=datetime(2018, 1, 1),
        )

        # When
        email_data = retrieve_data_for_offerer_booking_recap_email(
            booking.individualBooking)

        # Then
        expected = get_expected_base_email_data(
            booking,
            date="",
            heure="",
            is_event=0,
            is_booking_autovalidated=1,
            must_use_token_for_payment=0,
            offer_type="VOD",
            contremarque=booking.token,
        )
        assert email_data == expected
Ejemplo n.º 3
0
    def test_should_return_thing_data_when_booking_is_on_an_online_offer(self):
        # Given
        stock = offers_factories.ThingStockFactory(
            offer__product=offers_factories.DigitalProductFactory())
        booking = bookings_factories.IndividualBookingFactory(
            stock=stock,
            individualBooking__user__firstName="Georges",
            individualBooking__user__lastName="Georges",
        )

        # When
        mailjet_data = retrieve_data_to_warn_user_after_pro_booking_cancellation(
            booking)

        # Then
        assert mailjet_data == {
            "MJ-TemplateID": 1116690,
            "MJ-TemplateLanguage": True,
            "Vars": {
                "event_date": "",
                "event_hour": "",
                "is_event": 0,
                "is_free_offer": 0,
                "is_online": 1,
                "is_thing": 0,
                "offer_name": booking.stock.offer.name,
                "offer_price": "10.00",
                "offerer_name": booking.offerer.name,
                "user_first_name": "Georges",
                "user_last_name": "Georges",
                "venue_name": booking.venue.name,
            },
        }
Ejemplo n.º 4
0
    def test_should_return_thing_data_when_booking_is_on_an_online_offer(self):
        # Given
        stock = offers_factories.ThingStockFactory(
            offer__product=offers_factories.DigitalProductFactory())
        booking = bookings_factories.BookingFactory(stock=stock)

        # When
        mailjet_data = retrieve_data_to_warn_beneficiary_after_pro_booking_cancellation(
            booking)

        # Then
        assert mailjet_data == {
            "MJ-TemplateID": 1116690,
            "MJ-TemplateLanguage": True,
            "Vars": {
                "can_book_again": 1,
                "event_date": "",
                "event_hour": "",
                "is_event": 0,
                "is_free_offer": 0,
                "is_online": 1,
                "is_thing": 0,
                "offer_name": booking.stock.offer.name,
                "offer_price": "10.00",
                "offerer_name": booking.stock.offer.venue.managingOfferer.name,
                "user_first_name": "Jeanne",
                "venue_name": booking.stock.offer.venue.name,
            },
        }
Ejemplo n.º 5
0
    def test_digital_limit_on_uncapped_type(self):
        beneficiary = self._get_beneficiary()
        product = offers_factories.DigitalProductFactory(type=str(ThingType.OEUVRE_ART))
        offer = offers_factories.OfferFactory(product=product)
        factories.BookingFactory(user=beneficiary, stock__price=190, stock__offer=offer)

        # should not raise because OEUVRE_ART is not capped
        validation.check_expenses_limits(beneficiary, 11, offer)
Ejemplo n.º 6
0
    def test_booking_on_digital_offer_without_activation_stock(self):
        offer = offers_factories.OfferFactory(product=offers_factories.DigitalProductFactory())
        stock = offers_factories.StockFactory(price=10, dnBookedQuantity=5, offer=offer)
        beneficiary = users_factories.BeneficiaryGrant18Factory()

        booking = api.book_offer(beneficiary=beneficiary, stock_id=stock.id, quantity=1)

        assert not booking.isUsed
        assert booking.status is not BookingStatus.USED
Ejemplo n.º 7
0
    def test_success_if_digital_product_and_virtual_venue(self):
        venue = factories.VirtualVenueFactory()
        user_offerer = factories.UserOffererFactory(offerer=venue.managingOfferer)
        product = factories.DigitalProductFactory()

        data = offers_serialize.PostOfferBodyModel(
            venueId=humanize(venue.id),
            productId=humanize(product.id),
        )
        api.create_offer(data, user_offerer.user)  # should not fail
Ejemplo n.º 8
0
 def test_raise_if_booking_was_automatically_used_for_digital_offer_with_activation_code(self):
     offer = offers_factories.OfferFactory(product=offers_factories.DigitalProductFactory())
     digital_stock = offers_factories.StockWithActivationCodesFactory()
     first_activation_code = digital_stock.activationCodes[0]
     booking = booking_factories.UsedIndividualBookingFactory(
         stock__offer=offer, activationCode=first_activation_code
     )
     with pytest.raises(api_errors.ForbiddenError):
         api.mark_as_unused(booking)
     assert booking.isUsed
     assert booking.status is BookingStatus.USED
Ejemplo n.º 9
0
    def test_digital_limit_on_uncapped_type(self):
        beneficiary = self._get_beneficiary()
        product = offers_factories.DigitalProductFactory(
            subcategoryId=subcategories.OEUVRE_ART.id)
        offer = offers_factories.OfferFactory(product=product)
        factories.IndividualBookingFactory(individualBooking__user=beneficiary,
                                           stock__price=190,
                                           stock__offer=offer)

        # should not raise because OEUVRE_ART is not capped
        validation.check_expenses_limits(beneficiary, 11, offer)
Ejemplo n.º 10
0
def create_digital_booking(quantity=1, price=10, user=None, product_type=None):
    user = user or users_factories.UserFactory()
    product_kwargs = {}
    if product_type:
        product_kwargs = {"type": product_type}
    product = offers_factories.DigitalProductFactory(**product_kwargs)
    stock = offers_factories.StockFactory(
        price=price,
        offer=offers_factories.ThingOfferFactory(product=product),
    )
    return bookings_factories.BookingFactory(user=user, stock=stock, quantity=quantity)
Ejemplo n.º 11
0
    def test_fail_if_digital_product_and_physical_venue(self):
        venue = factories.VenueFactory()
        user_offerer = factories.UserOffererFactory(offerer=venue.managingOfferer)
        product = factories.DigitalProductFactory()

        data = offers_serialize.PostOfferBodyModel(
            venueId=humanize(venue.id),
            productId=humanize(product.id),
        )
        with pytest.raises(api_errors.ApiErrors) as error:
            api.create_offer(data, user_offerer.user)
        err = 'Une offre numérique doit obligatoirement être associée au lieu "Offre numérique"'
        assert error.value.errors["venue"] == [err]
Ejemplo n.º 12
0
    def test_with_virtual_offer(self):
        # Given
        author = users_factories.ProFactory()
        offer = offers_factories.EventOfferFactory(
            author=author,
            product=offers_factories.DigitalProductFactory(
                name="Les lièvres pas malins"),
            venue=offers_factories.VirtualVenueFactory(),
        )

        # When
        email = make_offer_creation_notification_email(offer)

        # Then
        assert email[
            "Subject"] == "[Création d’offre - numérique] Les lièvres pas malins"
    def test_relevancy(self):
        rule = reimbursement.DigitalThingsReimbursement()

        assert rule.is_relevant(create_digital_booking())
        digital_book_booking = create_digital_booking(
            product_subcategory_id=subcategories.LIVRE_PAPIER.id)
        assert not rule.is_relevant(digital_book_booking)
        cinema_card_booking = create_digital_booking(
            product_subcategory_id=subcategories.CINE_VENTE_DISTANCE.id)
        assert not rule.is_relevant(cinema_card_booking)
        assert not rule.is_relevant(create_non_digital_thing_booking())
        assert not rule.is_relevant(create_event_booking())
        assert not rule.is_relevant(
            bookings_factories.EducationalBookingFactory(
                stock__offer__product=offers_factories.DigitalProductFactory())
        )
Ejemplo n.º 14
0
    def test_digital_limit(self):
        beneficiary = self._get_beneficiary()
        product = offers_factories.DigitalProductFactory(type=str(ThingType.AUDIOVISUEL))
        offer = offers_factories.OfferFactory(product=product)
        factories.BookingFactory(
            user=beneficiary,
            stock__price=90,
            stock__offer=offer,
        )

        validation.check_expenses_limits(beneficiary, 10, offer)  # should not raise

        with pytest.raises(exceptions.DigitalExpenseLimitHasBeenReached) as error:
            validation.check_expenses_limits(beneficiary, 11, offer)
        assert error.value.errors["global"] == [
            "Le plafond de 100 € pour les offres numériques ne vous permet pas de réserver cette offre."
        ]
def create_digital_booking(quantity=1,
                           price=10,
                           user=None,
                           product_subcategory_id=None):
    user = user or users_factories.BeneficiaryGrant18Factory()
    product_kwargs = {}
    if product_subcategory_id:
        product_kwargs = {"subcategoryId": product_subcategory_id}
    product = offers_factories.DigitalProductFactory(**product_kwargs)
    stock = offers_factories.StockFactory(
        price=price,
        offer=offers_factories.ThingOfferFactory(product=product),
    )
    return bookings_factories.UsedBookingFactory(user=user,
                                                 stock=stock,
                                                 quantity=quantity,
                                                 dateUsed=datetime.now())
Ejemplo n.º 16
0
    def test_hide_cancellation_policy_on_bookings_with_activation_code(self):
        offer = offers_factories.OfferFactory(
            venue__name="Lieu de l'offreur",
            venue__managingOfferer__name="Théâtre du coin",
            product=offers_factories.DigitalProductFactory(name="Super offre numérique", url="http://example.com"),
        )
        digital_stock = offers_factories.StockWithActivationCodesFactory()
        first_activation_code = digital_stock.activationCodes[0]
        booking = bookings_factories.UsedIndividualBookingFactory(
            stock__offer=offer,
            activationCode=first_activation_code,
            dateCreated=datetime(2018, 1, 1),
        )

        mediation = offers_factories.MediationFactory(offer=booking.stock.offer)

        email_data = retrieve_data_for_beneficiary_booking_confirmation_email(booking.individualBooking)
        expected = get_expected_base_email_data(
            booking,
            mediation,
            all_but_not_virtual_thing=0,
            all_things_not_virtual_thing=0,
            event_date="",
            event_hour="",
            is_event=0,
            is_single_event=0,
            offer_name="Super offre numérique",
            offer_price="10.00 €",
            offer_token=booking.activationCode.code,
            can_expire=0,
            is_digital_booking_with_activation_code_and_no_expiration_date=1,
            has_offer_url=1,
            digital_offer_url="http://example.com",
            user_first_name="Jeanne",
            venue_address="1 boulevard Poissonnière",
            venue_city="Paris",
            venue_postal_code="75000",
            booking_date="1 janvier 2018",
            booking_hour="01h00",
            expiration_delay="",
        )

        assert email_data == expected
Ejemplo n.º 17
0
    def test_digital_limit(self):
        beneficiary = self._get_beneficiary()
        product = offers_factories.DigitalProductFactory(
            subcategoryId=subcategories.VOD.id)
        offer = offers_factories.OfferFactory(product=product)
        factories.IndividualBookingFactory(
            individualBooking__user=beneficiary,
            stock__price=190,
            stock__offer=offer,
        )

        validation.check_expenses_limits(beneficiary, 10,
                                         offer)  # should not raise

        with pytest.raises(
                exceptions.DigitalExpenseLimitHasBeenReached) as error:
            validation.check_expenses_limits(beneficiary, 11, offer)
        assert error.value.errors["global"] == [
            "Le plafond de 200 € pour les offres numériques ne vous permet pas de réserver cette offre."
        ]
Ejemplo n.º 18
0
 def test_mark_as_unused_digital_offer(self):
     offer = offers_factories.OfferFactory(product=offers_factories.DigitalProductFactory())
     booking = booking_factories.UsedIndividualBookingFactory(stock__offer=offer)
     api.mark_as_unused(booking)
     assert not booking.isUsed
     assert booking.status is not BookingStatus.USED