示例#1
0
    def test_should_return_event_data_when_booking_is_an_event(
            self, mock_format_environment_for_email):
        # Given
        booking = factories.BookingFactory(
            user=UserFactory(email="*****@*****.**", firstName="Fabien"),
            isCancelled=True,
            stock=EventStockFactory(
                price=10.2,
                beginningDatetime=datetime.utcnow(),
                offer__name="Test event name",
                offer__id=123456,
            ),
        )

        # When
        email_data = make_beneficiary_booking_cancellation_email_data(booking)

        # Then
        assert email_data == {
            "FromEmail": "*****@*****.**",
            "Mj-TemplateID": 1091464,
            "Mj-TemplateLanguage": True,
            "To": "*****@*****.**",
            "Vars": {
                "env": "-testing",
                "event_date": "26 novembre",
                "event_hour": "19h29",
                "is_event": 1,
                "is_free_offer": 0,
                "offer_id": "AHREA",
                "offer_name": "Test event name",
                "offer_price": "10.20",
                "user_first_name": "Fabien",
            },
        }
    def test_should_return_event_data_when_booking_is_an_event(self):
        # Given
        booking = factories.CancelledIndividualBookingFactory(
            individualBooking__user=BeneficiaryGrant18Factory(
                email="*****@*****.**", firstName="Fabien"),
            stock=EventStockFactory(
                price=10.2,
                beginningDatetime=datetime.utcnow(),
                offer__name="Test event name",
                offer__id=123456,
            ),
        )

        # When
        email_data = make_beneficiary_booking_cancellation_email_data(
            booking.individualBooking)

        # Then
        assert email_data == {
            "Mj-TemplateID": 1091464,
            "Mj-TemplateLanguage": True,
            "Vars": {
                "can_book_again": 1,
                "event_date": "26 novembre 2019",
                "event_hour": "19h29",
                "is_event": 1,
                "is_free_offer": 0,
                "offer_id": "AHREA",
                "offer_name": "Test event name",
                "offer_price": "10.20",
                "user_first_name": "Fabien",
            },
        }
示例#3
0
    def test_should_deactivate_thing_offers_that_are_higher_than_300e_and_non_educational(
            self):
        # Given
        ThingStockFactory(price=305)
        ThingStockFactory(price=315)
        ThingStockFactory(price=103)
        ThingStockFactory(price=300)
        educational_offer = EducationalThingOfferFactory()
        ThingStockFactory(offer=educational_offer, price=376)
        EventStockFactory(price=310)
        EventStockFactory(price=297)

        # When
        deactivate_300e_thing_offers()

        # Then
        deactivated_offers = Offer.query.filter_by(isActive=False).all()
        assert len(deactivated_offers) == 2
示例#4
0
    def test_should_not_return_activation_bookings(self, app):
        # Given
        beneficiary = BeneficiaryGrant18Factory()
        offer1 = EventOfferFactory(subcategoryId=subcategories.ACTIVATION_THING.id)
        offer2 = EventOfferFactory(subcategoryId=subcategories.ACTIVATION_THING.id)
        offer3 = EventOfferFactory(subcategoryId=subcategories.SUPPORT_PHYSIQUE_FILM.id)
        stock1 = EventStockFactory(offer=offer1)
        stock2 = EventStockFactory(offer=offer2)
        stock3 = EventStockFactory(offer=offer3)
        booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock1)
        booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock2)
        booking3 = booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary, stock=stock3)

        # When
        result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id)

        # Then
        assert len(result.bookings) == 1
        assert result.bookings[0].id == booking3.id
    def test_get_expired_offer(self, app):
        stock = EventStockFactory(beginningDatetime=datetime.utcnow() -
                                  timedelta(days=1))

        offer_id = stock.offer.id
        with assert_num_queries(1):
            response = TestClient(
                app.test_client()).get(f"/native/v1/offer/{offer_id}")

        assert response.json["isExpired"]
