def edit_restaurant(id_op, rest_id):
    """This method allows the operator to edit the information about his restaurant

    Args:
        id_op (int): univocal identifier of the operator
        rest_id (int): univocal identifier of the restaurant

    Returns:
        Returns the page of the restaurant's details
    """
    form = RestaurantForm()
    restaurant = RestaurantManager.retrieve_by_id(rest_id)

    if request.method == "POST":
        if form.is_submitted():
            name = form.data['name']
            restaurant.set_name(name)
            address = form.data['address']
            restaurant.set_address(address)
            city = form.data['city']
            restaurant.set_city(city)
            phone = form.data['phone']
            restaurant.set_phone(phone)
            menu_type = form.data['menu_type']
            restaurant.set_menu_type(menu_type)

            RestaurantManager.update_restaurant(restaurant)
            return redirect(url_for('auth.operator', id=id_op))

    return render_template('update_restaurant.html', form=form)
def create_reservation(restaurant_id):
    """This method allows the customer to create a new reservation, on a specific restaurant,
    depending on its opening hours and the available tables

    Args:
        restaurant_id (int): univocal identifier of the restaurant
    
    """
    if current_user.type == 'customer':
        form = ReservationForm()
        restaurant = RestaurantManager.retrieve_by_id(restaurant_id)
        if request.method == 'POST':
            if form.validate_on_submit():
                start_date = form.data['start_date']
                start_time = form.data['start_time']
                people_number = form.data['people_number']
                start_time_merged = datetime.combine(start_date, start_time)
                table = validate_reservation(restaurant, start_time_merged,
                                             people_number)
                if table != False:
                    reservation = Reservation(current_user, table, restaurant,
                                              people_number, start_time_merged)
                    ReservationManager.create_reservation(reservation)
                    return redirect(
                        url_for('reservation.customer_my_reservation'))
                else:
                    flash(
                        "There aren't free tables for that hour or the restaurant is close"
                    )
            else:
                flash("Take a look to the inserted data")
        return render_template('create_reservation.html',
                               restaurant=restaurant,
                               form=form)
    return redirect(url_for('home.index'))
def save_time(id_op, rest_id):
    """This method gives the operator the possibility to add opening hours to his restaurant

    Args:
        id_op (int): univocal identifier of the operator
        rest_id (int): univocal identifier of the restaurant

    Returns:
        Returns the page of the restaurant's details
    """
    time_form = TimesForm()
    restaurant = RestaurantManager.retrieve_by_id(rest_id)
    availabilities = restaurant.availabilities
    present = False
    if request.method == "POST":
        if time_form.is_submitted():
            day = time_form.data['day']
            start_time = time_form.data['start_time']
            end_time = time_form.data['end_time']
            if end_time > start_time:
                for ava in availabilities:
                    if ava.day == day:
                        ava.set_times(start_time, end_time)
                        RestaurantAvailabilityManager.update_availability(ava)
                        present = True
                if not present:
                    time = RestaurantAvailability(rest_id, day, start_time,
                                                  end_time)
                    RestaurantAvailabilityManager.create_availability(time)

    return redirect(url_for('restaurants.details', id_op=id_op))
def notifications():
    """[summary]

    Returns:
        [type]: [description]
    """
    notifications = NotificationManager.retrieve_by_target_user_id(current_user.id)
    processed_notification_info = []
    if current_user.type == "customer":
        for notification in notifications:
            restaurant_name = RestaurantManager.retrieve_by_id(notification.contagion_restaurant_id).name
            processed_notification_info.append({"timestamp": notification.timestamp,
                                                 "contagion_datetime": notification.contagion_datetime,
                                                 "contagion_restaurant_name": restaurant_name})
        return render_template('customer_notifications.html', current_user=current_user, notifications=processed_notification_info)
    elif current_user.type == "operator":
        for notification in notifications:
            info = {"timestamp": notification.timestamp,
                    "contagion_datetime": notification.contagion_datetime}
            is_future = notification.timestamp < notification.contagion_datetime
            info['is_future'] = is_future
            if is_future:
                customer_phone_number = UserManager.retrieve_by_id(notification.positive_customer_id).phone
                info['customer_phone_number'] = customer_phone_number
            processed_notification_info.append(info)
        return render_template('operator_notifications.html', current_user=current_user, notifications=processed_notification_info)
