def cancel_bookings(bookings: list[Booking]) -> None:
    for booking in bookings:
        booking.mark_as_unused_set_confirmed()
    repository.save(*bookings)
Example #2
0
    def test_should_add_objects_when_objects_are_eligible_and_not_already_indexed(
        self,
        mock_build_object,
        mock_check_offer_exists,
        mock_add_objects,
        mock_delete_objects,
        mock_add_to_indexed_offers,
        mock_delete_indexed_offers,
        mock_add_offer_ids_in_error,
        app,
    ):
        # Given
        client = MagicMock()
        client.pipeline = MagicMock()
        client.pipeline.return_value = MagicMock()
        mock_pipeline = client.pipeline()
        mock_pipeline.execute = MagicMock()
        mock_pipeline.reset = MagicMock()
        offerer = create_offerer(is_active=True, validation_token=None)
        venue = create_venue(offerer=offerer, validation_token=None)
        offer1 = create_offer_with_thing_product(venue=venue, is_active=True)
        stock1 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer1,
                              quantity=10)
        offer2 = create_offer_with_thing_product(venue=venue, is_active=True)
        stock2 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer2,
                              quantity=10)
        offer3 = create_offer_with_thing_product(venue=venue, is_active=False)
        stock3 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer3,
                              quantity=10)
        repository.save(stock1, stock2, stock3)
        mock_check_offer_exists.side_effect = [False, False, False]

        # When
        process_eligible_offers(client=client,
                                offer_ids=[offer1.id, offer2.id],
                                from_provider_update=False)

        # Then
        assert mock_build_object.call_count == 2
        mock_add_objects.assert_called_once_with(objects=[{
            "fake": "test"
        }, {
            "fake": "test"
        }])
        assert mock_add_to_indexed_offers.call_count == 2
        assert mock_add_to_indexed_offers.call_args_list == [
            call(
                pipeline=mock_pipeline,
                offer_details={
                    "name": "Test Book",
                    "dates": [],
                    "prices": [10.0]
                },
                offer_id=offer1.id,
            ),
            call(
                pipeline=mock_pipeline,
                offer_details={
                    "name": "Test Book",
                    "dates": [],
                    "prices": [10.0]
                },
                offer_id=offer2.id,
            ),
        ]
        mock_delete_indexed_offers.assert_not_called()
        mock_delete_objects.assert_not_called()
        mock_pipeline.execute.assert_called_once()
        mock_pipeline.reset.assert_called_once()
        mock_add_offer_ids_in_error.assert_not_called()
Example #3
0
    def test_should_reindex_offers_that_are_already_indexed_only_if_offer_name_changed(
        self,
        mock_add_objects,
        mock_build_object,
        mock_delete_objects,
        mock_check_offer_exists,
        mock_get_offer_details,
        mock_add_to_indexed_offers,
        app,
    ):
        # Given
        client = MagicMock()
        client.pipeline = MagicMock()
        client.pipeline.return_value = MagicMock()
        mock_pipeline = client.pipeline()
        mock_pipeline.execute = MagicMock()
        mock_pipeline.reset = MagicMock()
        offerer = create_offerer(is_active=True, validation_token=None)
        venue = create_venue(offerer=offerer, validation_token=None)
        offer1 = create_offer_with_thing_product(thing_name="super offre 1",
                                                 venue=venue,
                                                 is_active=True)
        stock1 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer1,
                              quantity=1)
        repository.save(stock1)
        offer_ids = [offer1.id]
        mock_build_object.side_effect = [
            {
                "fake": "object"
            },
        ]
        mock_check_offer_exists.return_value = True
        mock_get_offer_details.return_value = {
            "name": "une autre super offre",
            "dates": [],
            "prices": [11.0]
        }

        # When
        process_eligible_offers(client=client,
                                offer_ids=offer_ids,
                                from_provider_update=True)

        # Then
        assert mock_check_offer_exists.call_count == 1
        assert mock_get_offer_details.call_count == 1
        assert mock_add_to_indexed_offers.call_count == 1
        assert mock_add_to_indexed_offers.call_args_list == [
            call(
                pipeline=mock_pipeline,
                offer_details={
                    "name": "super offre 1",
                    "dates": [],
                    "prices": [10.0]
                },
                offer_id=offer1.id,
            ),
        ]
        assert mock_add_objects.call_count == 1
        assert mock_add_objects.call_args_list == [
            call(objects=[{
                "fake": "object"
            }])
        ]
        assert mock_pipeline.execute.call_count == 1
        assert mock_pipeline.reset.call_count == 1
        assert mock_delete_objects.call_count == 0
    def test_should_return_algolia_object_with_required_information(self, app):
        # Given
        in_four_days = datetime.utcnow() + timedelta(days=4)
        three_days_ago = datetime.utcnow() + timedelta(days=-3)
        offerer = create_offerer(name="Offerer name", idx=1)
        venue = create_venue(
            offerer=offerer,
            city="Paris",
            idx=2,
            latitude=48.8638689,
            longitude=2.3380198,
            name="Venue name",
            public_name="Venue public name",
        )
        offer = create_offer_with_event_product(
            venue=venue,
            description="Un lit sous une rivière",
            withdrawal_details="A emporter sur place",
            idx=3,
            is_active=True,
            event_name="Event name",
            event_subcategory_id=subcategories.EVENEMENT_MUSIQUE.id,
            thumb_count=1,
            date_created=datetime(2020, 1, 1, 10, 0, 0),
            ranking_weight=3,
        )
        stock1 = create_stock(
            beginning_datetime=in_four_days,
            date_created=datetime(2020, 12, 5, 11, 0, 0),
            offer=offer,
            price=10,
            quantity=10,
        )
        stock2 = create_stock(
            beginning_datetime=in_four_days,
            date_created=datetime(2020, 12, 11, 8, 0, 0),
            offer=offer,
            price=20,
            quantity=10,
        )
        stock3 = create_stock(
            beginning_datetime=in_four_days,
            date_created=datetime(2020, 12, 1, 11, 0, 0),
            offer=offer,
            price=0,
            quantity=10,
        )
        stock4 = create_stock(
            beginning_datetime=in_four_days,
            date_created=datetime(2020, 12, 4, 7, 0, 0),
            is_soft_deleted=True,
            offer=offer,
            price=0,
            quantity=10,
        )
        stock5 = create_stock(
            beginning_datetime=three_days_ago,
            date_created=datetime(2020, 12, 7, 14, 0, 0),
            offer=offer,
            price=0,
            quantity=10,
        )
        repository.save(stock1, stock2, stock3, stock4, stock5)
        humanized_product_id = humanize(offer.product.id)

        # When
        result = AlgoliaBackend.serialize_offer(offer)

        # Then
        assert result == {
            "distinct": "3",
            "objectID": 3,
            "offer": {
                "artist": None,
                "category": "MUSIQUE",
                "dateCreated": 1577872800.0,
                "dates": [1603098000.0, 1603098000.0, 1603098000.0],
                "description": "lit sous rivière",
                "id": "AM",
                "isbn": None,
                "isDuo": False,
                "isEducational": False,
                "isDigital": False,
                "isEvent": True,
                "isThing": False,
                "label": "Autre type d'événement musical",
                "name": "Event name",
                "prices":
                [Decimal("0.00"),
                 Decimal("10.00"),
                 Decimal("20.00")],
                "rankingWeight": 3,
                "searchGroupName": subcategories.SearchGroups.MUSIQUE.name,
                "stocksDateCreated":
                [1606820400.0, 1607166000.0, 1607673600.0],
                "subcategoryId": subcategories.EVENEMENT_MUSIQUE.id,
                "thumbUrl": f"/storage/thumbs/products/{humanized_product_id}",
                "tags": [],
                "times": [32400],
                "visa": None,
            },
            "offerer": {
                "name": "Offerer name",
            },
            "venue": {
                "id": 2,
                "departementCode": "93",
                "name": "Venue name",
                "publicName": "Venue public name",
            },
            "_geoloc": {
                "lat": 48.86387,
                "lng": 2.33802
            },
        }
Example #5
0
def generate_and_save_api_key(offerer_id: int) -> str:
    if ApiKey.query.filter_by(offererId=offerer_id).count() >= settings.MAX_API_KEY_PER_OFFERER:
        raise ApiKeyCountMaxReached()
    model_api_key, clear_api_key = generate_api_key(offerer_id)
    repository.save(model_api_key)
    return clear_api_key