def test_pc_send_tomorrow_events_notifications_only_to_individual_bookings_users(
):
    """
    Test that each stock that is linked to an offer that occurs tomorrow and
    creates a job that will send a notification to all of the stock's users
    with a valid (not cancelled) booking, for individual bookings only.
    """
    tomorrow = datetime.now() + timedelta(days=1)
    stock_tomorrow = EventStockFactory(beginningDatetime=tomorrow,
                                       offer__name="my_offer")

    begin = datetime.now() + timedelta(days=7)
    stock_next_week = EventStockFactory(beginningDatetime=begin)

    bookings_tomorrow = IndividualBookingFactory.create_batch(
        2, stock=stock_tomorrow, isCancelled=False)
    BookingFactory.create_batch(2,
                                stock=stock_tomorrow,
                                isCancelled=True,
                                status=BookingStatus.CANCELLED)
    BookingFactory.create_batch(2, stock=stock_next_week, isCancelled=False)
    EducationalBookingFactory.create_batch(2,
                                           stock=stock_tomorrow,
                                           isCancelled=False)

    pc_send_tomorrow_events_notifications()

    assert len(testing.requests) == 1
    assert all(data["message"]["title"] == "my_offer, c'est demain !"
               for data in testing.requests)

    user_ids = set()
    for data in testing.requests:
        for user_id in data["user_ids"]:
            user_ids.add(user_id)

    expected_user_ids = {
        booking.individualBooking.userId
        for booking in bookings_tomorrow
    }
    assert user_ids == expected_user_ids
示例#7
0
    def test_should_return_is_free_offer_when_offer_price_equals_to_zero(self):
        # Given
        booking = factories.BookingFactory(
            isCancelled=True,
            stock=EventStockFactory(price=0, ),
        )

        # When
        email_data = make_beneficiary_booking_cancellation_email_data(booking)

        # Then
        assert email_data["Vars"]["is_free_offer"] == 1
示例#8
0
    def should_return_bookings(self, app):
        # Given
        now = datetime.utcnow()
        two_days = now + timedelta(days=2, hours=10)
        two_days_bis = now + timedelta(days=2, hours=20)
        three_days = now + timedelta(days=3)

        user = UserFactory()

        booking1 = factories.BookingFactory(
            user=user,
            stock=EventStockFactory(
                beginningDatetime=three_days,
                bookingLimitDatetime=now,
            ),
        )
        booking2 = factories.BookingFactory(
            user=user,
            stock=EventStockFactory(
                beginningDatetime=two_days,
                bookingLimitDatetime=now,
            ),
        )
        booking3 = factories.BookingFactory(
            user=user,
            stock=EventStockFactory(
                beginningDatetime=two_days_bis,
                bookingLimitDatetime=now,
            ),
        )

        # When
        result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(
            beneficiary_id=user.id)

        # Then
        assert len(result.bookings) == 3
        assert set(booking.id for booking in result.bookings) == {
            booking1.id, booking2.id, booking3.id
        }
示例#9
0
    def test_should_return_bookings(self, app):
        # Given
        now = datetime.utcnow()
        two_days = now + timedelta(days=2, hours=10)
        two_days_bis = now + timedelta(days=2, hours=20)
        three_days = now + timedelta(days=3)

        beneficiary = BeneficiaryGrant18Factory()

        booking1 = booking_factories.IndividualBookingFactory(
            individualBooking__user=beneficiary,
            stock=EventStockFactory(
                beginningDatetime=three_days,
                bookingLimitDatetime=now,
            ),
        )
        booking2 = booking_factories.IndividualBookingFactory(
            individualBooking__user=beneficiary,
            stock=EventStockFactory(
                beginningDatetime=two_days,
                bookingLimitDatetime=now,
            ),
        )
        booking3 = booking_factories.IndividualBookingFactory(
            individualBooking__user=beneficiary,
            stock=EventStockFactory(
                beginningDatetime=two_days_bis,
                bookingLimitDatetime=now,
            ),
        )

        # When
        result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id)

        # Then
        assert len(result.bookings) == 3
        assert set(booking.id for booking in result.bookings) == {booking1.id, booking2.id, booking3.id}
示例#10
0
    def test_should_return_bookings_by_beneficiary_id(self, app):
        # Given
        beneficiary_1 = BeneficiaryGrant18Factory()
        beneficiary_2 = BeneficiaryGrant18Factory()
        offer = EventOfferFactory()
        stock = EventStockFactory(offer=offer)
        booking1 = booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary_1, stock=stock)
        booking_factories.IndividualBookingFactory(individualBooking__user=beneficiary_2, stock=stock)

        # When
        result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary_1.id)

        # Then
        assert len(result.bookings) == 1
        assert result.bookings[0].id == booking1.id
