def referral(apptid):

    appt = appt_manager.search_by_id(int(apptid))
    user = user_manager.get_user(current_user.get_id())

    if type(user) is Provider:
        identity = user_manager.get_user(appt.provider_email)
    else:
        identity = user_manager.get_user(appt.patient_email)
    correct_identity(identity, user)

    specialist = user_manager.specialists()
    if request.method == 'POST':
        patient = user_manager.get_user(appt.patient_email)
        spec = request.form['ref_tgt']
        gp = appt.provider_email
        msg = request.form['ref_msg']
        patient.add_referral(spec, gp, msg)
        print(patient.referrals)
        print(spec)
        user_manager.save_data()
        content = {"spec": spec, "patient": patient.email, "msg": msg}
        return render_template('referral.html',
                               apptid=apptid,
                               specialist=specialist,
                               content=content)

    return render_template('referral.html',
                           apptid=apptid,
                           specialist=specialist)
def provider_profile(provider):
    """
	Renders a provider profile
	:param user: a Provider email
	:return: renders the provider_profile.html template
	"""
    try:
        p = user_manager.get_user(provider)
    except IdentityError as e:
        raise e

    if request.method == 'POST':
        rating = int(request.form['rate'])
        p.add_rating(current_user.get_id(), rating)
        user_manager.save_data()
    content = p.get_information()
    centre_name_to_id = {}
    for centre in content['centres']:
        try:
            centre_obj = centre_manager.get_centre_from_name(centre)
            centre_name_to_id[centre] = centre_obj.id
        except IdentityError:
            pass  # Still want to present profile page if centre returns error
    return render_template('provider_profile.html',
                           content=content,
                           centres=centre_name_to_id)
def view_appointment(apptid):

    try:
        appt = appt_manager.search_by_id(int(apptid))
    except IdentityError as e:
        raise e

    edit = False
    gp = False
    user = user_manager.get_user(current_user.get_id())
    if type(user) is Provider:
        identity = user_manager.get_user(appt.provider_email)
        if appt.past is False:
            edit = True
        if user.service == "gp":
            gp = True
    else:
        identity = user_manager.get_user(appt.patient_email)

    if permissions.check_permissions(current_user.get_id(),
                                     appt.patient_email):
        pass
    elif user.email == appt.patient_email:
        pass
    elif not correct_identity(identity, user):
        raise IdentityError("Wrong user for Appointment")

    if request.method == 'POST':
        if request.form['notes']:
            appt.notes = {
                'provider': current_user.get_id(),
                'notes': request.form['notes']
            }
        if request.form['meds']:
            appt.add_meds(request.form["meds"])
        user_manager.save_data()
        appt_manager.save_data()

    content = appt.get_information()
    prov = user_manager.get_user(appt.provider_email)
    content['prov_name'] = " ".join([prov.given_name, prov.surname])
    patient = user_manager.get_user(content['patient_email'])
    content['patient_name'] = " ".join([patient.given_name, patient.surname])
    content['centre_name'] = centre_manager.get_centre_from_id(
        content['centre_id']).name
    content['meds'] = ", ".join(content['meds'])

    can_edit = permissions.check_permissions(current_user.get_id(),
                                             content['patient_email'])

    return render_template('appointment.html',
                           content=content,
                           edit=edit,
                           gp=gp,
                           has_permission=can_edit,
                           curr_user=current_user.get_id())
def user_profile():
    """
	Renders Current User's Profile
	:return: user_profile.html if all works out
	"""
    user = load_user(current_user.get_id())
    provider = False
    content = user.get_information()
    if type(user) is Provider:
        provider = True
    if request.args.get('edit'):
        return render_template('user_profile.html',
                               content=content,
                               edit=True,
                               provider=provider)

    if request.method == 'POST':
        if request.form['given_name']:
            user.given_name = request.form['given_name']
        if request.form['surname']:
            user.surname = request.form['surname']
        if provider is False:
            if request.form['medicare_no']:
                user.medicare_no = request.form['medicare_no']
        content = user.get_information()
        user_manager.save_data()

    if provider:
        centre_name_to_id = {}
        for centre in content['centres']:
            centre_obj = centre_manager.get_centre_from_name(centre)
            centre_name_to_id[centre] = centre_obj.id
        return render_template('user_profile.html',
                               content=content,
                               provider=provider,
                               centres=centre_name_to_id)

    return render_template('user_profile.html',
                           content=content,
                           provider=provider)
def book_confirmation(provider, centre, date, time_slot, reason):
    """
	Submmits Booking request
	:param provider: a provider email
	:param centre: a centre id
	:param date: a date in form of string
	:param time_slot: string
	:param reason: string
	:return: redirects to index function if all works out, otherwise 'Something Wrong?'
	"""
    # if date_and_time_valid(time_slot, date) == False:
    # 	raise BookingError("Invalid date or time")

    # Check that provider and centre exist
    try:
        p = user_manager.get_user(provider)
    except IdentityError as e:
        raise e
    try:
        c = centre_manager.get_centre_from_id(centre)
    except IdentityError as e:
        raise e

    # Check that provider is associated with centre
    if c.name.lower() not in p.centres:
        raise BookingError("Provider isn't associated with centre")

    # make appointment object
    #
    try:
        appt = appt_manager.make_appt_and_add_appointment_to_manager(
            current_user.email, provider, centre, date, time_slot, reason)
    except BookingError as e:
        raise e
    except DateTimeValidityError as e:
        raise e

    if appt not in appt_manager.appointments:
        raise BookingError("Booking isn't being saved")
    # Add appts object to patient and provider
    current_user.add_appointment(appt)
    if appt not in current_user.appointments:
        raise BookingError("Booking isn't being saved in current user")

    p.add_appointment(appt)
    if appt not in p.appointments:
        raise BookingError("Booking isn't being saved in provider")

    if p.specialist is True:
        user = user_manager.get_user(current_user.email)
        try:
            user.rem_referral(p.email)
        except:
            pass  #Do not want system to crash on exception, system can go on without this

    # Make time slot unavailable
    date_split = date.split('-')
    year = int(date_split[0])
    month = int(date_split[1])
    day = int(date_split[2])
    try:
        p.make_time_slot_unavailable(c.name, year, month, day, time_slot)
    except BookingError as e:
        appt_manager.remove_appointment(appt.id)
        raise e
    except DateTimeValidityError as e:
        appt_manager.remove_appointment(appt.id)
        raise e

    user_manager.save_data()
    appt_manager.save_data()

    # send notification to patient
    notifications_manager.add_notification(provider, current_user.get_id())

    return render_template(
        'booking_confirmed.html',
        prov_name=user_manager.get_user(appt.provider_email).fullname,
        centre_name=centre_manager.get_centre_from_name(c.name).name,
        date=appt.date,
        time=appt.time_slot)