def save_bookings_recap_sandbox():
    yesterday = datetime.utcnow() - timedelta(days=1)
    today = datetime.utcnow()

    beneficiary1 = create_user(
        public_name="Riri Duck",
        first_name="Riri",
        last_name="Duck",
        email="*****@*****.**",
    )
    beneficiary2 = create_user(
        public_name="Fifi Brindacier",
        first_name="Fifi",
        last_name="Brindacier",
        email="*****@*****.**",
    )
    beneficiary3 = create_user(
        public_name="LouLou Duck",
        first_name="Loulou",
        last_name="Duck",
        email="*****@*****.**",
    )

    repository.save(beneficiary1, beneficiary2, beneficiary3)
    deposit1 = create_deposit(beneficiary1, "public")
    deposit2 = create_deposit(beneficiary2, "public")
    deposit3 = create_deposit(beneficiary3, "public")
    repository.save(deposit1, deposit2, deposit3)

    pro = create_user(
        public_name="Balthazar Picsou",
        first_name="Balthazar",
        last_name="Picsou",
        email="*****@*****.**",
        is_beneficiary=False,
    )
    offerer = create_offerer(siren="645389012", )
    user_offerer = create_user_offerer(user=pro, offerer=offerer)
    venue1 = create_venue(offerer,
                          name="Cinéma Le Monde Perdu",
                          siret="64538901265877")
    venue2 = create_venue(offerer,
                          name="Librairie Atlantis",
                          siret="64538901201379")
    venue3 = create_venue(offerer,
                          name="Théatre Mordor",
                          siret="64538954601379")
    venue4_virtual = create_venue(offerer,
                                  name="Un lieu virtuel",
                                  siret=None,
                                  is_virtual=True)

    offer1_venue1 = create_offer_with_event_product(
        venue=venue1,
        event_name="Jurassic Park",
        event_type=EventType.CINEMA,
        is_duo=True,
    )
    stock_1_offer1_venue1 = create_stock(
        offer=offer1_venue1,
        beginning_datetime=yesterday,
        quantity=None,
        price=12.99,
    )
    offer2_venue1 = create_offer_with_event_product(
        venue=venue1,
        event_name="Matrix",
        event_type=EventType.CINEMA,
        is_duo=False,
    )
    stock_2_offer2_venue1 = create_stock(
        offer=offer2_venue1,
        beginning_datetime=today,
        quantity=None,
        price=0,
    )

    offer1_venue2 = create_offer_with_thing_product(
        venue=venue2,
        thing_name="Fondation",
        thing_type=ThingType.LIVRE_EDITION,
        extra_data={"isbn": "9788804119135"})
    stock_1_offer1_venue2 = create_stock(
        offer=offer1_venue2,
        quantity=42,
        price=9.99,
    )
    offer2_venue2 = create_offer_with_thing_product(
        venue=venue2,
        thing_name="Martine à la playa",
        thing_type=ThingType.LIVRE_EDITION,
        extra_data={"isbn": "9787605639121"},
    )
    stock_1_offer2_venue2 = create_stock(
        offer=offer2_venue2,
        quantity=12,
        price=49.99,
    )

    offer1_venue3 = create_offer_with_event_product(
        venue=venue3,
        event_name="Danse des haricots",
        event_type=EventType.SPECTACLE_VIVANT,
    )
    stock_1_offer1_venue3 = create_stock(
        offer=offer1_venue3,
        quantity=44,
        price=18.50,
    )

    offer1_venue4 = create_offer_with_thing_product(
        venue=venue4_virtual,
        thing_name="Le livre des haricots",
        thing_type=ThingType.LIVRE_EDITION,
    )
    stock_1_offer1_venue4 = create_stock(
        offer=offer1_venue4,
        quantity=70,
        price=10.99,
    )

    booking1_beneficiary1 = create_booking(
        user=beneficiary1,
        stock=stock_1_offer1_venue1,
        date_created=datetime(2020, 3, 18, 14, 56, 12, 0),
        is_used=True,
        date_used=datetime(2020, 3, 22, 17, 00, 10, 0),
        quantity=2,
    )
    booking2_beneficiary1 = create_booking(
        user=beneficiary1,
        stock=stock_2_offer2_venue1,
        date_created=datetime(2020, 4, 22, 9, 17, 12, 0),
    )
    booking1_beneficiary2 = create_booking(
        user=beneficiary2,
        stock=stock_1_offer1_venue1,
        date_created=datetime(2020, 3, 18, 12, 18, 12, 0),
        is_used=True,
        date_used=datetime(2020, 5, 2),
        quantity=2,
    )
    booking2_beneficiary2 = create_booking(
        user=beneficiary2,
        stock=stock_1_offer1_venue2,
        date_created=datetime(2020, 4, 12, 14, 31, 12, 0),
        is_cancelled=False,
    )
    booking1_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_2_offer2_venue1,
        date_created=datetime(2020, 1, 4, 19, 31, 12, 0),
        is_cancelled=False,
        is_used=True,
        date_used=datetime(2020, 1, 4, 23, 00, 10, 0),
        quantity=2,
    )
    booking2_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_1_offer1_venue2,
        date_created=datetime(2020, 3, 21, 22, 9, 12, 0),
        is_cancelled=False,
    )
    booking3_beneficiary1 = create_booking(
        user=beneficiary1,
        stock=stock_1_offer1_venue3,
        date_created=datetime(2020, 4, 12, 14, 31, 12, 0),
    )
    payment_booking3_beneficiary1 = create_payment(
        booking=booking3_beneficiary1,
        offerer=offerer,
        status=TransactionStatus.PENDING)
    booking3_beneficiary2 = create_booking(
        user=beneficiary2,
        stock=stock_1_offer1_venue3,
        date_created=datetime(2020, 4, 12, 19, 31, 12, 0),
        is_used=True,
        date_used=datetime(2020, 4, 22, 17, 00, 10, 0),
        is_cancelled=False,
    )
    payment_booking3_beneficiary2 = create_payment(
        booking=booking3_beneficiary2,
        offerer=offerer,
        status=TransactionStatus.SENT)
    booking3_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_1_offer1_venue3,
        date_created=datetime(2020, 4, 12, 22, 9, 12, 0),
    )
    payment_booking3_beneficiary3 = create_payment(
        booking=booking3_beneficiary3,
        offerer=offerer,
        status=TransactionStatus.ERROR)
    booking4_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_1_offer1_venue2,
        date_created=datetime(2020, 3, 21, 22, 9, 12, 0),
        is_cancelled=False,
        is_used=False,
    )
    booking5_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_1_offer1_venue4,
        date_created=datetime(2020, 3, 21, 22, 9, 12, 0),
        is_cancelled=False,
    )

    booking6_beneficiary3 = create_booking(
        user=beneficiary3,
        stock=stock_1_offer2_venue2,
        date_created=datetime(2020, 3, 21, 22, 9, 12, 0),
        is_used=True,
        date_used=datetime(2020, 4, 22, 21, 9, 12, 0),
    )
    payment_booking6_beneficiary3 = create_payment(
        booking=booking6_beneficiary3,
        offerer=offerer,
        status=TransactionStatus.SENT)

    booking7_beneficiary2 = create_booking(
        user=beneficiary2,
        stock=stock_1_offer2_venue2,
        date_created=datetime(2020, 4, 21, 22, 6, 12, 0),
        is_used=True,
        date_used=datetime(2020, 4, 22, 22, 9, 12, 0),
    )

    payment_booking7_beneficiary2 = create_payment(
        booking=booking7_beneficiary2,
        offerer=offerer,
        status=TransactionStatus.RETRY)

    booking8_beneficiary1 = create_booking(
        user=beneficiary1,
        stock=stock_1_offer2_venue2,
        date_created=datetime(2020, 2, 21, 22, 6, 12, 0),
        is_used=True,
        date_used=datetime(2020, 4, 22, 23, 9, 12, 0),
    )

    payment_booking8_beneficiary1 = create_payment(
        booking=booking8_beneficiary1,
        offerer=offerer,
        status=TransactionStatus.PENDING)

    repository.save(
        pro,
        booking1_beneficiary1,
        booking2_beneficiary1,
        booking1_beneficiary2,
        booking2_beneficiary2,
        booking1_beneficiary3,
        booking2_beneficiary3,
        booking5_beneficiary3,
        payment_booking3_beneficiary1,
        payment_booking3_beneficiary2,
        payment_booking3_beneficiary3,
        user_offerer,
        payment_booking6_beneficiary3,
        payment_booking7_beneficiary2,
        payment_booking8_beneficiary1,
        booking4_beneficiary3,
    )

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

    for booking in bookings_to_cancel:
        booking.isCancelled = True
    repository.save(*bookings_to_cancel)