示例#11
0
    def test_should_return_only_most_recent_booking_when_two_cancelled_on_same_stock(self, app):
        # Given
        now = datetime.utcnow()
        two_days_ago = now - timedelta(days=2)
        three_days_ago = now - timedelta(days=3)
        beneficiary = BeneficiaryGrant18Factory()
        offer = EventOfferFactory()
        stock = EventStockFactory(offer=offer)
        booking1 = booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=beneficiary, stock=stock, dateCreated=two_days_ago
        )
        booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=beneficiary, stock=stock, dateCreated=three_days_ago
        )

        # When
        result = BeneficiaryBookingsSQLRepository().get_beneficiary_bookings(beneficiary_id=beneficiary.id)

        # Then
        assert len(result.bookings) == 1
        assert result.bookings[0].id == booking1.id
示例#12
0
def save_bookings_recap_sandbox():
    yesterday = datetime.utcnow() - timedelta(days=1)
    today = datetime.utcnow()

    beneficiary1 = BeneficiaryGrant18Factory(publicName="Riri Duck",
                                             firstName="Riri",
                                             lastName="Duck",
                                             email="*****@*****.**")

    beneficiary2 = BeneficiaryGrant18Factory(
        publicName="Fifi Brindacier",
        firstName="Fifi",
        lastName="Brindacier",
        email="*****@*****.**",
    )
    beneficiary3 = BeneficiaryGrant18Factory(
        publicName="LouLou Duck",
        firstName="Loulou",
        lastName="Duck",
        email="*****@*****.**",
    )

    pro = ProFactory(
        publicName="Balthazar Picsou",
        firstName="Balthazar",
        lastName="Picsou",
        email="*****@*****.**",
    )
    offerer = OffererFactory(siren="645389012")
    UserOffererFactory(user=pro, offerer=offerer)
    venue1 = VenueFactory(managingOfferer=offerer,
                          name="Cinéma Le Monde Perdu",
                          siret="64538901265877")
    venue2 = VenueFactory(managingOfferer=offerer,
                          name="Librairie Atlantis",
                          siret="64538901201379")
    venue3 = VenueFactory(managingOfferer=offerer,
                          name="Théatre Mordor",
                          siret="64538954601379")
    venue4_virtual = VenueFactory(managingOfferer=offerer,
                                  name="Un lieu virtuel",
                                  siret=None,
                                  isVirtual=True)

    product1_venue1 = EventProductFactory(
        name="Jurassic Park", subcategoryId=subcategories.SEANCE_CINE.id)
    offer1_venue1 = EventOfferFactory(product=product1_venue1,
                                      venue=venue1,
                                      isDuo=True)
    stock_1_offer1_venue1 = EventStockFactory(offer=offer1_venue1,
                                              beginningDatetime=yesterday,
                                              quantity=None,
                                              price=12.99)

    product2_venue1 = EventProductFactory(
        name="Matrix", subcategoryId=subcategories.SEANCE_CINE.id)

    offer2_venue1 = EventOfferFactory(product=product2_venue1,
                                      venue=venue1,
                                      isDuo=False)
    stock_2_offer2_venue1 = EventStockFactory(offer=offer2_venue1,
                                              beginningDatetime=today,
                                              quantity=None,
                                              price=0)

    product1_venue2 = ThingProductFactory(
        name="Fondation",
        subcategoryId=subcategories.LIVRE_PAPIER.id,
        extraData={"isbn": "9788804119135"})
    offer1_venue2 = ThingOfferFactory(product=product1_venue2, venue=venue2)
    stock_1_offer1_venue2 = ThingStockFactory(offer=offer1_venue2,
                                              quantity=42,
                                              price=9.99)

    product2_venue2 = ThingProductFactory(
        name="Martine à la playa",
        subcategoryId=subcategories.LIVRE_PAPIER.id,
        extraData={"isbn": "9787605639121"},
    )
    offer2_venue2 = ThingOfferFactory(product=product2_venue2, venue=venue2)
    stock_1_offer2_venue2 = ThingStockFactory(offer=offer2_venue2,
                                              quantity=12,
                                              price=49.99)

    product1_venue3 = EventProductFactory(
        name="Danse des haricots",
        subcategoryId=subcategories.SPECTACLE_REPRESENTATION.id)
    offer1_venue3 = EventOfferFactory(product=product1_venue3, venue=venue3)
    stock_1_offer1_venue3 = EventStockFactory(offer=offer1_venue3,
                                              quantity=44,
                                              price=18.50)

    product1_venue4 = ThingProductFactory(
        name="Le livre des haricots",
        subcategoryId=subcategories.LIVRE_PAPIER.id)
    offer1_venue4 = ThingOfferFactory(product=product1_venue4,
                                      venue=venue4_virtual)
    stock_1_offer1_venue4 = ThingStockFactory(offer=offer1_venue4,
                                              quantity=70,
                                              price=10.99)

    IndividualBookingFactory(
        individualBooking__user=beneficiary1,
        stock=stock_1_offer1_venue1,
        dateCreated=datetime(2020, 3, 18, 14, 56, 12, 0),
        isUsed=True,
        dateUsed=datetime(2020, 3, 22, 17, 00, 10, 0),
        quantity=2,
    )

    IndividualBookingFactory(
        individualBooking__user=beneficiary1,
        stock=stock_2_offer2_venue1,
        dateCreated=datetime(2020, 4, 22, 9, 17, 12, 0),
    )

    IndividualBookingFactory(
        individualBooking__user=beneficiary2,
        stock=stock_1_offer1_venue1,
        dateCreated=datetime(2020, 3, 18, 12, 18, 12, 0),
        isUsed=True,
        dateUsed=datetime(2020, 5, 2),
        quantity=2,
    )

    booking2_beneficiary2 = IndividualBookingFactory(
        individualBooking__user=beneficiary2,
        stock=stock_1_offer1_venue2,
        dateCreated=datetime(2020, 4, 12, 14, 31, 12, 0),
        isCancelled=False,
    )

    booking1_beneficiary3 = IndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_2_offer2_venue1,
        dateCreated=datetime(2020, 1, 4, 19, 31, 12, 0),
        isCancelled=False,
        isUsed=True,
        dateUsed=datetime(2020, 1, 4, 23, 00, 10, 0),
        quantity=2,
    )

    booking2_beneficiary3 = IndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_1_offer1_venue2,
        dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0),
        isCancelled=False,
    )

    booking3_beneficiary1 = UsedIndividualBookingFactory(
        individualBooking__user=beneficiary1,
        stock=stock_1_offer1_venue3,
        dateCreated=datetime(2020, 4, 12, 14, 31, 12, 0),
    )

    payment_booking3_beneficiary1 = PaymentFactory(
        booking=booking3_beneficiary1)
    PaymentStatusFactory(payment=payment_booking3_beneficiary1,
                         status=TransactionStatus.PENDING)

    booking3_beneficiary2 = UsedIndividualBookingFactory(
        individualBooking__user=beneficiary2,
        stock=stock_1_offer1_venue3,
        dateCreated=datetime(2020, 4, 12, 19, 31, 12, 0),
        dateUsed=datetime(2020, 4, 22, 17, 00, 10, 0),
    )

    PaymentFactory(booking=booking3_beneficiary2)
    PaymentStatusFactory(payment=payment_booking3_beneficiary1,
                         status=TransactionStatus.SENT)

    booking3_beneficiary3 = UsedIndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_1_offer1_venue3,
        dateCreated=datetime(2020, 4, 12, 22, 9, 12, 0),
    )

    payment_booking3_beneficiary3 = PaymentFactory(
        booking=booking3_beneficiary3)
    PaymentStatusFactory(payment=payment_booking3_beneficiary3,
                         status=TransactionStatus.ERROR)

    UsedIndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_1_offer1_venue2,
        dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0),
    )

    booking5_beneficiary3 = IndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_1_offer1_venue4,
        dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0),
        isCancelled=False,
    )

    booking6_beneficiary3 = UsedIndividualBookingFactory(
        individualBooking__user=beneficiary3,
        stock=stock_1_offer2_venue2,
        dateCreated=datetime(2020, 3, 21, 22, 9, 12, 0),
        dateUsed=datetime(2020, 4, 22, 21, 9, 12, 0),
    )

    payment_booking6_beneficiary3 = PaymentFactory(
        booking=booking6_beneficiary3)
    PaymentStatusFactory(payment=payment_booking6_beneficiary3,
                         status=TransactionStatus.SENT)

    booking7_beneficiary2 = UsedIndividualBookingFactory(
        individualBooking__user=beneficiary2,
        stock=stock_1_offer2_venue2,
        dateCreated=datetime(2020, 4, 21, 22, 6, 12, 0),
        dateUsed=datetime(2020, 4, 22, 22, 9, 12, 0),
    )

    payment_booking7_beneficiary2 = PaymentFactory(
        booking=booking7_beneficiary2)
    PaymentStatusFactory(payment=payment_booking7_beneficiary2,
                         status=TransactionStatus.RETRY)

    UsedIndividualBookingFactory(
        individualBooking__user=beneficiary1,
        stock=stock_1_offer2_venue2,
        dateCreated=datetime(2020, 2, 21, 22, 6, 12, 0),
        dateUsed=datetime(2020, 4, 22, 23, 9, 12, 0),
    )

    payment_booking8_beneficiary1 = PaymentFactory(
        booking=booking7_beneficiary2)
    PaymentStatusFactory(payment=payment_booking8_beneficiary1,
                         status=TransactionStatus.PENDING)

    bookings_to_cancel = [
        booking2_beneficiary2,
        booking1_beneficiary3,
        booking2_beneficiary3,
        booking3_beneficiary2,
        booking5_beneficiary3,
    ]

    for booking in bookings_to_cancel:
        try:
            booking.cancel_booking()
        except (BookingIsAlreadyUsed, BookingIsAlreadyCancelled) as e:
            logger.info(str(e), extra={"booking": booking.id})
    repository.save(*bookings_to_cancel)
