def filter_out_timeslots_with_existing_bookings(available_timeslots, provider, request_timeslot): ''' Remove provider's booking from the list of available timeslots for the day of the request ''' day_start = datetime.combine(request_timeslot.start.date(), time(0, 0, 0)) day_end = datetime.combine(request_timeslot.start.date(), time(23, 59, 59)) # request_day_confirmed_bookings = Booking.query( Booking.provider == provider.key, Booking.datetime > day_start, Booking.datetime < day_end).fetch() logging.debug('bookings for today: %s' % request_day_confirmed_bookings) # Hack, bookings are considered to be 1 hour long # TODO Add end_datetime in Booking to generalize this booking_datetimes = map(lambda b: b.datetime, request_day_confirmed_bookings) booking_timeslots = map(create_one_hour_timeslot, booking_datetimes) logging.debug("booking timeslots: %s" % booking_timeslots) # filter out previous booking engagements logging.debug("available_timeslots: %s" % available_timeslots) available_timeslots_without_conflicts = filter( lambda a: a not in booking_timeslots, available_timeslots) logging.debug("conflicts removed: %s" % available_timeslots_without_conflicts) return available_timeslots_without_conflicts
def test_find_providers_perfect_and_imperfect(self): providers = create_test_providers() logging.info("providers: %s" % providers) self.assertEqual(len(providers), Provider.query().count()) # create booking request next_monday_at_9 = testutil.create_datetime_from_weekday_and_hour( testutil.MONDAY, 15) booking_request = Booking(request_category='physiotherapy', request_location='mtl-downtown', request_datetime=next_monday_at_9) booking_responses = db_search.provider_search(booking_request) logging.info('Booking Respones:') for br in booking_responses: logging.info('providers %s on %s at %s' % (br.provider.email, br.timeslot.start.date(), br.timeslot.start.time())) # 2 responses self.assertEqual(2, len(booking_responses)) # first provider is perfet match br1 = booking_responses[0] self.assertTrue(br1.is_perfect_match(booking_request)) # second provider is not perfect match br2 = booking_responses[1] self.assertFalse(br2.is_perfect_match(booking_request)) # assert top provider is p2 self.assertEqual(providers[2][0], booking_responses[0].provider.key)
def test_find_providers_no_matches_wrong_category(self): providers = create_test_providers() # create booking request - Saturday at 10 PM sat_at_10 = testutil.create_datetime_from_weekday_and_hour(5, 22) booking_request = Booking(request_category='osteopath', request_location='mtl-downtown', request_datetime=sat_at_10) booking_responses = db_search.provider_search(booking_request) logging.info('Booking Respones:') # assert top provider is p2 self.assertEqual(0, len(booking_responses))
def check_activation_email_patient(self): ''' 1) receive confirmation email 2) clicks profile activation link 3) sets a password ''' # check email messages = self.mail_stub.get_sent_messages(to=self._TEST_PATIENT_EMAIL) self.assertEqual(1, len(messages)) m = messages[0] patient = Patient.query(Patient.email == self._TEST_PATIENT_EMAIL).get() booking = Booking.query(Booking.patient == patient.key).get() self.assertEqual(m.subject, 'Rendez-vous Veosan - %s' % 'Ostéopathe') # assert that activation link is in the email body user = User.query(User.key == patient.user).get() self.assertTrue('http://localhost/user/activation/%s' % user.signup_token in m.body.payload) # click link in email activation_response = self.testapp.get('/user/activation/%s' % str(user.signup_token)) # choose a password activation_response.mustcontain('Votre rendez-vous est confirmé') activation_response.mustcontain("Fantastic Fox") booking = Booking.query(Booking.patient == patient.key).get() activation_response_form = activation_response.forms[0] activation_response_form['password'] = self._TEST_PATIENT_PASSWORD activation_response_form['password_confirm'] = self._TEST_PATIENT_PASSWORD booking_confirm_page = activation_response_form.submit() # patient email in navbar booking_confirm_page.mustcontain(self._TEST_PATIENT_EMAIL) # Title check booking_confirm_page.mustcontain('You new appointment is confirmed!')
def test_find_providers_all_imperfect_matches(self): providers = create_test_providers() # create booking request - Saturday at 10 PM sat_at_10 = testutil.create_datetime_from_weekday_and_hour( testutil.MONDAY, 22) booking_request = Booking(request_category='physiotherapy', request_location='mtl-downtown', request_datetime=sat_at_10) booking_responses = db_search.provider_search(booking_request) logging.info('Booking Respones:') for br in booking_responses: logging.info('providers %s on %s at %s' % (br.provider.email, br.timeslot.start.date(), br.timeslot.start.time())) for br in booking_responses: self.assertFalse(br.is_perfect_match(booking_request)) # assert top provider is p2 self.assertEqual(providers[1][0], booking_responses[0].provider.key)
def filter_out_timeslots_with_existing_bookings(available_timeslots, provider, request_timeslot): ''' Remove provider's booking from the list of available timeslots for the day of the request ''' day_start = datetime.combine(request_timeslot.start.date(), time(0, 0, 0)) day_end = datetime.combine(request_timeslot.start.date(), time(23, 59, 59)) # request_day_confirmed_bookings = Booking.query(Booking.provider==provider.key, Booking.datetime > day_start, Booking.datetime < day_end).fetch() logging.debug('bookings for today: %s' % request_day_confirmed_bookings) # Hack, bookings are considered to be 1 hour long # TODO Add end_datetime in Booking to generalize this booking_datetimes = map(lambda b: b.datetime, request_day_confirmed_bookings) booking_timeslots = map(create_one_hour_timeslot, booking_datetimes) logging.debug("booking timeslots: %s" % booking_timeslots) # filter out previous booking engagements logging.debug("available_timeslots: %s" % available_timeslots) available_timeslots_without_conflicts = filter(lambda a: a not in booking_timeslots, available_timeslots) logging.debug("conflicts removed: %s" % available_timeslots_without_conflicts) return available_timeslots_without_conflicts
def testFindBestProviderForBooking(self): testCategory = u'physiotherapy' testLocation = u'montreal-west' # create provider p = Provider() p.terms_agreement = True p.status = 'client_enabled' p.first_name = 'Best-Test' p.last_name = 'Phys-Io' p.category = testCategory p.location = testLocation p.vanity_url = 'physio_guy' pkey = p.put() # add a provider's schedule (Thursday Morning) s = Schedule() s.day = 'thursday' s.start_time = 8 s.end_time = 12 s.provider = p.key s.put() # create provider with no schedule p = Provider() p.first_name = 'NoSchedule' p.last_name = 'Phys-Io' p.category = testCategory p.location = testLocation pkey2 = p.put() # 2 providers in db self.assertEqual(2, Provider.query().count(), '2 providers in datastore') # create booking b = Booking() b.request_category = testCategory b.request_location = testLocation b.request_datetime = datetime.strptime('2012-04-26 10', '%Y-%m-%d %H') b.put() # test the matching brs = db_search.provider_search(b) logging.info('best provider:' + str(brs)) # assert self.assertIsNotNone(brs, 'provider should not be None') self.assertEqual(pkey, brs[0].provider.key, 'provider keys should be equal')
def testFindBestProviderForBooking(self): testCategory = u'physiotherapy' testLocation = u'montreal-west' # create provider p = Provider() p.terms_agreement=True p.status = 'client_enabled' p.first_name = 'Best-Test' p.last_name = 'Phys-Io' p.category = testCategory p.location = testLocation p.vanity_url = 'physio_guy' pkey = p.put() # add a provider's schedule (Thursday Morning) s = Schedule() s.day = 'thursday' s.start_time = 8 s.end_time = 12 s.provider = p.key s.put() # create provider with no schedule p = Provider() p.first_name = 'NoSchedule' p.last_name = 'Phys-Io' p.category = testCategory p.location = testLocation pkey2 = p.put() # 2 providers in db self.assertEqual(2, Provider.query().count(), '2 providers in datastore') # create booking b = Booking() b.request_category = testCategory b.request_location = testLocation b.request_datetime = datetime.strptime('2012-04-26 10', '%Y-%m-%d %H') b.put(); # test the matching brs = db_search.provider_search(b) logging.info('best provider:' + str(brs)) # assert self.assertIsNotNone(brs, 'provider should not be None') self.assertEqual(pkey, brs[0].provider.key, 'provider keys should be equal')
def post(self, vanity_url=None): ''' Booking process from public profile ''' appointment_details_form = None provider = db.get_provider_from_vanity_url(vanity_url) user = self.get_current_user() if user: appointment_details_form = AppointmentDetailsForLoggedInUser( ).get_form(self.request.POST, provider=provider) else: appointment_details_form = AppointmentDetails().get_form( self.request.POST, provider=provider) provider = db.get_provider_from_vanity_url(vanity_url) if appointment_details_form.validate(): # create the booking object booking = Booking() booking.provider = provider.key booking.booking_source = 'profile' booking_date = appointment_details_form['booking_date'].data booking_time = appointment_details_form['booking_time'].data booking.datetime = to_utc( datetime.strptime(booking_date + " " + booking_time, '%Y-%m-%d %H:%M')) booking.comments = appointment_details_form['comments'].data schedule = db.get_schedule_for_date_time(provider, booking_date, booking_time) booking.schedule = schedule.key if appointment_details_form.__contains__('service'): service_key_from_form = appointment_details_form[ 'service'].data if service_key_from_form: service_key = ndb.Key(urlsafe=service_key_from_form) provider_service = service_key.get() if provider_service: booking.service = service_key if user: # user is logged in, is this a patient? existing_patient = db.get_patient_from_user(user) if existing_patient: booking.patient = existing_patient.key else: self.link_user_to_new_patient(appointment_details_form, user, booking) # confirm the booking since it is a "known" user booking.confirmed = True booking.email_sent_to_patient = False booking.email_sent_to_provider = False # save booking booking.put() # already logged in so go directly to bookings list self.redirect('/patient/bookings/' + booking.patient.urlsafe()) # mail it to the patient mail.email_booking_to_patient(self, booking) # mail it to the provider mail.email_booking_to_provider(self, booking) else: # no user is logged in, check if the email address exists, this means they just didn't log in email = appointment_details_form['email'].data existing_user = db.get_user_from_email(email) if existing_user: existing_patient = db.get_patient_from_user(existing_user) if existing_patient: # email is in datastore, but not logged in # link booking to existing patient booking.patient = existing_patient.key booking.put() else: self.link_user_to_new_patient(appointment_details_form, user, booking) # confirm the booking since it is a "known" user booking.confirmed = True booking.email_sent_to_patient = False booking.email_sent_to_provider = False # save booking booking.put() # get the user to login key = booking.key.urlsafe() self.redirect('/login/booking/' + key) else: # no patient, no user. get them to fill a profile in the form booking.put() patient_form = RegistrationDetailsForNewPatient().get_form( ) patient_form['terms_agreement'].data = True patient_form['booking_date'].data = booking_date patient_form['booking_time'].data = booking_time patient_form['booking_key'].data = booking.key.urlsafe() patient_form['email'].data = email self.render_template( 'provider/public/booking_new_patient.html', provider=provider, patient_form=patient_form) logging.info('Created booking from public profile: %s' % booking) else: self.render_template('provider/public/booking_details.html', provider=provider, booking_form=appointment_details_form)
def get_bookings_for_patient(patient): return Booking.query(Booking.patient == patient.key).fetch()
def fetch_bookings(): return Booking.query().order(-Booking.created_on)
def post(self, vanity_url=None): ''' Booking process from public profile ''' appointment_details_form = None provider = db.get_provider_from_vanity_url(vanity_url) user = self.get_current_user() if user: appointment_details_form = AppointmentDetailsForLoggedInUser().get_form(self.request.POST, provider=provider) else: appointment_details_form = AppointmentDetails().get_form(self.request.POST, provider=provider) provider = db.get_provider_from_vanity_url(vanity_url) if appointment_details_form.validate(): # create the booking object booking = Booking() booking.provider = provider.key booking.booking_source = 'profile' booking_date = appointment_details_form['booking_date'].data booking_time = appointment_details_form['booking_time'].data booking.datetime = to_utc(datetime.strptime(booking_date + " " + booking_time, '%Y-%m-%d %H:%M')) booking.comments = appointment_details_form['comments'].data schedule = db.get_schedule_for_date_time(provider, booking_date, booking_time) booking.schedule = schedule.key if appointment_details_form.__contains__('service'): service_key_from_form = appointment_details_form['service'].data if service_key_from_form: service_key = ndb.Key(urlsafe=service_key_from_form) provider_service = service_key.get() if provider_service: booking.service = service_key if user: # user is logged in, is this a patient? existing_patient = db.get_patient_from_user(user) if existing_patient: booking.patient = existing_patient.key else: self.link_user_to_new_patient(appointment_details_form, user, booking) # confirm the booking since it is a "known" user booking.confirmed = True booking.email_sent_to_patient = False booking.email_sent_to_provider = False # save booking booking.put() # already logged in so go directly to bookings list self.redirect('/patient/bookings/' + booking.patient.urlsafe()) # mail it to the patient mail.email_booking_to_patient(self, booking) # mail it to the provider mail.email_booking_to_provider(self, booking) else: # no user is logged in, check if the email address exists, this means they just didn't log in email = appointment_details_form['email'].data existing_user = db.get_user_from_email(email) if existing_user: existing_patient = db.get_patient_from_user(existing_user) if existing_patient: # email is in datastore, but not logged in # link booking to existing patient booking.patient = existing_patient.key booking.put() else: self.link_user_to_new_patient(appointment_details_form, user, booking) # confirm the booking since it is a "known" user booking.confirmed = True booking.email_sent_to_patient = False booking.email_sent_to_provider = False # save booking booking.put() # get the user to login key = booking.key.urlsafe() self.redirect('/login/booking/' + key) else: # no patient, no user. get them to fill a profile in the form booking.put() patient_form = RegistrationDetailsForNewPatient().get_form() patient_form['terms_agreement'].data = True patient_form['booking_date'].data = booking_date patient_form['booking_time'].data = booking_time patient_form['booking_key'].data = booking.key.urlsafe() patient_form['email'].data = email self.render_template('provider/public/booking_new_patient.html', provider=provider, patient_form=patient_form) logging.info('Created booking from public profile: %s' % booking) else: self.render_template('provider/public/booking_details.html', provider=provider, booking_form=appointment_details_form)