Example #7
0
def activate_provider(provider_classname: str) -> Provider:
    provider = get_provider_by_local_class(provider_classname)
    provider.isActive = True
    provider.enabledForPro = True
    repository.save(provider)
    return provider
Example #8
0
def edit_stock(
    stock: Stock,
    price: int = None,
    quantity: int = None,
    beginning: datetime.datetime = None,
    booking_limit_datetime: datetime.datetime = None,
) -> Stock:
    validation.check_stock_is_updatable(stock)
    validation.check_required_dates_for_stock(stock.offer, beginning, booking_limit_datetime)

    # FIXME (dbaty, 2020-11-25): We need this ugly workaround because
    # the frontend sends us datetimes like "2020-12-03T14:00:00Z"
    # (note the "Z" suffix). Pydantic deserializes it as a datetime
    # *with* a timezone. However, datetimes are stored in the database
    # as UTC datetimes *without* any timezone. Thus, we wrongly detect
    # a change for the "beginningDatetime" field for Allocine stocks:
    # because we do not allow it to be changed, we raise an error when
    # we should not.
    def as_utc_without_timezone(d: datetime.datetime) -> datetime.datetime:
        return d.astimezone(pytz.utc).replace(tzinfo=None)

    if beginning:
        beginning = as_utc_without_timezone(beginning)
    if booking_limit_datetime:
        booking_limit_datetime = as_utc_without_timezone(booking_limit_datetime)

    updates = {
        "price": price,
        "quantity": quantity,
        "beginningDatetime": beginning,
        "bookingLimitDatetime": booking_limit_datetime,
    }

    if stock.offer.isFromAllocine:
        # fmt: off
        updated_fields = {
            attr
            for attr, new_value in updates.items()
            if new_value != getattr(stock, attr)
        }
        # fmt: on
        validation.check_update_only_allowed_stock_fields_for_allocine_offer(updated_fields)
        stock.fieldsUpdated = list(updated_fields)

    previous_beginning = stock.beginningDatetime

    for model_attr, value in updates.items():
        setattr(stock, model_attr, value)
    repository.save(stock)

    if beginning != previous_beginning:
        bookings = bookings_repository.find_not_cancelled_bookings_by_stock(stock)
        if bookings:
            bookings = update_confirmation_dates(bookings, beginning)
            date_in_two_days = datetime.datetime.utcnow() + datetime.timedelta(days=2)
            check_event_is_in_more_than_48_hours = beginning > date_in_two_days
            if check_event_is_in_more_than_48_hours:
                bookings = _invalidate_bookings(bookings)
            try:
                user_emails.send_batch_stock_postponement_emails_to_users(bookings, send_email=mailing.send_raw_email)
            except mailing.MailServiceException as exc:
                # fmt: off
                app.logger.exception(
                    "Could not notify beneficiaries about update of stock=%s: %s",
                    stock.id,
                    exc,
                )
                # fmt: on

    if feature_queries.is_active(FeatureToggle.SYNCHRONIZE_ALGOLIA):
        redis.add_offer_id(client=app.redis_client, offer_id=stock.offerId)

    return stock
Example #9
0
 def _expire_deposit(self, user):
     deposit = user.deposits[0]
     deposit.expirationDate = datetime.now() - timedelta(days=1)
     repository.save(deposit)
def test_find_filtered_offerers_with_one_keyword_at_venue_public_name_level(app):
    # given
    offerer_with_only_virtual_venue_with_offer = create_offerer(siren="123456785")
    offerer_with_only_virtual_venue_without_offer = create_offerer(siren="123456786")
    offerer_with_both_venues_none_offer = create_offerer(siren="123456781")
    offerer_with_both_venues_offer_on_both = create_offerer(siren="123456782")
    offerer_with_both_venues_offer_on_virtual = create_offerer(siren="123456783")
    offerer_with_both_venues_offer_on_not_virtual = create_offerer(siren="123456784")

    virtual_venue_with_offer_1 = create_venue(offerer_with_only_virtual_venue_with_offer, is_virtual=True, siret=None)
    virtual_venue_without_offer_1 = create_venue(
        offerer_with_only_virtual_venue_without_offer, is_virtual=True, siret=None
    )
    virtual_venue_without_offer_2 = create_venue(offerer_with_both_venues_none_offer, is_virtual=True, siret=None)
    venue_without_offer_2 = create_venue(offerer_with_both_venues_none_offer, siret="12345678112345")
    virtual_venue_with_offer_3 = create_venue(
        offerer_with_both_venues_offer_on_both, is_virtual=True, siret=None, public_name="chouette lieu de ouf"
    )
    venue_with_offer_3 = create_venue(
        offerer_with_both_venues_offer_on_both, siret="12345678212345", public_name="chouette lieu de ouf"
    )
    virtual_venue_with_offer_4 = create_venue(
        offerer_with_both_venues_offer_on_virtual, is_virtual=True, siret=None, public_name="chouette lieu de ouf"
    )
    venue_without_offer_4 = create_venue(
        offerer_with_both_venues_offer_on_virtual, siret="12345678312345", public_name="chouette lieu de ouf"
    )
    virtual_venue_without_offer_5 = create_venue(
        offerer_with_both_venues_offer_on_not_virtual, is_virtual=True, siret=None, public_name="chouette lieu de ouf"
    )
    venue_with_offer_5 = create_venue(
        offerer_with_both_venues_offer_on_not_virtual, siret="12345678412345", public_name="chouette lieu de ouf"
    )

    offer_1 = create_offer_with_thing_product(virtual_venue_with_offer_1, url="http://url.com")
    offer_2 = create_offer_with_thing_product(virtual_venue_with_offer_3, url="http://url.com")
    offer_3 = create_offer_with_event_product(venue_with_offer_3)
    offer_4 = create_offer_with_thing_product(virtual_venue_with_offer_4, url="http://url.com")
    offer_5 = create_offer_with_event_product(venue_with_offer_5)

    repository.save(
        offer_1,
        offer_2,
        offer_3,
        offer_4,
        offer_5,
        virtual_venue_without_offer_1,
        virtual_venue_without_offer_2,
        virtual_venue_without_offer_5,
        venue_without_offer_2,
        venue_without_offer_4,
    )

    # when
    offerers = filter_offerers_with_keywords_string(Offerer.query.join(Venue), "chouette")

    # then
    assert offerer_with_only_virtual_venue_with_offer not in offerers
    assert offerer_with_only_virtual_venue_without_offer not in offerers
    assert offerer_with_both_venues_none_offer not in offerers
    assert offerer_with_both_venues_offer_on_both in offerers
    assert offerer_with_both_venues_offer_on_virtual in offerers
    assert offerer_with_both_venues_offer_on_not_virtual in offerers
Example #11
0
def create_admin_user():
    admin_user = create_user(is_beneficiary=False,
                             is_admin=True,
                             email="*****@*****.**")
    repository.save(admin_user)
    logger.info("created 1 admin user")
Example #12
0
 def save(cls,
          beneficiary_pre_subscription: BeneficiaryPreSubscription) -> User:
     user_sql_entity = beneficiary_pre_subscription_sql_converter.to_model(
         beneficiary_pre_subscription)
     repository.save(user_sql_entity)
     return user_sql_entity
Example #13
0
 def reject(cls, beneficiary_pre_subscription: BeneficiaryPreSubscription,
            detail: str) -> None:
     beneficiary_import = beneficiary_pre_subscription_sql_converter.to_rejected_model(
         beneficiary_pre_subscription, detail=detail)
     repository.save(beneficiary_import)