示例#13
0
    def test_get_bookings(self, app):
        OFFER_URL = "https://demo.pass/some/path?token={token}&email={email}&offerId={offerId}"
        user = users_factories.BeneficiaryGrant18Factory(email=self.identifier)

        permanent_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            stock__offer__subcategoryId=subcategories.
            TELECHARGEMENT_LIVRE_AUDIO.id,
            dateUsed=datetime(2021, 2, 3),
        )

        event_booking = booking_factories.IndividualBookingFactory(
            individualBooking__user=user,
            stock=EventStockFactory(beginningDatetime=datetime(2021, 3, 14)))

        digital_stock = StockWithActivationCodesFactory()
        first_activation_code = digital_stock.activationCodes[0]
        second_activation_code = digital_stock.activationCodes[1]
        digital_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            stock=digital_stock,
            activationCode=first_activation_code,
        )
        ended_digital_booking = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            displayAsEnded=True,
            stock=digital_stock,
            activationCode=second_activation_code,
        )
        expire_tomorrow = booking_factories.IndividualBookingFactory(
            individualBooking__user=user,
            dateCreated=datetime.now() - timedelta(days=29))
        used_but_in_future = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            dateUsed=datetime(2021, 3, 11),
            stock=StockFactory(beginningDatetime=datetime(2021, 3, 15)),
        )

        cancelled_permanent_booking = booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=user,
            stock__offer__subcategoryId=subcategories.
            TELECHARGEMENT_LIVRE_AUDIO.id,
            cancellation_date=datetime(2021, 3, 10),
        )
        cancelled = booking_factories.CancelledIndividualBookingFactory(
            individualBooking__user=user,
            cancellation_date=datetime(2021, 3, 8))
        used1 = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user, dateUsed=datetime(2021, 3, 1))
        used2 = booking_factories.UsedIndividualBookingFactory(
            individualBooking__user=user,
            displayAsEnded=True,
            dateUsed=datetime(2021, 3, 2),
            stock__offer__url=OFFER_URL,
            cancellation_limit_date=datetime(2021, 3, 2),
        )

        mediation = MediationFactory(id=111,
                                     offer=used2.stock.offer,
                                     thumbCount=1,
                                     credit="street credit")

        access_token = create_access_token(identity=self.identifier)
        test_client = TestClient(app.test_client())
        test_client.auth_header = {"Authorization": f"Bearer {access_token}"}

        # 1: get the user
        # 1: get the bookings
        # 1: get AUTO_ACTIVATE_DIGITAL_BOOKINGS feature
        # 1: rollback
        with assert_num_queries(4):
            response = test_client.get("/native/v1/bookings")

        assert response.status_code == 200
        assert [b["id"] for b in response.json["ongoing_bookings"]] == [
            expire_tomorrow.id,
            event_booking.id,
            used_but_in_future.id,
            digital_booking.id,
            permanent_booking.id,
        ]

        assert response.json["ongoing_bookings"][3]["activationCode"]

        assert [b["id"] for b in response.json["ended_bookings"]] == [
            ended_digital_booking.id,
            cancelled_permanent_booking.id,
            cancelled.id,
            used2.id,
            used1.id,
        ]

        assert response.json["ended_bookings"][3] == {
            "activationCode": None,
            "cancellationDate": None,
            "cancellationReason": None,
            "confirmationDate": "2021-03-02T00:00:00Z",
            "completedUrl":
            f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}",
            "dateUsed": "2021-03-02T00:00:00Z",
            "expirationDate": None,
            "quantity": 1,
            "qrCodeData": None,
            "id": used2.id,
            "stock": {
                "beginningDatetime": None,
                "id": used2.stock.id,
                "offer": {
                    "category": {
                        "categoryType": "Thing",
                        "label": "Support physique (DVD, Blu-ray...)",
                        "name": "FILM",
                    },
                    "subcategoryId": subcategories.SUPPORT_PHYSIQUE_FILM.id,
                    "extraData": None,
                    "id": used2.stock.offer.id,
                    "image": {
                        "credit": "street credit",
                        "url": mediation.thumbUrl
                    },
                    "isDigital": True,
                    "isPermanent": False,
                    "name": used2.stock.offer.name,
                    "url":
                    f"https://demo.pass/some/path?token={used2.token}&[email protected]&offerId={humanize(used2.stock.offer.id)}",
                    "venue": {
                        "city": "Paris",
                        "coordinates": {
                            "latitude": 48.87004,
                            "longitude": 2.3785
                        },
                        "id": used2.venue.id,
                        "name": used2.venue.name,
                        "publicName": used2.venue.publicName,
                    },
                    "withdrawalDetails": None,
                },
            },
            "token": used2.token,
            "totalAmount": 1000,
        }

        for booking in response.json["ongoing_bookings"]:
            assert booking["qrCodeData"] is not None