def reservation_all(restaurant_id):
    """Returns the whole list of reservations, given a restaurant.
    It also gives to the operator the opportunity to filter reservations
    by date, so it's possible to count people.

    Args:
        restaurant_id (int): univocal identifier of the restaurant

    Returns:
        The template of the reservations.
    """
    filter_form = FilterForm()
    reservations = ReservationManager.retrieve_by_restaurant_id(restaurant_id)
    restaurant = RestaurantManager.retrieve_by_id(restaurant_id)
    people = 0
    for r in reservations:
        if r.is_confirmed:
            people = people + r.people_number

    if request.method == 'POST':
        if filter_form.is_submitted():
            filter_date = filter_form.data['filter_date']
            start_time = filter_form.data['start_time']
            end_time = filter_form.data['end_time']

            if filter_date is not None and start_time is not None and end_time is not None:
                start_date_time = datetime.combine(filter_date, start_time)
                end_date_time = datetime.combine(filter_date, end_time)
                res = ReservationManager.retrieve_by_date_and_time(
                    restaurant_id, start_date_time, end_date_time)
                people = 0
                for r in res:
                    if r.is_confirmed:
                        people = people + r.people_number

                return render_template("restaurant_reservation.html",
                                       restaurant=restaurant,
                                       reservations=res,
                                       filter_form=filter_form,
                                       people=people)
            else:
                flash("The form is not correct")
    reservations.sort(key=lambda reservation: reservation.start_time)
    return render_template("restaurant_reservation.html",
                           restaurant=restaurant,
                           reservations=reservations,
                           filter_form=filter_form,
                           people=people)
def restaurant_sheet(restaurant_id):
    """This method returns the single page for a restaurant

    Args:
        restaurant_id (int): univocal identifier of the restaurant
    """
    restaurant = RestaurantManager.retrieve_by_id(id_=restaurant_id)

    if restaurant is None:
        return abort(404)

    list_measure = restaurant.measures.split(',')
    average_rate = RestaurantRatingManager.calculate_average_rate(restaurant)

    return render_template(
        "restaurantsheet.html",
        restaurant=restaurant,
        list_measures=list_measure[1:],
        average_rate=average_rate,
        max_rate=RestaurantRating.MAX_VALUE,
    )
def edit_reservation(reservation_id, customer_id):
    """Allows the customer to edit a single reservation,
    if there's an available table within the opening hours
    of the restaurant.

    Args:
        reservation_id (int): univocal identifier of the reservation
        customer_id (int): univocal identifier of the customer

    Returns:
        Redirects the view to the customer profile page.
    """
    form = ReservationForm()
    reservation = ReservationManager.retrieve_by_customer_id(
        user_id=customer_id)[0]
    restaurant = RestaurantManager.retrieve_by_id(reservation.restaurant_id)

    if request.method == 'POST':
        if form.validate_on_submit():
            start_date = form.data['start_date']
            start_time = form.data['start_time']
            people_number = form.data['people_number']
            start_time_merged = datetime.combine(start_date, start_time)
            table = validate_reservation(restaurant, start_time_merged,
                                         people_number)
            if table != False:
                reservation.set_people_number(people_number)
                reservation.set_start_time(start_time_merged)
                reservation.set_table(table)
                ReservationManager.update_reservation(reservation)
            else:
                flash(
                    "There aren't free tables for that hour or the restaurant is closed"
                )
        else:
            flash("The form is not correct")

    return redirect(url_for('auth.profile', id=customer_id))
def contact_tracing(contact_id):
    """This method allows the health authority to retrieve the list of
    contacts, given a positive user

    Args:
        contact_id (id): univocal id of the user

    Returns:
        Redirects the view to the health authority's home page
    """
    if current_user is not None and current_user.type == 'authority':
        customer = CustomerManager.retrieve_by_id(id_=contact_id)
        if customer is not None:
            pos_reservations = ReservationManager.retrieve_by_customer_id(
                user_id=customer.id)
            cust_contacts = []
            restaurant_contacts = []
            date_contacts = []
            for res in pos_reservations:
                contacts = ReservationManager.retrieve_all_contact_reservation_by_id(
                    res.id)
                for c in contacts:
                    cust = CustomerManager.retrieve_by_id(c.user_id)
                    cust_contacts.append(cust)
                    restaurant_contacts.append(
                        RestaurantManager.retrieve_by_id(c.restaurant_id).name)
                    date_contacts.append(c.start_time.date())
            return render_template('contact_tracing_positive.html',
                                   customer=customer,
                                   pos_contact=cust_contacts,
                                   res_contact=restaurant_contacts,
                                   date_contact=date_contacts)
        else:
            return redirect(
                url_for('auth.authority', id=current_user.id, positive_id=0))
    else:
        return redirect(url_for('home.index'))