Example #14
0
    def test_should_return_expected_payload_for_bookable_offer(self, app):
        # Given
        offerer = create_offerer()
        venue = create_venue(offerer)
        product = create_product_with_thing_type()
        offer = create_offer_with_thing_product(venue, product=product)
        stock = create_stock(offer=offer)
        mediation = create_mediation(offer)
        repository.save(mediation, stock)

        # When
        offer_json_response = get_non_free_thing_offer_with_active_mediation()

        # Then
        assert offer_json_response == {
            "mediationId": humanize(mediation.id),
            "offer": {
                "ageMax":
                None,
                "ageMin":
                None,
                "audioDisabilityCompliant":
                None,
                "bookingEmail":
                "*****@*****.**",
                "conditions":
                None,
                "dateCreated":
                format_into_utc_date(offer.dateCreated),
                "dateModifiedAtLastProvider":
                format_into_utc_date(offer.dateModifiedAtLastProvider),
                "description":
                None,
                "durationMinutes":
                None,
                "externalTicketOfficeUrl":
                None,
                "extraData": {
                    "author": "Test Author"
                },
                "fieldsUpdated": [],
                "id":
                humanize(offer.id),
                "idAtProviders":
                offer.idAtProviders,
                "isActive":
                True,
                "isDuo":
                False,
                "isNational":
                False,
                "lastProviderId":
                None,
                "mediaUrls": ["test/urls"],
                "mentalDisabilityCompliant":
                None,
                "motorDisabilityCompliant":
                None,
                "name":
                "Test Book",
                "productId":
                humanize(product.id),
                "thingName":
                "Test Book",
                "type":
                "ThingType.LIVRE_EDITION",
                "url":
                None,
                "venueCity":
                "Montreuil",
                "venueId":
                humanize(venue.id),
                "venueName":
                "La petite librairie",
                "visualDisabilityCompliant":
                None,
                "withdrawalDetails":
                None,
            },
        }
Example #15
0
        def expect_booking_to_have_completed_url(self, app):
            # Given
            user = create_user(email="*****@*****.**")
            offerer = create_offerer()
            venue = create_venue(offerer)
            offer = create_offer_with_thing_product(
                venue,
                url="https://host/path/{token}?offerId={offerId}&email={email}"
            )
            stock = create_stock(offer=offer, price=0)
            booking = create_booking(user=user,
                                     stock=stock,
                                     token="ABCDEF",
                                     venue=venue)
            repository.save(booking)

            # When
            response = TestClient(app.test_client()).with_auth(
                user.email).get("/bookings/" + humanize(booking.id))

            # Then
            assert response.status_code == 200
            completed_url = "https://host/path/ABCDEF?offerId={}&[email protected]".format(
                humanize(offer.id))

            assert "validationToken" not in response.json["stock"]["offer"]
            assert response.json == {
                "amount": 0.0,
                "cancellationDate": None,
                "cancellationReason": None,
                "completedUrl": completed_url,
                "confirmationDate": None,
                "dateCreated": format_into_utc_date(booking.dateCreated),
                "dateUsed": None,
                "id": humanize(booking.id),
                "isCancelled": False,
                "isEventExpired": False,
                "isUsed": False,
                "mediation": None,
                "quantity": 1,
                "stock": {
                    "beginningDatetime":
                    None,
                    "bookingLimitDatetime":
                    None,
                    "dateCreated":
                    format_into_utc_date(stock.dateCreated),
                    "dateModified":
                    format_into_utc_date(stock.dateModified),
                    "dateModifiedAtLastProvider":
                    format_into_utc_date(stock.dateModifiedAtLastProvider),
                    "fieldsUpdated": [],
                    "id":
                    humanize(stock.id),
                    "idAtProviders":
                    None,
                    "isBookable":
                    True,
                    "isEventExpired":
                    False,
                    "isSoftDeleted":
                    False,
                    "lastProviderId":
                    None,
                    "offer": {
                        "ageMax":
                        None,
                        "ageMin":
                        None,
                        "audioDisabilityCompliant":
                        None,
                        "bookingEmail":
                        "*****@*****.**",
                        "conditions":
                        None,
                        "dateCreated":
                        format_into_utc_date(offer.dateCreated),
                        "dateModifiedAtLastProvider":
                        format_into_utc_date(offer.dateModifiedAtLastProvider),
                        "description":
                        None,
                        "durationMinutes":
                        None,
                        "externalTicketOfficeUrl":
                        None,
                        "extraData": {
                            "author": "Test Author"
                        },
                        "fieldsUpdated": [],
                        "hasBookingLimitDatetimesPassed":
                        False,
                        "id":
                        humanize(offer.id),
                        "idAtProviders":
                        offer.idAtProviders,
                        "isActive":
                        True,
                        "isBookable":
                        True,
                        "isDigital":
                        True,
                        "isDuo":
                        False,
                        "isEvent":
                        False,
                        "isNational":
                        False,
                        "lastProviderId":
                        None,
                        "mediaUrls": ["test/urls"],
                        "mentalDisabilityCompliant":
                        None,
                        "motorDisabilityCompliant":
                        None,
                        "name":
                        "Test Book",
                        "offerType": {
                            "appLabel":
                            "Film",
                            "canExpire":
                            True,
                            "conditionalFields": [],
                            "description":
                            ("Action, science-fiction, documentaire ou comédie "
                             "sentimentale ? En salle, en plein air ou bien au chaud "
                             "chez soi ? Et si c’était plutôt cette exposition qui "
                             "allait faire son cinéma ?"),
                            "isActive":
                            True,
                            "offlineOnly":
                            False,
                            "onlineOnly":
                            False,
                            "proLabel":
                            "Audiovisuel - films sur supports physiques et VOD",
                            "sublabel":
                            "Regarder",
                            "type":
                            "Thing",
                            "value":
                            "ThingType.AUDIOVISUEL",
                        },
                        "productId":
                        humanize(offer.product.id),
                        "stocks": [{
                            "beginningDatetime":
                            None,
                            "bookingLimitDatetime":
                            None,
                            "dateCreated":
                            format_into_utc_date(stock.dateCreated),
                            "dateModified":
                            format_into_utc_date(stock.dateModified),
                            "dateModifiedAtLastProvider":
                            format_into_utc_date(
                                stock.dateModifiedAtLastProvider),
                            "fieldsUpdated": [],
                            "id":
                            humanize(stock.id),
                            "idAtProviders":
                            None,
                            "isBookable":
                            True,
                            "isEventExpired":
                            False,
                            "isSoftDeleted":
                            False,
                            "lastProviderId":
                            None,
                            "offerId":
                            humanize(offer.id),
                            "price":
                            0.0,
                            "quantity":
                            None,
                            "remainingQuantity":
                            "unlimited",
                        }],
                        "thumbUrl":
                        None,
                        "type":
                        "ThingType.AUDIOVISUEL",
                        "url":
                        "https://host/path/{token}?offerId={offerId}&email={email}",
                        "venue": {
                            "address":
                            "123 rue de Paris",
                            "bookingEmail":
                            None,
                            "city":
                            "Montreuil",
                            "comment":
                            None,
                            "dateCreated":
                            format_into_utc_date(venue.dateCreated),
                            "dateModifiedAtLastProvider":
                            format_into_utc_date(
                                venue.dateModifiedAtLastProvider),
                            "departementCode":
                            "93",
                            "fieldsUpdated": [],
                            "id":
                            humanize(venue.id),
                            "idAtProviders":
                            None,
                            "isVirtual":
                            False,
                            "lastProviderId":
                            None,
                            "latitude":
                            None,
                            "longitude":
                            None,
                            "managingOffererId":
                            humanize(offerer.id),
                            "name":
                            "La petite librairie",
                            "postalCode":
                            "93100",
                            "publicName":
                            None,
                            "siret":
                            "12345678912345",
                            "thumbCount":
                            0,
                            "venueLabelId":
                            None,
                            "venueTypeId":
                            None,
                        },
                        "venueId":
                        humanize(venue.id),
                        "visualDisabilityCompliant":
                        None,
                        "withdrawalDetails":
                        None,
                    },
                    "offerId":
                    humanize(offer.id),
                    "price":
                    0.0,
                    "quantity":
                    None,
                    "remainingQuantity":
                    "unlimited",
                },
                "stockId": humanize(stock.id),
                "token": booking.token,
                "userId": humanize(user.id),
            }
 def save(self, bank_informations: BankInformations) -> BankInformations:
     bank_informations_sql_entity = bank_informations_domain_converter.to_model(
         bank_informations)
     repository.save(bank_informations_sql_entity)
     return bank_informations