示例#14
0
    def test_get_event_offer(self, app):
        offer_type = EventType.CINEMA
        extra_data = {
            "author": "mandibule",
            "isbn": "3838",
            "musicSubType": "502",
            "musicType": "501",
            "performer": "interprète",
            "showSubType": "101",
            "showType": "100",
            "stageDirector": "metteur en scène",
            "speaker": "intervenant",
            "visa": "vasi",
        }
        offer = OfferFactory(
            type=str(offer_type),
            isDuo=True,
            description="desk cryption",
            name="l'offre du siècle",
            withdrawalDetails="modalité de retrait",
            extraData=extra_data,
            durationMinutes=33,
            visualDisabilityCompliant=True,
            externalTicketOfficeUrl="https://url.com",
            venue__name="il est venu le temps des names",
        )
        MediationFactory(id=111,
                         offer=offer,
                         thumbCount=1,
                         credit="street credit")

        bookableStock = EventStockFactory(offer=offer, price=12.34)
        notBookableStock = EventStockFactory(
            offer=offer,
            price=45.68,
            beginningDatetime=datetime.utcnow() - timedelta(days=1))

        response = TestClient(
            app.test_client()).get(f"/native/v1/offer/{offer.id}")

        assert response.status_code == 200
        assert response.json == {
            "id":
            offer.id,
            "accessibility": {
                "audioDisability": False,
                "mentalDisability": False,
                "motorDisability": False,
                "visualDisability": True,
            },
            "stocks": [
                {
                    "id": bookableStock.id,
                    "price": 1234,
                    "beginningDatetime": "2020-01-06T00:00:00",
                    "bookingLimitDatetime": "2020-01-05T23:00:00",
                    "cancellationLimitDatetime": "2020-01-03T00:00:00",
                    "isBookable": True,
                },
                {
                    "id": notBookableStock.id,
                    "price": 4568,
                    "isBookable": False,
                    "beginningDatetime": "2019-12-31T00:00:00",
                    "bookingLimitDatetime": "2019-12-30T23:00:00",
                    "cancellationLimitDatetime": "2020-01-01T00:00:00",
                },
            ],
            "category": {
                "categoryType": "Event",
                "label": "Cinéma",
                "name": "CINEMA"
            },
            "description":
            "desk cryption",
            "externalTicketOfficeUrl":
            "https://url.com",
            "extraData": {
                "author": "mandibule",
                "isbn": "3838",
                "durationMinutes": 33,
                "musicSubType": "Acid Jazz",
                "musicType": "Jazz",
                "performer": "interprète",
                "showSubType": "Carnaval",
                "showType": "Arts de la rue",
                "speaker": "intervenant",
                "stageDirector": "metteur en scène",
                "visa": "vasi",
            },
            "image": {
                "url": "http://localhost/storage/thumbs/mediations/N4",
                "credit": "street credit"
            },
            "isActive":
            True,
            "isDuo":
            True,
            "isDigital":
            False,
            "name":
            "l'offre du siècle",
            "venue": {
                "id": offer.venue.id,
                "address": "1 boulevard Poissonnière",
                "city": "Paris",
                "coordinates": {
                    "latitude": 48.87004,
                    "longitude": 2.3785,
                },
                "name": "il est venu le temps des names",
                "offerer": {
                    "name": offer.venue.managingOfferer.name
                },
                "postalCode": "75000",
                "publicName": "il est venu le temps des names",
            },
            "withdrawalDetails":
            "modalité de retrait",
        }
    def test_refuse_prebooking(self, app) -> None:
        redactor = EducationalRedactorFactory(
            civility="M.",
            firstName="Jean",
            lastName="Doudou",
            email="*****@*****.**",
        )
        stock: Stock = EventStockFactory(quantity=200, dnBookedQuantity=0)
        booking = EducationalBookingFactory(
            educationalBooking__educationalRedactor=redactor,
            status=BookingStatus.CONFIRMED,
            stock=stock,
            quantity=20,
        )

        client = TestClient(app.test_client()).with_eac_token()
        response = client.post(
            f"/adage/v1/prebookings/{booking.educationalBookingId}/refuse")

        assert response.status_code == 200

        booking = Booking.query.one()
        stock = booking.stock
        offer = stock.offer
        venue = offer.venue
        educational_booking = booking.educationalBooking
        assert response.json == {
            "address":
            venue.address,
            "beginningDatetime":
            format_into_utc_date(stock.beginningDatetime),
            "cancellationDate":
            "2022-11-17T15:00:00Z",
            "cancellationLimitDate":
            format_into_utc_date(booking.cancellationLimitDate),
            "city":
            venue.city,
            "confirmationDate":
            None,
            "confirmationLimitDate":
            format_into_utc_date(educational_booking.confirmationLimitDate),
            "coordinates": {
                "latitude": float(venue.latitude),
                "longitude": float(venue.longitude),
            },
            "creationDate":
            format_into_utc_date(booking.dateCreated),
            "description":
            offer.description,
            "durationMinutes":
            offer.durationMinutes,
            "expirationDate":
            booking.expirationDate,
            "id":
            educational_booking.id,
            "image":
            None,
            "isDigital":
            offer.isDigital,
            "venueName":
            venue.name,
            "name":
            offer.name,
            "postalCode":
            venue.postalCode,
            "price":
            booking.amount,
            "quantity":
            booking.quantity,
            "redactor": {
                "email": "*****@*****.**",
                "redactorFirstName": "Jean",
                "redactorLastName": "Doudou",
                "redactorCivility": "M.",
            },
            "UAICode":
            educational_booking.educationalInstitution.institutionId,
            "yearId":
            int(educational_booking.educationalYearId),
            "status":
            "REFUSED",
            "venueTimezone":
            venue.timezone,
            "totalAmount":
            booking.total_amount,
            "url":
            offer_webapp_link(offer),
            "withdrawalDetails":
            offer.withdrawalDetails,
        }

        # It should be 0 because on booking factory creation it goes to 20, then on cancellation it goes 20-20
        assert stock.dnBookedQuantity == 0
        assert booking.status == BookingStatus.CANCELLED
        assert booking.cancellationReason == BookingCancellationReasons.REFUSED_BY_INSTITUTE
