def patch_occasion(occasionType, occasionId): model_name = inflect_engine.singular_noun(occasionType.title(), 1) # UPDATE THE OCCASION occasion = app.model[model_name].query\ .filter_by(id=dehumanize(occasionId))\ .first_or_404() occasion_dict = request.json.get('occasion') if occasion_dict: update(occasion, occasion_dict) app.model.PcObject.check_and_save(occasion) first_occurence = occasion.occurences[0] venue = first_occurence.venue offerer = venue.managingOfferer # UPDATE CORRESPONDING EVENT OCCURENCES event_occurences = request.json.get('eventOccurences') if event_occurences: for event_occurence_dict in event_occurences: if event_occurence_dict.get('DELETE') == '_delete_': app.model.Offer\ .query\ .filter_by(eventOccurenceId=dehumanize(event_occurence_dict['id']))\ .delete() app.model.EventOccurence\ .query\ .filter_by(id=dehumanize(event_occurence_dict['id']))\ .delete() app.db.session.commit() else: create_event_occurence(event_occurence_dict, occasion, offerer, venue) return jsonify(occasion._asdict(include=OCCASION_INCLUDES)), 200
def test_12_if_i_request_a_specific_reco_it_should_be_first(): # Full request subtest_recos_with_params('occasionType=event&occasionId=AE&mediationId=AM', expected_status=200, expected_mediation_id=dehumanize('AM'), expected_occasion_type='event', expected_occasion_id=dehumanize('AE')) # No mediationId but occasionId subtest_recos_with_params('occasionType=event&occasionId=AE', expected_status=200, expected_mediation_id=dehumanize('AM'), expected_occasion_type='event', expected_occasion_id=dehumanize('AE')) # No occasionId but mediationId and occasionType subtest_recos_with_params('occasionType=event&mediationId=AE', expected_status=200, expected_mediation_id=dehumanize('AM'), expected_occasion_type='event', expected_occasion_id=dehumanize('AE')) # No occasionId, no occasionType, but mediationId subtest_recos_with_params('mediationId=AE', expected_status=200, expected_mediation_id=dehumanize('AM'), expected_occasion_type='event', expected_occasion_id=dehumanize('AE')) # no occasionType but mediationId and occasionId subtest_recos_with_params('occasionId=AE&mediationId=AM', expected_status=200, expected_mediation_id=dehumanize('AM'), expected_occasion_type='event', expected_occasion_id=dehumanize('AE'))
def post_occasion(occasionType): model_name = inflect_engine.singular_noun(occasionType.title(), 1) # CREATE THE OCCASION (EVENT OR THING) occasion = app.model[model_name]() occasion_dict = request.json['occasion'] update(occasion, occasion_dict) app.model.PcObject.check_and_save(occasion) # DETERMINE OFFERER offerer = app.model.Offerer.query\ .filter_by(id=dehumanize(occasion_dict['offererId']))\ .first_or_404() # DETERMINE VENUE venue = app.model.Venue.query\ .filter_by(id=dehumanize(occasion_dict['venueId']))\ .first_or_404() # CREATE CORRESPONDING EVENT OCCURENCES event_occurences = request.json.get('eventOccurences') if event_occurences: for event_occurence_dict in event_occurences: create_event_occurence(event_occurence_dict, occasion, offerer, venue) return jsonify(occasion._asdict(include=OCCASION_INCLUDES)), 201
def patch_offerer(offererId): ensure_current_user_has_rights(RightsType.admin, dehumanize(offererId)) data = request.json check_valid_edition(data) offerer = Offerer.query.filter_by(id=dehumanize(offererId)).first() offerer.populate_from_dict(data, skipped_keys=['validationToken']) recommendations = find_all_recommendations_for_offerer(offerer) invalidate_recommendations_if_deactivating_object(data, recommendations) PcObject.save(offerer) return jsonify(get_dict_offerer(offerer)), 200
def when_creating_new_thing_offer(self, app): # Given user = create_user(email='*****@*****.**') offerer = create_offerer() user_offerer = create_user_offerer(user, offerer) venue = create_venue(offerer, is_virtual=True, siret=None) thing_product = create_product_with_thing_type() PcObject.save(user, venue, thing_product, user_offerer) offerer_id = offerer.id json = { 'type': 'ThingType.JEUX_VIDEO', 'name': 'Les lapins crétins', 'mediaUrls': ['http://media.url'], 'url': 'http://jeux.fr/offre', 'venueId': humanize(venue.id), 'bookingEmail': '*****@*****.**' } # When response = TestClient(app.test_client()).with_auth(user.email).post( f'{API_URL}/offers', json=json) # Then assert response.status_code == 201 offer_id = dehumanize(response.json['id']) offer = Offer.query.filter_by(id=offer_id).first() assert offer.bookingEmail == '*****@*****.**' assert response.json['product']['offerType'] == { 'conditionalFields': [], 'description': 'Résoudre l’énigme d’un jeu de piste dans votre ville ? ' 'Jouer en ligne entre amis ? ' 'Découvrir cet univers étrange avec une manette ?', 'proLabel': 'Jeux vidéo', 'appLabel': 'Jeux vidéo', 'offlineOnly': False, 'onlineOnly': True, 'sublabel': 'Jouer', 'type': 'Thing', 'value': 'ThingType.JEUX_VIDEO' } offer_id = dehumanize(response.json['id']) offer = Offer.query.filter_by(id=offer_id).first() assert offer.bookingEmail == '*****@*****.**' assert offer.venueId == venue.id thing_id = dehumanize(response.json['product']['id']) thing_product = Product.query.filter_by(id=thing_id).first() assert thing_product.name == 'Les lapins crétins' assert offer.type == str(ThingType.JEUX_VIDEO) assert thing_product.url == 'http://jeux.fr/offre' assert offer.url == 'http://jeux.fr/offre' assert offer.isDigital assert offer.isNational assert thing_product.isNational assert offer.product.owningOfferer == Offerer.query.get(offerer_id)
def get_recommendation(offer_id): try: recommendation = give_requested_recommendation_to_user( current_user, dehumanize(offer_id), dehumanize(request.args.get('mediationId'))) except OfferNotFoundException: errors = ResourceNotFound() errors.add_error('global', "Offre ou médiation introuvable") raise errors return jsonify(_serialize_recommendation(recommendation)), 200
def when_creating_a_new_event_offer(self, app): # Given user = create_user(email='*****@*****.**') offerer = create_offerer() venue = create_venue(offerer) user_offerer = create_user_offerer(user, offerer) PcObject.save(user, user_offerer, venue) offerer_id = offerer.id json = { 'venueId': humanize(venue.id), 'bookingEmail': '*****@*****.**', 'name': 'La pièce de théâtre', 'durationMinutes': 60, 'type': str(EventType.SPECTACLE_VIVANT) } # When response = TestClient(app.test_client()).with_auth(user.email).post( f'{API_URL}/offers', json=json) # Then assert response.status_code == 201 assert response.json['product']['offerType'] == { 'conditionalFields': ["author", "showType", "stageDirector", "performer"], 'description': 'Suivre un géant de 12 mètres dans la ville ? ' 'Rire aux éclats devant un stand up ? ' 'Rêver le temps d’un opéra ou d’un spectacle de danse ? ' 'Assister à une pièce de théâtre, ' 'ou se laisser conter une histoire ?', 'proLabel': 'Spectacle vivant', 'appLabel': 'Spectacle vivant', 'offlineOnly': True, 'onlineOnly': False, 'sublabel': 'Applaudir', 'type': 'Event', 'value': 'EventType.SPECTACLE_VIVANT' } assert response.json['isEvent'] is True assert response.json['isThing'] is False offer_id = dehumanize(response.json['id']) offer = Offer.query.filter_by(id=offer_id).first() assert offer.bookingEmail == '*****@*****.**' assert offer.venueId == venue.id event_id = dehumanize(response.json['product']['id']) event_product = Product.query.filter_by(id=event_id).first() assert event_product.durationMinutes == 60 assert event_product.name == 'La pièce de théâtre' assert offer.type == str(EventType.SPECTACLE_VIVANT) assert offer.product.owningOfferer == Offerer.query.get(offerer_id)
def create_mediation(): check_thumb_in_request(files=request.files, form=request.form) offerer_id = dehumanize(request.form['offererId']) offer_id = dehumanize(request.form['offerId']) credit = request.form.get('credit') ensure_current_user_has_rights(RightsType.editor, offerer_id) mediation = create_new_mediation(offer_id, offerer_id, current_user, credit) thumb = read_thumb(files=request.files, form=request.form) check_thumb_quality(thumb) PcObject.save(mediation) save_thumb(mediation, thumb, 0, crop=_get_crop(request.form)) return jsonify(as_dict(mediation)), 201
def post_booking(): offer_id = request.json.get('offerId') ae = ApiErrors() if current_user.canBook == False: ae.addError('canBook', 'L\'utilisateur n\'a pas le droit de réserver d\'offre') return jsonify(ae.errors), 400 if offer_id is None: ae.addError('offerId', 'Vous devez préciser un identifiant d\'offre') return jsonify(ae.errors), 400 offer = Offer.query.filter_by(id=dehumanize(offer_id)).first() if offer is None: ae.addError('offerId', 'offerId ne correspond à aucune offer') return jsonify(ae.errors), 400 if offer.bookingLimitDatetime is not None and\ offer.bookingLimitDatetime < datetime.utcnow(): ae.addError( 'global', 'la date limite de réservation de cette offre' + ' est dépassée') return jsonify(ae.errors), 400 new_booking = Booking() new_booking.offerId = dehumanize(offer_id) token = random_token() new_booking.token = token new_booking.user = current_user recommendation_id = request.json.get('recommendationId') if recommendation_id is not None: new_booking.recommendationId = dehumanize(recommendation_id) try: app.model.PcObject.check_and_save(new_booking) except InternalError as ie: if 'check_booking' in str(ie.orig): ae.addError( 'global', 'la quantité disponible pour cette offre' + ' est atteinte') return jsonify(ae.errors), 400 else: raise ie send_booking_recap_emails(app.model.Offer.query.get(new_booking.offerId), new_booking) return jsonify(new_booking._asdict(include=BOOKINGS_INCLUDES, venueTz=True)), 201
def from_venue_without_SIRET_application(cls, response: dict) -> dict: application_details = dict() application_details['BIC'] = cls._find_value_in_fields(response['dossier']["champs"], "BIC") application_details['IBAN'] = cls._find_value_in_fields(response['dossier']["champs"], "IBAN") application_details['applicationId'] = response['dossier']["id"] application_details['updated_at'] = datetime.strptime(response['dossier']["updated_at"], DATE_ISO_FORMAT) url = cls._find_value_in_fields(response['dossier']["champs"], "URL") human_structure_id = url.split('/')[-3] human_venue_id = url.split('/')[-1] application_details['structureId'] = dehumanize(human_structure_id) application_details['venueId'] = dehumanize(human_venue_id) return application_details
def get_bookings_csv(): only_digital_venues = request.args.get('onlyDigitalVenues', False) try: venue_id = dehumanize(request.args.get('venueId', None)) offer_id = dehumanize(request.args.get('offerId', None)) except ValueError: errors = ApiErrors() errors.add_error('global', 'Les identifiants sont incorrects') errors.status_code = 400 raise errors try: if request.args.get('dateFrom', None): date_from = dateutil.parser.parse(request.args.get('dateFrom')) else: date_from = None if request.args.get('dateTo', None): date_to = dateutil.parser.parse(request.args.get('dateTo')) else: date_to = None except ValueError: errors = ApiErrors() errors.add_error('global', 'Les dates sont incorrectes') errors.status_code = 400 raise errors check_rights_to_get_bookings_csv(current_user, venue_id, offer_id) query = filter_query_where_user_is_user_offerer_and_is_validated( Offerer.query, current_user) if only_digital_venues: bookings = chain(*list( map( lambda offerer: find_all_digital_bookings_for_offerer( offerer.id, offer_id, date_from, date_to), query))) else: bookings = chain(*list( map( lambda offerer: find_all_offerer_bookings( offerer.id, venue_id, offer_id, date_from, date_to), query))) bookings_csv = generate_bookings_details_csv(bookings) return bookings_csv.encode('utf-8-sig'), \ 200, \ {'Content-type': 'text/csv; charset=utf-8;', 'Content-Disposition': 'attachment; filename=reservations_pass_culture.csv'}
def patch_booking_by_token(token): email = request.args.get('email', None) offer_id = dehumanize(request.args.get('offer_id', None)) booking_token_upper_case = token.upper() booking = booking_queries.find_by(booking_token_upper_case, email, offer_id) if current_user.is_authenticated: ensure_current_user_has_rights( RightsType.editor, booking.stock.resolvedOffer.venue.managingOffererId) else: check_email_and_offer_id_for_anonymous_user(email, offer_id) check_booking_is_usable(booking) if check_is_activation_booking(booking): activate_user(booking.user) send_activation_notification_email(booking.user, send_raw_email) booking.isUsed = True booking.dateUsed = datetime.utcnow() PcObject.save(booking) return '', 204
def test_16_openagenda_events_provider(): with app.app_context(): oa_provider = app.model.Provider.getByClassName('OpenAgendaEvents') venueProvider = app.model.VenueProvider() venueProvider.venueId = dehumanize('AE') venueProvider.provider = oa_provider venueProvider.isActive = True venueProvider.venueIdAtOfferProvider = '49050769' app.model.PcObject.check_and_save(venueProvider) venueProvider = app.model.VenueProvider.query\ .filter_by(venueIdAtOfferProvider='49050769')\ .one_or_none() provider_test(app.local_providers.OpenAgendaEvents, venueProvider, checkedObjects=15, createdObjects=15, updatedObjects=0, erroredObjects=0, checkedThumbs=3, createdThumbs=3, updatedThumbs=0, erroredThumbs=0, Event=3, EventOccurence=12, Offer=0, Venue=0, Offerer=0)
def update_read_recommendations(read_recommendations): if read_recommendations: for read_recommendation in read_recommendations: recommendation_id = dehumanize(read_recommendation['id']) Recommendation.query.filter_by(id=recommendation_id) \ .update({"dateRead": read_recommendation['dateRead']}) db.session.commit()
def when_creating_a_new_event_offer_without_booking_email(self, app): # Given user = create_user(email='*****@*****.**') offerer = create_offerer() venue = create_venue(offerer) user_offerer = create_user_offerer(user, offerer) PcObject.save(user, user_offerer, venue) json = { 'venueId': humanize(venue.id), 'name': 'La pièce de théâtre', 'durationMinutes': 60, 'type': str(EventType.SPECTACLE_VIVANT) } # When response = TestClient(app.test_client()).with_auth(user.email).post( f'{API_URL}/offers', json=json) # Then offer_id = dehumanize(response.json['id']) offer = Offer.query.filter_by(id=offer_id).first() assert response.status_code == 201 assert offer.bookingEmail == None
def populateFromDict(self, dct): data = dct.copy() if data.__contains__('id'): del data['id'] cols = self.__class__.__table__.columns._data for key in data.keys(): if key == 'deleted': continue if cols.__contains__(key): col = cols[key] if key.endswith('Id'): value = dehumanize(data.get(key)) else: value = data.get(key) if isinstance(value, str) and isinstance(col.type, db.Integer): try: setattr(self, key, Decimal(value)) except InvalidOperation as io: raise TypeError( 'Invalid value for %s: %r' % (key, value), 'integer', key) elif isinstance(value, str) and (isinstance(col.type, db.Float) or isinstance(col.type, db.Numeric)): try: setattr(self, key, Decimal(value)) except InvalidOperation as io: raise TypeError( 'Invalid value for %s: %r' % (key, value), 'decimal', key) else: setattr(self, key, value)
def when_user_has_rights_on_managing_offerer_and_has_siret(self, app): # given offerer = create_offerer(siren='302559178') user = create_user(email='*****@*****.**') user_offerer = create_user_offerer(user, offerer) PcObject.save(user_offerer) auth_request = TestClient( app.test_client()).with_auth(email=user.email) venue_data = { 'name': 'Ma venue', 'siret': '30255917810045', 'address': '75 Rue Charles Fourier, 75013 Paris', 'postalCode': '75200', 'bookingEmail': '*****@*****.**', 'city': 'Paris', 'managingOffererId': humanize(offerer.id), 'latitude': 48.82387, 'longitude': 2.35284, 'publicName': 'Ma venue publique' } # when response = auth_request.post('/venues', json=venue_data) # then assert response.status_code == 201 id = response.json['id'] venue = Venue.query.filter_by(id=dehumanize(id)).one() assert venue.name == 'Ma venue' assert venue.publicName == 'Ma venue publique' assert venue.siret == '30255917810045' assert venue.isValidated
def get_user_offerer(offerer_id): user_offerers = UserOfferer.query.filter_by( user=current_user, offererId=dehumanize(offerer_id)).all() return jsonify([ as_dict(user_offerer, includes=USER_OFFERER_INCLUDES) for user_offerer in user_offerers ]), 200
def get_occasion(occasionType, occasionId): model_name = inflect_engine.singular_noun(occasionType.title(), 1) occasion = app.model[model_name]\ .query.filter_by(id=dehumanize(occasionId))\ .first_or_404() occasion_dict = occasion._asdict(include=OCCASION_INCLUDES) return jsonify(occasion_dict)
def patch_booking(booking_id): is_cancelled = request.json.get('isCancelled') if is_cancelled is not True: api_errors = ApiErrors() api_errors.add_error( 'isCancelled', "Vous pouvez seulement changer l'état isCancelled à vrai") raise api_errors booking = booking_queries.find_by_id(dehumanize(booking_id)) is_user_cancellation = booking.user == current_user check_booking_is_cancellable(booking, is_user_cancellation) booking_offerer = booking.stock.resolvedOffer.venue.managingOffererId is_offerer_cancellation = current_user.hasRights(RightsType.editor, booking_offerer) if not is_user_cancellation and not is_offerer_cancellation: return "Vous n'avez pas le droit d'annuler cette réservation", 403 booking.isCancelled = True PcObject.save(booking) try: send_cancellation_emails_to_user_and_offerer(booking, is_offerer_cancellation, is_user_cancellation, send_raw_email) except MailServiceException as e: app.logger.error('Mail service failure', e) return jsonify( as_dict(booking, includes=WEBAPP_PATCH_POST_BOOKING_INCLUDES)), 200
def end_activity(activity_id): activity_id = dehumanize(activity_id) EndActivity().execute(activity_id=activity_id, user_id=int(current_user.get_id())) result = dict({"success": "yes"}) return jsonify(result)
def when_booking_limit_datetime_is_none_for_thing(self, app): # Given user = create_user(email='*****@*****.**', can_book_free_offers=False, is_admin=True) offerer = create_offerer() venue = create_venue(offerer) offer = create_offer_with_thing_product(venue) PcObject.save(user, offer) data = { 'price': 0, 'offerId': humanize(offer.id), 'bookingLimitDatetime': None } # When response = TestClient(app.test_client()).with_auth(user.email) \ .post('/stocks', json=data) # Then assert response.status_code == 201 assert response.json["price"] == 0 assert response.json["bookingLimitDatetime"] is None id = response.json['id'] stock = Stock.query.filter_by(id=dehumanize(id)).first() assert stock.price == 0 assert stock.bookingLimitDatetime is None
def put_read_recommendations(): update_read_recommendations(request.json) read_recommendation_ids = [dehumanize(reco['id']) for reco in request.json] read_recommendations = Recommendation.query.filter( Recommendation.id.in_(read_recommendation_ids)).all() return jsonify(_serialize_recommendations(read_recommendations)), 200
def get_offerer(id): dehumanize_id = dehumanize(id) for offerer in current_user.offerers: if offerer.id == dehumanize_id: return jsonify(offerer._asdict(include=OFFERERS_INCLUDES)), 200 e = ApiErrors() e.addError('global', "Cette structure n'est pas enregistrée chez cet utilisateur.") return jsonify(e.errors), 400
def test_results_are_paginated_by_default_on_page_1(self, app): # given user = create_user(email='*****@*****.**') create_offers_for(user, 20) auth_request = TestClient( app.test_client()).with_auth(email='*****@*****.**') offers = auth_request.get('/offers').json first_id = dehumanize(offers[0]['id']) # when response = auth_request.get('/offers?page=1') # then result = response.json assert response.status_code == 200 assert dehumanize(result[0]['id']) == first_id assert 'validationToken' not in result[0]['venue']
def put_recommendations(): json_keys = request.json.keys() if 'readRecommendations' in json_keys: update_read_recommendations(request.json['readRecommendations'] or []) if 'seenRecommendationIds' in json_keys: humanized_seen_recommendation_ids = request.json[ 'seenRecommendationIds'] or [] seen_recommendation_ids = list( map(dehumanize, humanized_seen_recommendation_ids)) else: seen_recommendation_ids = [] offer_id = dehumanize(request.args.get('offerId')) mediation_id = dehumanize(request.args.get('mediationId')) try: requested_recommendation = give_requested_recommendation_to_user( current_user, offer_id, mediation_id) except OfferNotFoundException: return "Offer or mediation not found", 404 logger.debug(lambda: '(special) requested_recommendation %s' % requested_recommendation) created_recommendations = create_recommendations_for_discovery( BLOB_SIZE, user=current_user) logger.debug( lambda: '(new recos)' + str([(reco, reco.mediation, reco.dateRead) for reco in created_recommendations])) logger.debug(lambda: '(new reco) count %i', len(created_recommendations)) recommendations = move_tutorial_recommendations_first( created_recommendations, seen_recommendation_ids, current_user) if requested_recommendation: recommendations = move_requested_recommendation_first( created_recommendations, requested_recommendation) logger.debug(lambda: '(recap reco) ' + str( [(reco, reco.mediation, reco.dateRead, reco.offer) for reco in recommendations]) + str(len(recommendations))) return jsonify(_serialize_recommendations(recommendations)), 200
def find_stocks_with_possible_filters(filters, user): query = Stock.queryNotSoftDeleted() if 'offererId' in filters: query = query.filter( Stock.offererId == dehumanize(filters['offererId'])) _check_offerer_user(query.first_or_404().offerer.query, user) if 'hasPrice' in filters and filters['hasPrice'].lower() == 'true': query = query.filter(Stock.price != None) return query
def delete_favorite(offer_id): dehumanized_offer_id = dehumanize(offer_id) favorite = find_favorite_for_offer_and_user(dehumanized_offer_id, current_user.id) \ .first_or_404() PcObject.delete(favorite) return jsonify(as_dict(favorite)), 200
def validate_new_venue_provider_information(payload: json): errors = ApiErrors() errors.status_code = 400 if 'venueIdAtOfferProvider' not in payload: errors.add_error('venueIdAtOfferProvider', 'Ce champ est obligatoire') if 'venueId' not in payload: errors.add_error('venueId', 'Ce champ est obligatoire') if 'providerId' not in payload: errors.add_error('providerId', 'Ce champ est obligatoire') errors.maybe_raise() provider_id = dehumanize(payload.get('providerId')) venue_id = dehumanize(payload.get('venueId')) venue_id_at_offer_provider = payload.get('venueIdAtOfferProvider') _validate_existing_provider(provider_id) _validate_existing_venue_provider(provider_id, venue_id, venue_id_at_offer_provider)
def list_offers(): offerer_id = dehumanize(request.args.get('offererId')) venue_id = dehumanize(request.args.get('venueId')) venue = venue_queries.find_by_id(venue_id) check_venue_exists_when_requested(venue, venue_id) check_user_has_rights_for_query(offerer_id, venue, venue_id) query = find_offers_with_filter_parameters( current_user, offerer_id=offerer_id, venue_id=venue_id, keywords_string=request.args.get('keywords')) return handle_rest_get_list(Offer, query=query, order_by='offer.id desc', includes=OFFER_INCLUDES, paginate=10, page=request.args.get('page'))