Example #17
0
def create_industrial_offerers_with_pro_users():
    logger.info("create_industrial_offerers_with_pro_users")

    locations = create_locations_from_places(OFFERER_PLACES,
                                             max_location_per_place=3)

    offerers_by_name = {}
    users_by_name = {}
    user_offerers_by_name = {}

    user_index = 0
    user_validation_prefix, user_validation_suffix = "AZERTY", 123

    # add a real offerer just for the inscription/validation API
    real_siren = "784340093"
    if not check_if_siren_already_exists(real_siren):
        offerer_name = "784340093 lat:48.8 lon:1.48"
        offerer = create_offerer(
            address="LIEU DIT CARTOUCHERIE",
            city="Paris 12",
            name="THEATRE DU SOLEIL",
            postal_code="75012",
            siren=real_siren,
        )
        offerers_by_name[offerer_name] = offerer

        departement_code = 75

        domain = MOCK_DOMAINS[user_index]
        first_name = MOCK_FIRST_NAMES[user_index]
        last_name = MOCK_LAST_NAMES[user_index]
        email = get_email(first_name, last_name, domain)
        user_name = "{} {}".format(first_name, last_name)
        user = create_user(
            reset_password_token_validity_limit=datetime.utcnow() +
            timedelta(hours=24),
            departement_code=str(departement_code),
            email=email,
            first_name=first_name,
            last_name=last_name,
            postal_code="{}100".format(departement_code),
            public_name="{} {}".format(first_name, last_name),
            validation_token="{}{}".format(user_validation_prefix,
                                           user_validation_suffix),
        )
        users_by_name[user_name] = user
        user_index += 1
        user_validation_suffix += 1

        user_offerers_by_name["{} / {}".format(
            user_name, offerer_name)] = create_user_offerer(
                offerer=offerer,
                user=user,
            )

    # loop on locations to create offerers and associated users
    incremented_siren = 222222222
    starting_index = 0
    iban_prefix = "FR7630001007941234567890185"
    bic_prefix, bic_suffix = "QSDFGH8Z", 555
    user_offerer_validation_prefix, user_offerer_validation_suffix = "AZERTY", 123
    application_id_prefix = "23"

    for (location_index, location) in enumerate(locations):

        mock_index = location_index % len(MOCK_NAMES) + starting_index

        departement_code = location["postalCode"][:2]

        offerer_name = "{} lat:{} lon:{}".format(incremented_siren,
                                                 location["latitude"],
                                                 location["longitude"])

        offerer = create_offerer(
            address=location["address"].upper(),
            city=location["city"],
            name=MOCK_NAMES[mock_index],
            postal_code=location["postalCode"],
            siren=str(incremented_siren),
        )

        # create every OFFERERS_WITH_IBAN_REMOVE_MODULO an offerer with no iban
        if location_index % OFFERERS_WITH_IBAN_REMOVE_MODULO:
            create_bank_information(
                bic=bic_prefix + str(bic_suffix),
                iban=iban_prefix,
                offerer=offerer,
                application_id=application_id_prefix + str(location_index),
            )

        offerers_by_name[offerer_name] = offerer

        incremented_siren += 1
        bic_suffix += 1

        # special user that signed up with this offerer
        domain = MOCK_DOMAINS[user_index % len(MOCK_DOMAINS)]
        first_name = MOCK_FIRST_NAMES[user_index % len(MOCK_FIRST_NAMES)]
        last_name = MOCK_LAST_NAMES[user_index % len(MOCK_LAST_NAMES)]
        email = get_email(first_name, last_name, domain)
        user_name = "{} {}".format(first_name, last_name)

        if location_index % VALIDATED_USER_REMOVE_MODULO:
            user_validation_token = None
        else:
            user_validation_token = "{}{}".format(user_validation_prefix,
                                                  user_validation_suffix)

        if location_index % VALIDATED_OFFERERS_REMOVE_MODULO == 0:
            offerer.generate_validation_token()

        user = create_user(
            reset_password_token_validity_limit=datetime.utcnow() +
            timedelta(hours=24),
            departement_code=str(departement_code),
            email=email,
            first_name=first_name,
            last_name=last_name,
            postal_code="{}100".format(departement_code),
            public_name="{} {}".format(first_name, last_name),
            validation_token=user_validation_token,
        )
        users_by_name[user_name] = user
        user_validation_suffix += 1
        user_index += 1

        # user_offerer with None as validation token
        # because this user has created the offerer
        user_offerers_by_name["{} / {}".format(
            user_name, offerer_name)] = create_user_offerer(offerer=offerer,
                                                            user=user)

        # create also users that are attached to this offerer
        for _i in range(ATTACHED_PRO_USERS_COUNT):
            # special user that signed up with this offerer
            domain = MOCK_DOMAINS[user_index % len(MOCK_DOMAINS)]
            first_name = MOCK_FIRST_NAMES[user_index % len(MOCK_FIRST_NAMES)]
            last_name = MOCK_LAST_NAMES[user_index % len(MOCK_LAST_NAMES)]
            email = get_email(first_name, last_name, domain)
            user_name = "{} {}".format(first_name, last_name)
            if location_index % VALIDATED_USER_REMOVE_MODULO:
                user_validation_token = None
            else:
                user_validation_token = "{}{}".format(user_validation_prefix,
                                                      user_validation_suffix)
            user_name = "{} {}".format(first_name, last_name)
            user = create_user(
                reset_password_token_validity_limit=datetime.utcnow() +
                timedelta(hours=24),
                departement_code=str(departement_code),
                email=email,
                first_name=first_name,
                last_name=last_name,
                postal_code="{}100".format(departement_code),
                public_name="{} {}".format(first_name, last_name),
                validation_token=user_validation_token,
            )
            users_by_name[user_name] = user
            user_index += 1
            user_validation_suffix += 1

            if location_index % VALIDATED_USER_OFFERER_REMOVE_MODULO:
                user_offerer_validation_token = None
            else:
                user_offerer_validation_token = "{}{}".format(
                    user_offerer_validation_prefix,
                    user_offerer_validation_suffix)
            user_offerers_by_name["{} / {}".format(
                user_name, offerer_name)] = create_user_offerer(
                    offerer=offerer,
                    user=user,
                    validation_token=user_offerer_validation_token)
            user_offerer_validation_suffix += 1

    # loop on users to make some of them with several attached offerers
    user_items_with_several_offerers = pick_every(
        users_by_name.items(), USERS_WITH_SEVERAL_OFFERERS_PICK_MODULO)
    user_offerer_index = 0

    for (user_name, user) in user_items_with_several_offerers:
        offerer_items_with_three_attached_users = pick_every(
            offerers_by_name.items(),
            OFFERERS_WITH_THREE_ATTACHED_USERS_PICK_MODULO)
        for (offerer_name, offerer) in offerer_items_with_three_attached_users:
            user_offerer_name = "{} / {}".format(user_name, offerer_name)

            if user_offerer_name in user_offerers_by_name:
                continue

            if offerer.isValidated and user_offerer_index % VALIDATED_USER_OFFERER_REMOVE_MODULO == 0:
                user_offerer_validation_token = None
            else:
                user_offerer_validation_token = "{}{}".format(
                    user_offerer_validation_prefix,
                    user_offerer_validation_suffix)
            user_offerers_by_name["{} / {}".format(
                user_name, offerer_name)] = create_user_offerer(
                    offerer=offerer,
                    user=user,
                    validation_token=user_offerer_validation_token)
            user_offerer_index += 1
            user_offerer_validation_suffix += 1

    objects_to_save = (list(offerers_by_name.values()) +
                       list(users_by_name.values()) +
                       list(user_offerers_by_name.values()))

    repository.save(*objects_to_save)

    logger.info("created %d offerers with pro users", len(offerers_by_name))

    return (offerers_by_name, users_by_name)