示例#16
0
    def test_get_event_offer(self, app):
        offer_type = EventType.CINEMA
        extra_data = {
            "author": "mandibule",
            "isbn": "3838",
            "musicSubType": "502",
            "musicType": "501",
            "performer": "interprète",
            "showSubType": "101",
            "showType": "100",
            "stageDirector": "metteur en scène",
            "speaker": "intervenant",
            "visa": "vasi",
        }
        offer = OfferFactory(
            type=str(offer_type),
            isDuo=True,
            withdrawalDetails="modalité de retrait",
            extraData=extra_data,
            durationMinutes=33,
            visualDisabilityCompliant=True,
            externalTicketOfficeUrl="https://url.com",
        )
        mediation = MediationFactory(offer=offer,
                                     thumbCount=1,
                                     credit="street credit")

        bookableStock = EventStockFactory(offer=offer, price=12.34)
        notBookableStock = EventStockFactory(
            offer=offer,
            price=45.68,
            beginningDatetime=datetime.utcnow() - timedelta(days=1))

        response = TestClient(
            app.test_client()).get(f"/native/v1/offer/{offer.id}")

        assert response.status_code == 200
        assert response.json == {
            "id":
            offer.id,
            "accessibility": {
                "audioDisability": None,
                "mentalDisability": None,
                "motorDisability": None,
                "visualDisability": True,
            },
            "stocks": [
                {
                    "id":
                    bookableStock.id,
                    "price":
                    12.34,
                    "beginningDatetime":
                    bookableStock.beginningDatetime.strftime(
                        "%Y-%m-%dT%H:%M:%S.%f"),
                    "bookingLimitDatetime":
                    bookableStock.bookingLimitDatetime.strftime(
                        "%Y-%m-%dT%H:%M:%S.%f"),
                    "isBookable":
                    True,
                },
                {
                    "id":
                    notBookableStock.id,
                    "price":
                    45.68,
                    "isBookable":
                    False,
                    "beginningDatetime":
                    notBookableStock.beginningDatetime.strftime(
                        "%Y-%m-%dT%H:%M:%S.%f"),
                    "bookingLimitDatetime":
                    notBookableStock.bookingLimitDatetime.strftime(
                        "%Y-%m-%dT%H:%M:%S.%f"),
                },
            ],
            "category": {
                "categoryType": "Event",
                "label": "Cinéma",
                "name": "CINEMA"
            },
            "description":
            offer.description,
            "externalTicketOfficeUrl":
            "https://url.com",
            "extraData": {
                "author": "mandibule",
                "isbn": "3838",
                "durationMinutes": 33,
                "musicSubType": "Acid Jazz",
                "musicType": "Jazz",
                "performer": "interprète",
                "showSubType": "Carnaval",
                "showType": "Arts de la rue",
                "speaker": "intervenant",
                "stageDirector": "metteur en scène",
                "visa": "vasi",
            },
            "image": {
                "url": mediation.thumbUrl,
                "credit": mediation.credit
            },
            "isActive":
            True,
            "isDuo":
            True,
            "isDigital":
            offer.isDigital,
            "name":
            offer.name,
            "venue": {
                "id": offer.venue.id,
                "address": offer.venue.address,
                "city": offer.venue.city,
                "coordinates": {
                    "latitude":
                    float(offer.venue.latitude)
                    if offer.venue.latitude else None,
                    "longitude":
                    float(offer.venue.longitude)
                    if offer.venue.longitude else None,
                },
                "name": offer.venue.name,
                "offerer": {
                    "name": offer.venue.managingOfferer.name
                },
                "postalCode": offer.venue.postalCode,
                "publicName": offer.venue.publicName,
            },
            "withdrawalDetails":
            offer.withdrawalDetails,
        }