def __init__(self, *args, **kwargs): """Overloaded constructor populating activity list""" super().__init__(*args, **kwargs) activity_list = current_user.get_supervised_activities() self.activity_id.choices = [(0, "Activité...")] self.activity_id.choices += [(a.id, a.name) for a in activity_list]
def csv_import(): activities = current_user.get_supervised_activities() if activities == []: flash("Fonction non autorisée.", "error") return redirect(url_for("event.index")) choices = [(str(a.id), a.name) for a in activities] form = CSVForm(choices) if not form.is_submitted(): form.description.data = current_app.config["DESCRIPTION_TEMPLATE"] failed = [] if form.validate_on_submit(): activity_type = ActivityType.query.get(form.type.data) file = form.csv_file.data processed, failed = process_stream(file.stream, activity_type, form.description.data) flash( f"Importation de {processed-len(failed)} éléments sur {processed}", "message", ) return render_template( "import_csv.html", conf=current_app.config, form=form, failed=failed, title="Création d'event par CSV", )
def leaders(): """API endpoint to list current leaders Only available to administrators and activity supervisors :return: A tuple: - JSON containing information describe in UserSchema - HTTP return code : 200 - additional header (content as JSON) :rtype: (string, int, dict) """ supervised_activities = current_user.get_supervised_activities() query = db.session.query(Role) query = query.filter( Role.role_id.in_( [RoleIds.Trainee, RoleIds.EventLeader, RoleIds.ActivitySupervisor])) query = query.filter( Role.activity_id.in_(a.id for a in supervised_activities)) query = query.join(Role.user) query = query.order_by(User.last_name, User.first_name, User.id) response = LeaderRoleSchema(many=True).dump(query.all()) return json.dumps(response), 200, {"content-type": "application/json"}
def csv_import(): activities = current_user.get_supervised_activities() if activities == []: flash('Fonction non autorisée.', 'error') return redirect(url_for('event.index')) choices = [(str(a.id), a.name) for a in activities] form = CSVForm(choices) if not form.is_submitted(): form.description.data = current_app.config['DESCRIPTION_TEMPLATE'] if not form.validate_on_submit(): return render_template('import_csv.html', conf=current_app.config, form=form, title="Création d'event par CSV") activity_type = ActivityType.query.get(form.type.data) file = form.csv_file.data processed, failed = process_stream(file.stream, activity_type, form.description.data) flash(f'Importation de {processed-failed} éléments sur {processed}', 'message') return redirect(url_for('event.csv_import'))
def filter_hidden_events(query): """Update a SQLAlchemy query object with a filter that removes Event with a status that the current use is not allowed to see - Moderators can see all events - Normal users cannot see 'Pending' events - Activity supervisors can see 'Pending' events for the activities that they supervise - Leaders can see the events that they lead :param query: The original query :type query: :py:class:`sqlalchemy.orm.query.Query` :return: The filtered query :rtype: :py:class:`sqlalchemy.orm.query.Query` """ # Display pending events only to relevant persons if not current_user.is_authenticated: # Not logged users see no pending event query = query.filter(Event.status != EventStatus.Pending) elif current_user.is_moderator(): # Admin see all pending events (no filter) pass else: # Regular user can see non Pending query_filter = Event.status != EventStatus.Pending # If user is a supervisor, it can see Pending events of its activities if current_user.is_supervisor(): # Supervisors can see all sup activities = current_user.get_supervised_activities() activities_ids = [a.id for a in activities] supervised = Event.activity_types.any( ActivityType.id.in_(activities_ids)) query_filter = or_(query_filter, supervised) # If user can create event, it can see its pending events if current_user.can_create_events(): lead = Event.leaders.any(id=current_user.id) query_filter = or_(query_filter, lead) # After filter construction, it is applied to the query query = query.filter(query_filter) return query
def remove_trainee(role_id): """Route for an activity supervisor to remove a "Trainee" role :param role_id: Id of role to delete :type role_id: int """ role = Role.query.get(role_id) if role is None or role.role_id != RoleIds.Trainee: flash("Role invalide", "error") return redirect(url_for(".leader_list")) if role.activity_type not in current_user.get_supervised_activities(): flash("Non autorisé", "error") return redirect(url_for(".leader_list")) db.session.delete(role) db.session.commit() return redirect(url_for(".leader_list"))
def add_trainee(): """Route for an activity supervisor to add a "Trainee" role" """ add_trainee_form = AddTraineeForm() if add_trainee_form.validate_on_submit(): role = Role(role_id=RoleIds.Trainee) add_trainee_form.populate_obj(role) supervised_activity_ids = [ a.id for a in current_user.get_supervised_activities() ] if role.activity_id not in supervised_activity_ids: flash("Activité invalide", "error") return redirect(url_for(".manage_trainees")) user = User.query.get(role.user_id) if user is None: flash("Utilisateur invalide", "error") return redirect(url_for(".manage_trainees")) if user.has_role_for_activity( [RoleIds.Trainee, RoleIds.EventLeader], role.activity_id, ): flash( "L'utilisateur est déjà initiateur ou initiateur en formation pour cette activité", "error", ) return redirect(url_for(".manage_trainees")) db.session.add(role) db.session.commit() add_trainee_form = AddTraineeForm(formdata=None) return render_template( "trainees.html", conf=current_app.config, add_trainee_form=add_trainee_form, title="Initiateurs en formation", )
def events(): page = int(request.args.get('page')) size = int(request.args.get('size')) # Initialize query query = Event.query # Display pending events only to relevant persons if not current_user.is_authenticated: # Not logged users see no pending event query = query.filter(Event.status != EventStatus.Pending) elif current_user.is_admin(): # Admin see all pending events (no filter) pass else: # Regular user can see non Pending filter = Event.status != EventStatus.Pending # If user is a supervisor, it can see Pending events of its activities if current_user.is_supervisor(): # Supervisors can see all sup activities = current_user.get_supervised_activities() activities_ids = [a.id for a in activities] supervised = Event.activity_types.any( ActivityType.id.in_(activities_ids)) filter = or_(filter, supervised) # If user can create event, it can see its pending events if current_user.can_create_events(): lead = Event.leaders.any(id=current_user.id) filter = or_(filter, lead) # After filter construction, it is applied to the query query = query.filter(filter) # Process all filters. # All filter are added as AND i = 0 while f'filters[{i}][field]' in request.args: value = request.args.get(f'filters[{i}][value]') field = request.args.get(f'filters[{i}][field]') if field == 'activity_type': filter = Event.activity_types.any(short=value) if field == 'end': filter = Event.end >= value if field == 'status': filter = Event.status == value query = query.filter(filter) # Get next filter i += 1 # Process first sorter only if f'sorters[0][field]' in request.args: sort_field = request.args.get('sorters[0][field]') sort_dir = request.args.get('sorters[0][dir]') order = desc(sort_field) if sort_dir == 'desc' else sort_field query = query.order_by(order) paginated_events = query.paginate(page, size, False) data = EventSchema(many=True).dump(paginated_events.items) response = {'data': data, "last_page": paginated_events.pages} return json.dumps(response), 200, {'content-type': 'application/json'}
def events(): page = int(request.args.get("page")) size = int(request.args.get("size")) # Initialize query query = Event.query # Display pending events only to relevant persons if not current_user.is_authenticated: # Not logged users see no pending event query = query.filter(Event.status != EventStatus.Pending) elif current_user.is_admin(): # Admin see all pending events (no filter) pass else: # Regular user can see non Pending query_filter = Event.status != EventStatus.Pending # If user is a supervisor, it can see Pending events of its activities if current_user.is_supervisor(): # Supervisors can see all sup activities = current_user.get_supervised_activities() activities_ids = [a.id for a in activities] supervised = Event.activity_types.any( ActivityType.id.in_(activities_ids)) query_filter = or_(query_filter, supervised) # If user can create event, it can see its pending events if current_user.can_create_events(): lead = Event.leaders.any(id=current_user.id) query_filter = or_(query_filter, lead) # After filter construction, it is applied to the query query = query.filter(query_filter) # Process all filters. # All filter are added as AND i = 0 while f"filters[{i}][field]" in request.args: value = request.args.get(f"filters[{i}][value]") filter_type = request.args.get(f"filters[{i}][type]") field = request.args.get(f"filters[{i}][field]") if field == "status": value = getattr(EventStatus, value) query_filter = None if field == "activity_type": query_filter = Event.activity_types.any(short=value) elif field == "end": if filter_type == ">=": query_filter = Event.end >= current_time() elif field == "status": if filter_type == "=": query_filter = Event.status == value elif filter_type == "!=": query_filter = Event.status != value if query_filter is not None: query = query.filter(query_filter) # Get next filter i += 1 # Process first sorter only if "sorters[0][field]" in request.args: sort_field = request.args.get("sorters[0][field]") sort_dir = request.args.get("sorters[0][dir]") order = desc(sort_field) if sort_dir == "desc" else sort_field query = query.order_by(order) paginated_events = query.paginate(page, size, False) data = EventSchema(many=True).dump(paginated_events.items) response = {"data": data, "last_page": paginated_events.pages} return json.dumps(response), 200, {"content-type": "application/json"}