def create_industrial_thing_offers(things_by_name, offerers_by_name,
                                   venues_by_name):
    logger.info("create_industrial_thing_offers")

    thing_offers_by_name = {}

    id_at_providers = 1234
    thing_index = 0
    offer_index = 0
    thing_items = list(things_by_name.items())

    for offerer in offerers_by_name.values():

        virtual_venue = [
            venue for venue in offerer.managedVenues if venue.isVirtual
        ][0]

        physical_venue_name = virtual_venue.name.replace(
            " (Offre numérique)", "")
        physical_venue = venues_by_name.get(physical_venue_name)

        for venue_thing_index in range(0, THINGS_PER_OFFERER):

            thing_venue = None
            while thing_venue is None:
                rest_thing_index = (venue_thing_index +
                                    thing_index) % len(thing_items)

                (thing_name, thing) = thing_items[rest_thing_index]

                if thing.offerType["offlineOnly"]:
                    thing_venue = physical_venue
                elif thing.offerType["onlineOnly"]:
                    thing_venue = virtual_venue
                else:
                    thing_venue = physical_venue

                thing_index += 1

            name = "{} / {}".format(thing_name, thing_venue.name)
            if offer_index % DEACTIVATED_OFFERS_PICK_MODULO == 0:
                is_active = False
            else:
                is_active = True
            thing_offers_by_name[name] = create_offer_with_thing_product(
                thing_venue,
                product=thing,
                thing_type=thing.type,
                is_active=is_active,
                id_at_providers=str(id_at_providers),
            )
            offer_index += 1
            id_at_providers += 1

        thing_index += THINGS_PER_OFFERER

    repository.save(*thing_offers_by_name.values())

    logger.info("created %d thing_offers", len(thing_offers_by_name))

    return thing_offers_by_name
Example #19
0
    def test_should_return_last_matching_status_based_on_date_for_each_payment(self, app):
        # Given
        user = create_user(last_name="User", first_name="Plus")
        deposit = create_deposit(user)
        offerer = create_offerer(address="7 rue du livre")
        venue = create_venue(offerer)
        stock = create_stock_with_thing_offer(offerer=offerer, venue=venue, price=10)
        now = datetime.utcnow()
        booking1 = create_booking(user=user, stock=stock, is_used=True, date_used=now, token="ABCDEF", venue=venue)
        booking2 = create_booking(user=user, stock=stock, is_used=True, date_used=now, token="ABCDFE", venue=venue)

        payment1 = create_payment(
            booking1,
            offerer,
            transaction_label="pass Culture Pro - remboursement 1ère quinzaine 07-2019",
            status=TransactionStatus.PENDING,
            amount=50,
            status_date=now - timedelta(days=2),
        )
        payment2 = create_payment(
            booking2,
            offerer,
            transaction_label="pass Culture Pro - remboursement 2ème quinzaine 07-2019",
            status=TransactionStatus.PENDING,
            amount=75,
            status_date=now - timedelta(days=4),
        )

        repository.save(deposit, payment1, payment2)

        last_status_for_payment1 = create_payment_status(
            payment1, detail="All good", status=TransactionStatus.SENT, date=now
        )
        last_status_for_payment2 = create_payment_status(payment2, detail=None, status=TransactionStatus.SENT, date=now)
        repository.save(last_status_for_payment1, last_status_for_payment2)

        first_status_for_payment1 = create_payment_status(
            payment1, detail="Retry", status=TransactionStatus.RETRY, date=now - timedelta(days=1)
        )
        first_status_for_payment2 = create_payment_status(
            payment2, detail="Iban non fournis", status=TransactionStatus.ERROR, date=now - timedelta(days=3)
        )
        repository.save(first_status_for_payment1, first_status_for_payment2)

        # When
        payments = find_all_offerer_payments(offerer.id)

        # Then
        assert len(payments) == 2
        assert payments[0] == (
            "User",
            "Plus",
            "ABCDFE",
            now,
            "Test Book",
            "7 rue du livre",
            "La petite librairie",
            "12345678912345",
            "123 rue de Paris",
            Decimal("75.00"),
            None,
            "pass Culture Pro - remboursement 2ème quinzaine 07-2019",
            TransactionStatus.SENT,
            None,
        )
        assert payments[1] == (
            "User",
            "Plus",
            "ABCDEF",
            now,
            "Test Book",
            "7 rue du livre",
            "La petite librairie",
            "12345678912345",
            "123 rue de Paris",
            Decimal("50.00"),
            None,
            "pass Culture Pro - remboursement 1ère quinzaine 07-2019",
            TransactionStatus.SENT,
            "All good",
        )
Example #20
0
def has_completed_id_check(user: User) -> None:
    user.hasCompletedIdCheck = True
    repository.save(user)
    update_external_user(user)
Example #21
0
    def test_cancel_bookings_of_offers_from_rows(self):
        beneficiary = create_user()
        create_deposit(user=beneficiary)
        offerer_to_cancel = create_offerer(
            name="Librairie les petits parapluies gris", siren="123456789")
        offerer_to_not_cancel = create_offerer(
            name="L'amicale du club de combat", siren="987654321")
        venue_to_cancel = create_venue(offerer=offerer_to_cancel,
                                       siret="12345678912345")
        venue_to_not_cancel = create_venue(offerer=offerer_to_not_cancel,
                                           siret="54321987654321")
        offer_to_cancel = create_offer_with_event_product(
            venue=venue_to_cancel,
            event_name="Dédicace de la Joie des Visiteurs")
        offer_to_not_cancel = create_offer_with_event_product(
            venue=venue_to_not_cancel,
            event_name="Règle numéro une, ne pas du club de combat")
        stock_to_cancel = create_stock(offer=offer_to_cancel)
        stock_to_not_cancel = create_stock(offer=offer_to_not_cancel)
        self.booking_to_cancel = create_booking(stock=stock_to_cancel,
                                                user=beneficiary,
                                                is_used=True,
                                                date_used=datetime.utcnow())
        self.booking_to_not_cancel = create_booking(stock=stock_to_not_cancel,
                                                    user=beneficiary)
        self.booking_2QLYYA_not_to_cancel = create_booking(
            stock=stock_to_cancel, user=beneficiary, token="2QLYYA")
        self.booking_BMTUME_not_to_cancel = create_booking(
            stock=stock_to_cancel, user=beneficiary, token="BMTUME")
        self.booking_LUJ9AM_not_to_cancel = create_booking(
            stock=stock_to_cancel, user=beneficiary, token="LUJ9AM")
        self.booking_DA8YLU_not_to_cancel = create_booking(
            stock=stock_to_cancel, user=beneficiary, token="DA8YLU")
        self.booking_Q46YHM_not_to_cancel = create_booking(
            stock=stock_to_cancel, user=beneficiary, token="Q46YHM")
        repository.save(self.booking_to_cancel, self.booking_to_not_cancel)

        self.csv_rows = [
            [
                "id offre",
                "Structure",
                "Département",
                "Offre",
                "Date de l'évènement",
                "Nb Réservations",
                "A annuler ?",
                "Commentaire",
            ],
            [
                offer_to_cancel.id,
                offer_to_cancel.name,
                "75000",
                offer_to_cancel.name,
                "2020-06-19 18:00:48",
                1,
                "Oui",
                "",
            ],
            [
                offer_to_not_cancel.id,
                offerer_to_not_cancel.name,
                offer_to_not_cancel.name,
                "93000",
                "2020-06-20 18:00:12",
                1,
                "Non",
                "",
            ],
        ]

        _cancel_bookings_of_offers_from_rows(self.csv_rows)

        # Then
        saved_booking = Booking.query.get(self.booking_to_cancel.id)
        assert saved_booking.isCancelled is True
        assert saved_booking.cancellationDate is not None
        assert saved_booking.isUsed is False
        assert saved_booking.dateUsed is None

        saved_booking = Booking.query.get(self.booking_to_not_cancel.id)
        assert saved_booking.isCancelled is False
        assert saved_booking.cancellationDate is None

        saved_2QLYYA_booking = Booking.query.get(
            self.booking_2QLYYA_not_to_cancel.id)
        assert saved_2QLYYA_booking.isCancelled is False
        assert saved_2QLYYA_booking.cancellationDate is None

        saved_BMTUME_booking = Booking.query.get(
            self.booking_BMTUME_not_to_cancel.id)
        assert saved_BMTUME_booking.isCancelled is False
        assert saved_BMTUME_booking.cancellationDate is None

        saved_LUJ9AM_booking = Booking.query.get(
            self.booking_LUJ9AM_not_to_cancel.id)
        assert saved_LUJ9AM_booking.isCancelled is False
        assert saved_LUJ9AM_booking.cancellationDate is None

        saved_DA8YLU_booking = Booking.query.get(
            self.booking_DA8YLU_not_to_cancel.id)
        assert saved_DA8YLU_booking.isCancelled is False
        assert saved_DA8YLU_booking.cancellationDate is None

        saved_Q46YHM_booking = Booking.query.get(
            self.booking_Q46YHM_not_to_cancel.id)
        assert saved_Q46YHM_booking.isCancelled is False
        assert saved_Q46YHM_booking.cancellationDate is None
