def build_data_for_offer_webapp_link(user: User, offer: Offer) -> dict: return { "MJ-TemplateID": 2826195, "MJ-TemplateLanguage": True, "Vars": { "offer_webapp_link": offer_webapp_link(offer), "user_first_name": user.firstName, "offer_name": offer.name, "venue_name": offer.venue.name, }, }
def get_offer_notification_data(user_id: int, offer: Offer) -> TransactionalNotificationData: return TransactionalNotificationData( group_id=GroupId.OFFER_LINK.value, user_ids=[user_id], message=TransactionalNotificationMessage( title=f"{offer.name}", body="Pour réserver, c'est par ici !", ), extra={"deeplink": offer_webapp_link(offer)}, )
def serialize_educational_booking(educational_booking: EducationalBooking) -> EducationalBookingResponse: booking = educational_booking.booking stock = booking.stock offer = stock.offer venue = offer.venue return EducationalBookingResponse( address=venue.address, beginningDatetime=stock.beginningDatetime, cancellationDate=booking.cancellationDate, cancellationLimitDate=booking.cancellationLimitDate, city=venue.city, confirmationDate=educational_booking.confirmationDate, confirmationLimitDate=educational_booking.confirmationLimitDate, coordinates={ "latitude": venue.latitude, "longitude": venue.longitude, }, creationDate=booking.dateCreated, description=offer.description, durationMinutes=offer.durationMinutes, expirationDate=booking.expirationDate, id=educational_booking.id, image={"url": offer.image.url, "credit": offer.image.credit} if offer.image else None, isDigital=offer.isDigital, venueName=venue.name, name=offer.name, postalCode=venue.postalCode, price=booking.amount, quantity=booking.quantity, redactor={ "email": educational_booking.educationalRedactor.email, "redactorFirstName": educational_booking.educationalRedactor.firstName, "redactorLastName": educational_booking.educationalRedactor.lastName, "redactorCivility": educational_booking.educationalRedactor.civility, }, UAICode=educational_booking.educationalInstitution.institutionId, yearId=educational_booking.educationalYearId, status=get_education_booking_status(educational_booking), venueTimezone=venue.timezone, totalAmount=booking.total_amount, url=offer_webapp_link(offer), withdrawalDetails=offer.withdrawalDetails, )
def make_offer_creation_notification_email(offer: Offer) -> dict: author = offer.author or offer.venue.managingOfferer.UserOfferers[0].user venue = offer.venue pro_link_to_offer = f"{settings.PRO_URL}/offres/{humanize(offer.id)}/edition" pro_venue_link = f"{settings.PRO_URL}/structures/{humanize(venue.managingOffererId)}/lieux/{humanize(venue.id)}" webapp_link_to_offer = offer_webapp_link(offer) html = render_template( "mails/offer_creation_notification_email.html", offer=offer, venue=venue, author=author, pro_link_to_offer=pro_link_to_offer, webapp_link_to_offer=webapp_link_to_offer, pro_venue_link=pro_venue_link, ) location_information = offer.venue.departementCode or "numérique" return { "Html-part": html, "FromName": "pass Culture", "Subject": f"[Création d’offre - {location_information}] {offer.name}", }
def test_confirm_prebooking(self, app, db_session) -> None: redactor = EducationalRedactorFactory( civility="Mme", firstName="Jeanne", lastName="Dodu", email="*****@*****.**", ) educational_institution = EducationalInstitutionFactory() educational_year = EducationalYearFactory(adageId="1") EducationalDeposit( educationalInstitution=educational_institution, educationalYear=educational_year, amount=Decimal(1400.00), isFinal=True, ) EducationalBookingFactory( amount=Decimal(20.00), quantity=20, educationalBooking__educationalInstitution=educational_institution, educationalBooking__educationalYear=educational_year, status=BookingStatus.CONFIRMED, ) booking = EducationalBookingFactory( amount=Decimal(20.00), quantity=20, educationalBooking__educationalInstitution=educational_institution, educationalBooking__educationalYear=educational_year, educationalBooking__educationalRedactor=redactor, status=BookingStatus.PENDING, educationalBooking__confirmationLimitDate=datetime( 2021, 10, 15, 10), ) client = TestClient(app.test_client()).with_eac_token() response = client.post( f"/adage/v1/prebookings/{booking.educationalBookingId}/confirm") assert response.status_code == 200 stock = booking.stock offer = stock.offer venue = offer.venue educational_booking = booking.educationalBooking assert response.json == { "address": venue.address, "beginningDatetime": format_into_utc_date(stock.beginningDatetime), "cancellationDate": None, "cancellationLimitDate": format_into_utc_date(booking.cancellationLimitDate), "city": venue.city, "confirmationDate": "2021-10-15T09:00:00Z", "confirmationLimitDate": format_into_utc_date(educational_booking.confirmationLimitDate), "coordinates": { "latitude": float(venue.latitude), "longitude": float(venue.longitude), }, "creationDate": format_into_utc_date(booking.dateCreated), "description": offer.description, "durationMinutes": offer.durationMinutes, "expirationDate": booking.expirationDate, "id": educational_booking.id, "image": None, "isDigital": offer.isDigital, "venueName": venue.name, "name": offer.name, "postalCode": venue.postalCode, "price": booking.amount, "quantity": booking.quantity, "redactor": { "email": "*****@*****.**", "redactorFirstName": "Jeanne", "redactorLastName": "Dodu", "redactorCivility": "Mme", }, "UAICode": educational_booking.educationalInstitution.institutionId, "yearId": int(educational_booking.educationalYearId), "status": "CONFIRMED", "venueTimezone": venue.timezone, "totalAmount": booking.total_amount, "url": offer_webapp_link(offer), "withdrawalDetails": offer.withdrawalDetails, } assert Booking.query.filter( Booking.id == booking.id).one().status == BookingStatus.CONFIRMED
def test_offer_webapp_link_when_webapp_V2_enabled(self): offer = offers_factories.OffererFactory() link = offer_webapp_link(offer) assert link == generate_firebase_dynamic_link(path=f"offre/{offer.id}", params=None)
def test_offer_webapp_link_when_webapp_V2_not_enabled(self): offer = offers_factories.OffererFactory() link = offer_webapp_link(offer) assert link == f"{settings.WEBAPP_URL}/offre/details/{humanize(offer.id)}"
def test_get_educational_institution(self, app) -> None: redactor = EducationalRedactorFactory( civility="M.", firstName="Jean", lastName="Doudou", email="*****@*****.**", ) educational_year = EducationalYearFactory() educational_institution = EducationalInstitutionFactory() EducationalDepositFactory( educationalInstitution=educational_institution, educationalYear=educational_year, amount=2000, isFinal=True, ) EducationalInstitutionFactory() booking = EducationalBookingFactory( educationalBooking__educationalRedactor=redactor, educationalBooking__educationalYear=educational_year, educationalBooking__educationalInstitution=educational_institution, ) other_educational_year = EducationalYearFactory(adageId="toto") other_educational_institution = EducationalInstitutionFactory( institutionId="tata") EducationalBookingFactory( educationalBooking__educationalYear=other_educational_year) EducationalBookingFactory(educationalBooking__educationalInstitution= other_educational_institution) EducationalDepositFactory( educationalInstitution=educational_institution, educationalYear=other_educational_year, amount=2000, isFinal=False, ) EducationalDepositFactory( educationalInstitution=other_educational_institution, educationalYear=educational_year, amount=2000, isFinal=False, ) client = TestClient(app.test_client()).with_eac_token() response = client.get( f"/adage/v1/years/{educational_year.adageId}/educational_institution/{educational_institution.institutionId}" ) assert response.status_code == 200 stock = booking.stock offer = stock.offer venue = offer.venue educational_booking = booking.educationalBooking assert response.json == { "credit": 2000, "isFinal": True, "prebookings": [{ "address": venue.address, "beginningDatetime": format_into_utc_date(stock.beginningDatetime), "cancellationDate": None, "cancellationLimitDate": format_into_utc_date(booking.cancellationLimitDate), "city": venue.city, "confirmationDate": format_into_utc_date(educational_booking.confirmationDate) if educational_booking.confirmationDate else None, "confirmationLimitDate": format_into_utc_date( educational_booking.confirmationLimitDate), "coordinates": { "latitude": float(venue.latitude), "longitude": float(venue.longitude), }, "creationDate": format_into_utc_date(booking.dateCreated), "description": offer.description, "durationMinutes": offer.durationMinutes, "expirationDate": booking.expirationDate, "id": educational_booking.id, "image": { "url": offer.image.url, "credit": offer.image.credit } if offer.image else None, "isDigital": offer.isDigital, "venueName": venue.name, "name": offer.name, "postalCode": venue.postalCode, "price": booking.amount, "quantity": booking.quantity, "redactor": { "email": "*****@*****.**", "redactorFirstName": "Jean", "redactorLastName": "Doudou", "redactorCivility": "M.", }, "UAICode": educational_booking.educationalInstitution.institutionId, "yearId": int(educational_booking.educationalYearId), "status": "CONFIRMED", "venueTimezone": venue.timezone, "totalAmount": booking.amount * booking.quantity, "url": offer_webapp_link(offer), "withdrawalDetails": offer.withdrawalDetails, }], }
def test_mark_prebooking_as_used(self, app) -> None: redactor = EducationalRedactorFactory( civility="M.", firstName="Jean", lastName="Doudou", email="*****@*****.**", ) booking = EducationalBookingFactory( educationalBooking__educationalRedactor=redactor, status=BookingStatus.CONFIRMED, ) client = TestClient(app.test_client()).with_eac_token() response = client.post( f"/adage/v1/prebookings/{booking.educationalBooking.id}/mark_as_used" ) assert response.status_code == 200 stock = booking.stock offer = stock.offer venue = offer.venue educational_booking = booking.educationalBooking assert response.json == { "address": venue.address, "beginningDatetime": format_into_utc_date(stock.beginningDatetime), "cancellationDate": None, "cancellationLimitDate": format_into_utc_date(booking.cancellationLimitDate), "city": venue.city, "confirmationDate": None, "confirmationLimitDate": format_into_utc_date(educational_booking.confirmationLimitDate), "coordinates": { "latitude": float(venue.latitude), "longitude": float(venue.longitude), }, "creationDate": format_into_utc_date(booking.dateCreated), "description": offer.description, "durationMinutes": offer.durationMinutes, "expirationDate": booking.expirationDate, "id": educational_booking.id, "image": None, "isDigital": offer.isDigital, "venueName": venue.name, "name": offer.name, "postalCode": venue.postalCode, "price": booking.amount, "quantity": booking.quantity, "redactor": { "email": "*****@*****.**", "redactorFirstName": "Jean", "redactorLastName": "Doudou", "redactorCivility": "M.", }, "UAICode": educational_booking.educationalInstitution.institutionId, "yearId": int(educational_booking.educationalYearId), "status": "USED_BY_INSTITUTE", "venueTimezone": venue.timezone, "totalAmount": booking.total_amount, "url": offer_webapp_link(offer), "withdrawalDetails": offer.withdrawalDetails, }
def test_refuse_prebooking(self, app) -> None: redactor = EducationalRedactorFactory( civility="M.", firstName="Jean", lastName="Doudou", email="*****@*****.**", ) stock: Stock = EventStockFactory(quantity=200, dnBookedQuantity=0) booking = EducationalBookingFactory( educationalBooking__educationalRedactor=redactor, status=BookingStatus.CONFIRMED, stock=stock, quantity=20, ) client = TestClient(app.test_client()).with_eac_token() response = client.post( f"/adage/v1/prebookings/{booking.educationalBookingId}/refuse") assert response.status_code == 200 booking = Booking.query.one() stock = booking.stock offer = stock.offer venue = offer.venue educational_booking = booking.educationalBooking assert response.json == { "address": venue.address, "beginningDatetime": format_into_utc_date(stock.beginningDatetime), "cancellationDate": "2022-11-17T15:00:00Z", "cancellationLimitDate": format_into_utc_date(booking.cancellationLimitDate), "city": venue.city, "confirmationDate": None, "confirmationLimitDate": format_into_utc_date(educational_booking.confirmationLimitDate), "coordinates": { "latitude": float(venue.latitude), "longitude": float(venue.longitude), }, "creationDate": format_into_utc_date(booking.dateCreated), "description": offer.description, "durationMinutes": offer.durationMinutes, "expirationDate": booking.expirationDate, "id": educational_booking.id, "image": None, "isDigital": offer.isDigital, "venueName": venue.name, "name": offer.name, "postalCode": venue.postalCode, "price": booking.amount, "quantity": booking.quantity, "redactor": { "email": "*****@*****.**", "redactorFirstName": "Jean", "redactorLastName": "Doudou", "redactorCivility": "M.", }, "UAICode": educational_booking.educationalInstitution.institutionId, "yearId": int(educational_booking.educationalYearId), "status": "REFUSED", "venueTimezone": venue.timezone, "totalAmount": booking.total_amount, "url": offer_webapp_link(offer), "withdrawalDetails": offer.withdrawalDetails, } # It should be 0 because on booking factory creation it goes to 20, then on cancellation it goes 20-20 assert stock.dnBookedQuantity == 0 assert booking.status == BookingStatus.CANCELLED assert booking.cancellationReason == BookingCancellationReasons.REFUSED_BY_INSTITUTE