def cancel_bookings(bookings: list[Booking]) -> None: for booking in bookings: booking.mark_as_unused_set_confirmed() repository.save(*bookings)
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()
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 }, }
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)
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
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
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
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")
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
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)
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, }, }
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
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
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", )
def has_completed_id_check(user: User) -> None: user.hasCompletedIdCheck = True repository.save(user) update_external_user(user)
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
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 }, }
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))
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)
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
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
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)