Example #22
0
def create_industrial_event_products():
    logger.info("create_industrial_event_products")

    event_products_by_name = {}

    event_subcategories = [s for s in subcategories.ALL_SUBCATEGORIES if s.is_event]

    activation_index = 0

    for product_creation_counter in range(0, EVENT_COUNTS_PER_TYPE):

        for (event_subcategories_list_index, event_subcategory) in enumerate(event_subcategories):

            mock_index = (product_creation_counter + event_subcategories_list_index) % len(MOCK_NAMES)
            if event_subcategory == subcategories.ACTIVATION_EVENT:
                event_name = "{} {}".format(MOCK_ACTIVATION_NAME, activation_index)
                description = MOCK_ACTIVATION_DESCRIPTION
                activation_index += 1
            else:
                event_name = MOCK_NAMES[mock_index]
                description = MOCK_DESCRIPTIONS[mock_index]

            name = "{} / {}".format(event_subcategory.id, event_name)
            event_product = create_product_with_event_subcategory(
                description=description,
                duration_minutes=60,
                event_name=event_name,
                event_subcategory_id=event_subcategory.id,
                thumb_count=0,
            )

            extraData = {}
            extra_data_index = 0
            for conditionalField in event_product.subcategory.conditional_fields:
                conditional_index = product_creation_counter + event_subcategories_list_index + extra_data_index
                if conditionalField in ["author", "performer", "speaker", "stageDirector"]:
                    mock_first_name_index = conditional_index % len(MOCK_FIRST_NAMES)
                    mock_first_name = MOCK_FIRST_NAMES[mock_first_name_index]
                    mock_last_name_index = conditional_index % len(MOCK_LAST_NAMES)
                    mock_last_name = MOCK_LAST_NAMES[mock_last_name_index]
                    mock_name = "{} {}".format(mock_first_name, mock_last_name)
                    extraData[conditionalField] = mock_name
                elif conditionalField == "musicType":
                    music_type_index = conditional_index % len(music_types)
                    music_type = music_types[music_type_index]
                    extraData[conditionalField] = str(music_type["code"])
                    music_sub_type_index = conditional_index % len(music_type["children"])
                    music_sub_type = music_type["children"][music_sub_type_index]
                    extraData["musicSubType"] = str(music_sub_type["code"])
                elif conditionalField == "showType":
                    show_type_index = conditional_index % len(show_types)
                    show_type = show_types[show_type_index]
                    extraData[conditionalField] = str(show_type["code"])
                    show_sub_type_index = conditional_index % len(show_type["children"])
                    show_sub_type = show_type["children"][show_sub_type_index]
                    extraData["showSubType"] = str(show_sub_type["code"])
                elif conditionalField == "visa":
                    pass
                extra_data_index += 1
            event_product.extraData = extraData
            event_products_by_name[name] = event_product

        product_creation_counter += len(event_subcategories)

    repository.save(*event_products_by_name.values())

    logger.info("created %d event products", len(event_products_by_name))

    return event_products_by_name
    def test_should_return_algolia_object_with_two_tags_when_two_criterion(
            self, app):
        # Given
        in_four_days = datetime.utcnow() + timedelta(days=4)
        offerer = create_offerer(name="Offerer name", idx=1)
        venue = create_venue(
            offerer=offerer,
            city="Paris",
            idx=2,
            latitude=48.8638689,
            longitude=2.3380198,
            name="Venue name",
            public_name="Venue public name",
        )
        criterion1 = create_criterion(description="Ma super offre",
                                      name="Mon tag associé",
                                      score_delta=0)
        criterion2 = create_criterion(description="Avengers",
                                      name="Iron Man mon super héros",
                                      score_delta=0)
        offer = create_offer_with_event_product(
            venue=venue,
            description="Un lit sous une rivière",
            withdrawal_details="A emporter sur place",
            idx=3,
            is_active=True,
            event_name="Event name",
            event_subcategory_id=subcategories.EVENEMENT_MUSIQUE.id,
            thumb_count=1,
            date_created=datetime(2020, 1, 1, 10, 0, 0),
            criteria=[criterion1, criterion2],
        )
        stock1 = create_stock(
            beginning_datetime=in_four_days,
            date_created=datetime(2020, 12, 5, 11, 0, 0),
            offer=offer,
            price=10,
            quantity=10,
        )
        repository.save(stock1)
        humanized_product_id = humanize(offer.product.id)

        # When
        result = AlgoliaBackend.serialize_offer(offer)

        # Then
        result["offer"]["tags"] = set(result["offer"]["tags"])
        assert result == {
            "distinct": "3",
            "objectID": 3,
            "offer": {
                "artist": None,
                "category": "MUSIQUE",
                "dateCreated": 1577872800.0,
                "dates": [1603098000.0],
                "description": "lit sous rivière",
                "id": "AM",
                "isbn": None,
                "isDuo": False,
                "isEducational": False,
                "isDigital": False,
                "isEvent": True,
                "isThing": False,
                "label": "Autre type d'événement musical",
                "name": "Event name",
                "prices": [Decimal("10.00")],
                "rankingWeight": None,
                "searchGroupName": subcategories.SearchGroups.MUSIQUE.name,
                "stocksDateCreated": [1607166000.0],
                "subcategoryId": subcategories.EVENEMENT_MUSIQUE.id,
                "thumbUrl": f"/storage/thumbs/products/{humanized_product_id}",
                "tags": {"Mon tag associé", "Iron Man mon super héros"},
                "times": [32400],
                "visa": None,
            },
            "offerer": {
                "name": "Offerer name",
            },
            "venue": {
                "id": 2,
                "departementCode": "93",
                "name": "Venue name",
                "publicName": "Venue public name",
            },
            "_geoloc": {
                "lat": 48.86387,
                "lng": 2.33802
            },
        }
Example #24
0
def create_industrial_bookings(offers_by_name, users_by_name):
    logger.info("create_industrial_bookings")

    bookings_by_name = {}

    list_of_users_with_no_more_money = []

    token = 100000

    for (user_name, user) in users_by_name.items():
        if (user.firstName != "PC Test Jeune" or "has-signed-up" in user_name
                or "has-filled-cultural-survey" in user_name):
            continue

        user_should_have_no_more_money = "has-no-more-money" in user.email

        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
            if offer_index % OFFER_WITH_BOOKINGS_RATIO != 0:
                continue

            if not offer.venue.managingOfferer.isValidated:
                continue

            user_has_only_activation_booked = (
                "has-booked-activation" in user.email
                or "has-confirmed-activation" in user.email)

            is_activation_offer = offer.product.offerType["value"] == str(
                EventType.ACTIVATION)

            if user_has_only_activation_booked and not is_activation_offer:
                continue

            for (index, stock) in enumerate(offer.stocks):
                # every STOCK_MODULO RECO will have several stocks
                if index > 0 and offer_index % (
                        OFFER_WITH_SEVERAL_STOCKS_REMOVE_MODULO + index):
                    continue

                booking_name = "{} / {} / {}".format(offer_name, user_name,
                                                     str(token))

                is_used = False
                if is_activation_offer:
                    is_used = ("has-confirmed-activation" in user.email
                               or "has-booked-some" in user.email
                               or "has-no-more-money" in user.email)
                else:
                    is_used = offer_index % BOOKINGS_USED_REMOVE_MODULO != 0

                if user_should_have_no_more_money and user not in list_of_users_with_no_more_money:
                    booking_amount = 500
                    list_of_users_with_no_more_money.append(user)
                elif user_should_have_no_more_money and user in list_of_users_with_no_more_money:
                    booking_amount = 0
                else:
                    booking_amount = None

                bookings_by_name[booking_name] = create_booking(
                    user=user,
                    amount=booking_amount,
                    is_used=is_used,
                    stock=stock,
                    token=str(token),
                    venue=offer.venue,
                )

                token += 1

                if bookings_by_name[booking_name].isUsed:
                    bookings_by_name[booking_name].dateUsed = datetime.now()

    repository.save(*bookings_by_name.values())

    logger.info("created %d bookings", len(bookings_by_name))
Example #25
0
def _remove_worker_id_after_venue_provider_sync_error(provider: LocalProvider):
    venue_provider_in_sync = provider.venue_provider
    if venue_provider_in_sync is not None:
        venue_provider_in_sync.syncWorkerId = None
        repository.save(venue_provider_in_sync)
def register_user_session(user_id: int, session_uuid: UUID):
    session = UserSession()
    session.userId = user_id
    session.uuid = session_uuid
    repository.save(session)
Example #27
0
    def test_should_delete_offers_that_are_already_indexed(
        self,
        mock_add_objects,
        mock_build_object,
        mock_delete_objects,
        mock_check_offer_exists,
        mock_get_offer_details,
        mock_add_to_indexed_offers,
        mock_delete_indexed_offers,
        app,
    ):
        # Given
        client = MagicMock()
        client.pipeline = MagicMock()
        client.pipeline.return_value = MagicMock()
        mock_pipeline = client.pipeline()
        mock_pipeline.execute = MagicMock()
        mock_pipeline.reset = MagicMock()
        offerer = create_offerer(is_active=True, validation_token=None)
        venue = create_venue(offerer=offerer, validation_token=None)
        offer1 = create_offer_with_thing_product(thing_name="super offre 1",
                                                 venue=venue,
                                                 is_active=False)
        stock1 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer1,
                              quantity=1)
        offer2 = create_offer_with_thing_product(thing_name="super offre 2",
                                                 venue=venue,
                                                 is_active=False)
        stock2 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer2,
                              quantity=1)
        offer3 = create_offer_with_thing_product(thing_name="super offre 3",
                                                 venue=venue,
                                                 is_active=False)
        stock3 = create_stock(booking_limit_datetime=TOMORROW,
                              offer=offer3,
                              quantity=1)
        repository.save(stock1, stock2, stock3)
        offer_ids = [offer1.id, offer2.id, offer3.id]
        mock_check_offer_exists.side_effect = [True, True, True]

        # When
        process_eligible_offers(client=client,
                                offer_ids=offer_ids,
                                from_provider_update=True)

        # Then
        assert mock_check_offer_exists.call_count == 3
        assert mock_build_object.call_count == 0
        assert mock_add_objects.call_count == 0
        assert mock_get_offer_details.call_count == 0
        assert mock_add_to_indexed_offers.call_count == 0
        assert mock_delete_objects.call_count == 1
        assert mock_delete_objects.call_args_list == [
            call(object_ids=[
                humanize(offer1.id),
                humanize(offer2.id),
                humanize(offer3.id)
            ])
        ]
        assert mock_delete_indexed_offers.call_count == 1
        assert mock_delete_indexed_offers.call_args_list == [
            call(client=client, offer_ids=[offer1.id, offer2.id, offer3.id])
        ]
        assert mock_pipeline.execute.call_count == 0
        assert mock_pipeline.reset.call_count == 0
    def update_model(self, form: Form, model: VenueProvider) -> None:  # pylint: disable=too-many-return-statements
        if form.venue.data.id != model.venue.id:
            flash("Le lieu ne peut pas changer", "error")
            return None

        if model.provider.isAllocine:
            if form.provider.data.id != model.provider.id:
                flash("Le provider de ce lieu ne peut pas être modifié",
                      "error")
                return None

            if form.allocine_price.data is not None or form.allocine_price.data != "":
                price_rule = AllocineVenueProviderPriceRule.query.filter_by(
                    allocineVenueProviderId=model.id).one_or_none()
                if not price_rule:
                    flash("Aucun PriceRule n'a été trouvé")
                    return None
                price_rule.price = form.allocine_price.data
                repository.save(price_rule)

            if form.allocine_quantity.data is not None or form.allocine_quantity.data != "":
                model.quantity = form.allocine_quantity.data

            if form.allocine_is_duo.data is not None or form.allocine_is_duo.data != "":
                model.isDuo = form.allocine_is_duo.data

            venue_provider_job.delay(model.id)
            return super().update_model(form, model)

        if form.provider.data.id == model.provider.id:
            venue_provider_job.delay(model.id)
            return super().update_model(form, model)

        if form.provider.data.isAllocine:
            flash("Le provider ne peut pas être changé pour Allociné", "error")
            return None

        venue_provider = None
        try:
            venue_provider = api.change_venue_provider(
                model,
                form.provider.data.id,
                form.venueIdAtOfferProvider.data,
            )
            venue_provider_job.delay(venue_provider.id)
        except exceptions.VenueSiretNotRegistered as exc:
            flash(
                f"L'identifiant pivot {exc.siret} n'est pas reconnu par {exc.provider_name}.",
                "error",
            )
        except exceptions.NoSiretSpecified:
            flash("Le siret du lieu n'est pas défini, veuillez en définir un",
                  "error")
        except exceptions.ConnexionToProviderApiFailed:
            flash("Problème de connexion à l'API du provider", "error")
        except exceptions.ProviderNotFound:
            flash("Aucun provider actif n'a été trouvé", "error")
        except exceptions.ProviderWithoutApiImplementation:
            flash("Le provider choisi n'implémente pas notre api", "error")
        except exceptions.NoAllocinePivot:
            flash("Aucun AllocinePivot n'est défini pour ce lieu", "error")
        except exceptions.NoPriceSpecified:
            flash("Il est obligatoire de saisir un prix", "error")
        except exceptions.VenueProviderException:
            flash("Le provider n'a pas pu être enregistré", "error")

        return venue_provider
Example #29
0
    def test_should_reindex_offers_only_when_stocks_beginning_datetime_have_changed(
        self,
        mock_add_objects,
        mock_build_object,
        mock_delete_objects,
        mock_check_offer_exists,
        mock_get_offer_details,
        mock_add_to_indexed_offers,
        app,
    ):
        # Given
        client = MagicMock()
        client.pipeline = MagicMock()
        client.pipeline.return_value = MagicMock()
        mock_pipeline = client.pipeline()
        mock_pipeline.execute = MagicMock()
        mock_pipeline.reset = MagicMock()
        offerer = create_offerer(is_active=True, validation_token=None)
        venue = create_venue(offerer=offerer, validation_token=None)
        offer = create_offer_with_event_product(date_created=datetime(
            2019, 1, 1),
                                                event_name="super offre 1",
                                                venue=venue,
                                                is_active=True)
        stock = create_stock(
            beginning_datetime=datetime(2019, 1, 5),
            booking_limit_datetime=datetime(2019, 1, 3),
            offer=offer,
            quantity=1,
        )
        repository.save(stock)
        offer_ids = [offer.id]
        mock_build_object.side_effect = [
            {
                "fake": "object"
            },
        ]
        mock_check_offer_exists.return_value = True
        mock_get_offer_details.return_value = {
            "name": "super offre 1",
            "dates": [1515542400.0],
            "prices": [10.0]
        }

        # When
        process_eligible_offers(client=client,
                                offer_ids=offer_ids,
                                from_provider_update=True)

        # Then
        assert mock_check_offer_exists.call_count == 1
        assert mock_get_offer_details.call_count == 1
        assert mock_add_to_indexed_offers.call_count == 1
        assert mock_add_to_indexed_offers.call_args_list == [
            call(
                pipeline=mock_pipeline,
                offer_details={
                    "name": "super offre 1",
                    "dates": [1546646400.0],
                    "prices": [10.0]
                },
                offer_id=offer.id,
            ),
        ]
        assert mock_add_objects.call_count == 1
        assert mock_add_objects.call_args_list == [
            call(objects=[{
                "fake": "object"
            }])
        ]
        assert mock_pipeline.execute.call_count == 1
        assert mock_pipeline.reset.call_count == 1
        assert mock_delete_objects.call_count == 0
Example #30
0
def save(content: dict, status: EmailStatus):
    email = Email()
    email.content = content
    email.status = status
    email.datetime = format_into_utc_date(datetime.utcnow())
    repository.save(email)