diff --git a/app.py b/app.py index 9e3ef00..e889e0e 100644 --- a/app.py +++ b/app.py @@ -229,6 +229,8 @@ def solar_register_post(): user_id = portal.solar.register_new_user(name, email, password, active=False) portal.solar.add_user_to_institution(user_id, institution_id, institution_role) + portal.solar.add_cooperation_history_item(user_id, institution_id, institution_role) + portal.solar.send_admins_new_user_notification_mail(user_id, upload_handler_solar.config) flash('Podatki so bili poslani v potrditev. Ko bo registracija potrjena, boste o tem obveščeni po e-mailu.') @@ -311,6 +313,7 @@ def solar(text): show_upload_form = True contract_school = portal.solar.get_institution_contract(current_user_institution.id) cooperation_history = portal.solar.get_institution_cooperation_history(current_user_institution.id) + institution_id = current_user_institution.id if portal.solar.is_institution_coordinator(current_user_obj.id, current_user_institution.id): contracts_students = portal.solar.get_institution_student_contracts(current_user_institution.id) @@ -331,17 +334,24 @@ def solar(text): users = portal.solar.get_all_users_join_institutions() inactive_users = portal.solar.get_all_users_join_institutions(active=False) solar_institutions = portal.solar.get_all_institutions() - cooperation_history = portal.solar.get_cooperation_history() uploads = portal.solar.get_all_upload_history(-1) if is_admin: - return render_template('solar-admin.html', users=users, user_cooperation_history=cooperation_history, + return render_template('solar-admin.html', users=users, institutions=solar_institutions, inactive_users=inactive_users, uploads=uploads) elif text.startswith('manage-institution/') or text == 'manage-institution': if portal.solar.is_institution_coordinator(current_user.id, current_user_institution.id): solar_users = portal.solar.get_all_active_users() institution_users = portal.solar.get_all_active_institution_users(current_user_institution.id) - return render_template('solar-manage-institution.html', users=solar_users, - institution_users=institution_users) + + role_map = dict() + for institution_user in institution_users: + role_map[institution_user.id] = portal.solar.get_user_institution_role_str(institution_user.id, current_user_institution.id) + + return render_template('solar-manage-institution.html', + institution=current_user_institution, + users=solar_users, + institution_users=institution_users, + role_map=role_map) return '', 404 @app.route('/pogodbe', methods=['POST']) @@ -547,41 +557,41 @@ def merge_institutions(): flash('Instituciji uspešno združeni') return redirect(redirect_url()) -@app.route('/addcooperationhistoryitem', methods=['POST']) -@login_required -def add_cooperation_history_item(): - if not portal.solar.is_admin(current_user.id): - return '', 404 - - user_id = request.form.get('user') - institution_id = request.form.get('institution') - role = request.form.get('role') - school_year = request.form.get('school-year') - badge_text = request.form.get('badge-text') - - user = portal.solar.get_user_obj(user_id) - institution = portal.solar.get_institution_obj(institution_id) - - if not user: - flash('Uporabnik s tem ID-jem ne obstaja.') - return redirect(redirect_url()) - - if not institution: - flash('Institucija s tem ID-jem ne obstaja.') - return redirect(redirect_url()) - - if not role in ['coordinator', 'mentor', 'other']: - flash('Neveljavna vloga "{}".'.format(role)) - return redirect(redirect_url()) - - if not school_year or not re.match('[0-9]{4}/[0-9]{2}', school_year): - flash('Šolsko leto mora biti formata "2021/22".') - return redirect(redirect_url()) - - portal.solar.add_cooperation_history_item(user_id, institution_id, role, school_year, badge_text) - - flash('Vnos dodan.') - return redirect(redirect_url()) +#@app.route('/addcooperationhistoryitem', methods=['POST']) +#@login_required +#def add_cooperation_history_item(): +# if not portal.solar.is_admin(current_user.id): +# return '', 404 +# +# user_id = request.form.get('user') +# institution_id = request.form.get('institution') +# role = request.form.get('role') +# school_year = request.form.get('school-year') +# badge_text = request.form.get('badge-text') +# +# user = portal.solar.get_user_obj(user_id) +# institution = portal.solar.get_institution_obj(institution_id) +# +# if not user: +# flash('Uporabnik s tem ID-jem ne obstaja.') +# return redirect(redirect_url()) +# +# if not institution: +# flash('Institucija s tem ID-jem ne obstaja.') +# return redirect(redirect_url()) +# +# if not role in ['coordinator', 'mentor', 'other']: +# flash('Neveljavna vloga "{}".'.format(role)) +# return redirect(redirect_url()) +# +# if not school_year or not re.match('[0-9]{4}/[0-9]{2}', school_year): +# flash('Šolsko leto mora biti formata "2021/22".') +# return redirect(redirect_url()) +# +# portal.solar.add_cooperation_history_item(user_id, institution_id, role, school_year, badge_text) +# +# flash('Vnos dodan.') +# return redirect(redirect_url()) @app.route('/updateuploaditem', methods=['POST']) @login_required @@ -622,17 +632,17 @@ def update_upload_item(): return redirect(redirect_url()) -@app.route('/delcooperationhistoryitem', methods=['POST']) -@login_required -def del_cooperation_history_item(): - if not portal.solar.is_admin(current_user.id): - return '', 404 - - entry_id = request.form.get('entry-id') - portal.solar.del_cooperation_history_item(entry_id) - - flash('Vnos odstranjen.') - return redirect(redirect_url()) +#@app.route('/delcooperationhistoryitem', methods=['POST']) +#@login_required +#def del_cooperation_history_item(): +# if not portal.solar.is_admin(current_user.id): +# return '', 404 +# +# entry_id = request.form.get('entry-id') +# portal.solar.del_cooperation_history_item(entry_id) +# +# flash('Vnos odstranjen.') +# return redirect(redirect_url()) @app.route('/changeinstitutiondata', methods=['POST']) @login_required @@ -678,13 +688,11 @@ def change_user_email(): flash('Email spremenjen.') return redirect(redirect_url()) - -@app.route('/changeuserrole', methods=['POST']) +@app.route('/changeuserrole-institution', methods=['POST']) @login_required -def change_user_role(): +def change_user_role_institution(): institution = portal.solar.get_user_institution(current_user.id) if not portal.solar.is_admin(current_user.id): - # Institution coordinators can only assign roles of users in their own # institution. if institution and portal.solar.is_institution_coordinator(current_user.id, institution.id): @@ -695,6 +703,27 @@ def change_user_role(): user_id = request.form.get('user-id') role = request.form.get('role') + if role not in ['coordinator', 'mentor', 'other']: + flash('Neveljavna vloga.') + return redirect(redirect_url()) + + portal.solar.update_user_institution_role(user_id, institution.id, role) + portal.solar.add_cooperation_history_item(user_id, institution.id, role) + + flash('Vloga v instituciji spremenjena.') + return redirect(redirect_url()) + + +@app.route('/changeuserrole', methods=['POST']) +@login_required +def change_user_role(): + institution = portal.solar.get_user_institution(current_user.id) + if not portal.solar.is_admin(current_user.id): + return '', 404 + + user_id = request.form.get('user-id') + role = request.form.get('role') + if not role in ['admin', 'user']: flash('Neveljavna vloga.') return redirect(redirect_url()) @@ -740,6 +769,7 @@ def add_user_institution_mapping(): return redirect(redirect_url()) portal.solar.add_user_to_institution(user_id, institution_id, role) + portal.solar.add_cooperation_history_item(user_id, institution_id, role) flash('Uporabnik je bil dodeljen instituciji.') return redirect(redirect_url()) diff --git a/migrations/versions/0cf2d8f74766_altered_cooperation_history_structure.py b/migrations/versions/0cf2d8f74766_altered_cooperation_history_structure.py new file mode 100644 index 0000000..df4b594 --- /dev/null +++ b/migrations/versions/0cf2d8f74766_altered_cooperation_history_structure.py @@ -0,0 +1,36 @@ +"""Altered cooperation history structure. + +Revision ID: 0cf2d8f74766 +Revises: c7bb822adf9f +Create Date: 2022-02-14 13:04:01.143637 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '0cf2d8f74766' +down_revision = 'c7bb822adf9f' +branch_labels = None +depends_on = None + + +def upgrade(): + # Delete all rows + query = 'DELETE FROM user_cooperation;' + op.execute(query) + + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('user_cooperation', sa.Column('timestamp', sa.DateTime(), nullable=False)) + op.drop_column('user_cooperation', 'badge_text') + op.drop_column('user_cooperation', 'school_year') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('user_cooperation', sa.Column('school_year', sa.VARCHAR(), autoincrement=False, nullable=False)) + op.add_column('user_cooperation', sa.Column('badge_text', sa.VARCHAR(), autoincrement=False, nullable=True)) + op.drop_column('user_cooperation', 'timestamp') + # ### end Alembic commands ### diff --git a/portal/model.py b/portal/model.py index fb51677..ce45174 100644 --- a/portal/model.py +++ b/portal/model.py @@ -71,8 +71,7 @@ class UserCooperationHistory(db.Model): user = db.Column(db.Integer, sqlalchemy.ForeignKey('registered_user.id'), nullable=False) institution = db.Column(db.Integer, sqlalchemy.ForeignKey('institution.id'), nullable=False) role = db.Column(db.String, nullable=False) - school_year = db.Column(db.String, nullable=False) - badge_text = db.Column(db.String, nullable=True) + timestamp = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) class Institution(db.Model): diff --git a/portal/solar.py b/portal/solar.py index d52c738..00b7d5f 100644 --- a/portal/solar.py +++ b/portal/solar.py @@ -300,7 +300,6 @@ class UploadHandlerSolar(): @staticmethod def check_form(form): - logging.info(form) region = form['regija'] program = form['program'] predmet = form['predmet'] @@ -529,10 +528,10 @@ def get_institution_contract(institution_id): def get_institution_cooperation_history(institution_id): - return db.session.query(UserCooperationHistory.role, - UserCooperationHistory.school_year, - UserCooperationHistory.badge_text, - RegisteredUser.name, + items = db.session.query(UserCooperationHistory.role, + UserCooperationHistory.timestamp, + RegisteredUser.id, + RegisteredUser.name ).select_from( UserCooperationHistory, ).join( @@ -540,28 +539,59 @@ def get_institution_cooperation_history(institution_id): UserCooperationHistory.user == RegisteredUser.id, ).filter( UserCooperationHistory.institution == institution_id, - ).order_by(UserCooperationHistory.school_year.desc()).all() + ).order_by(UserCooperationHistory.timestamp.desc()).all() + + + res = [] + + prev_schoolyear = None + item_buff = [] + users_seen = set() + for item in items: + timestamp = item.timestamp + year = timestamp.year + month = timestamp.month + + if month >= 9 : + school_year = '{}/{}'.format(year, str(year+1)[-2:]) + else: + school_year = '{}/{}'.format(year-1, str(year)[-2:]) + + if school_year != prev_schoolyear: + if len(item_buff) > 0: + res.append((prev_schoolyear, item_buff)) + prev_schoolyear = school_year + item_buff = [] + users_seen = set() + + if not item.id in users_seen: + users_seen.add(item.id) + item_buff.append(item) + + if len(item_buff) > 0: + res.append((prev_schoolyear, item_buff)) + + return res def get_cooperation_history(): return UserCooperationHistory.query.all() -def add_cooperation_history_item(user_id, institution_id, role, school_year, badge_text): +def add_cooperation_history_item(user_id, institution_id, role): model_obj = UserCooperationHistory( user=user_id, institution=institution_id, role=role, - school_year=school_year, - badge_text=badge_text + timestamp=datetime.now() ) db.session.add(model_obj) db.session.commit() return model_obj.id -def del_cooperation_history_item(entry_id): - db.session.query(UserCooperationHistory).filter_by(id=entry_id).delete() - db.session.commit() +#def del_cooperation_history_item(entry_id): +# db.session.query(UserCooperationHistory).filter_by(id=entry_id).delete() +# db.session.commit() def has_user_corpus_access(user_id, corpus_name): user = RegisteredUser.query.filter_by(id=user_id).first() @@ -597,7 +627,6 @@ def get_user_obj_by_email(email): def get_institution_obj(institution_id): return Institution.query.filter_by(id=institution_id).first() - def get_institution_obj_by_name(institution_name): return Institution.query.filter_by(name=institution_name).first() @@ -666,6 +695,12 @@ def update_user_role(user_id, role): return rowcount +def update_user_institution_role(user_id, institution_id, role): + rowcount = db.session.query(UserInstitutionMapping).filter_by(user=user_id, institution=institution_id).update({'role': role}) + db.session.commit() + return rowcount + + def update_user_email(user_id, new_email): rowcount = db.session.query(RegisteredUser).filter_by(id=user_id).update({'email': new_email}) db.session.commit() @@ -708,6 +743,22 @@ def del_user_from_institution(user_id, institution_id): db.session.commit() +def get_user_institution_role_str(user_id, institution_id): + res = UserInstitutionMapping.query.filter_by( + user=user_id + ).filter_by( + institution=institution_id + ).first() + if not res: + return '' + role_str_map = { + 'coordinator': 'Koordinator/-ka', + 'mentor': 'Mentor/-ica', + 'other': 'Druga vloga' + } + return role_str_map[res.role] + + def get_all_active_users(): return RegisteredUser.query.filter_by(active=True).order_by(RegisteredUser.id).all() @@ -722,7 +773,6 @@ def get_all_users_join_institutions(active=True): RegisteredUser.id == UserInstitutionMapping.user).filter(RegisteredUser.active == active).order_by(RegisteredUser.id).all() - def get_all_active_institution_users(institution_id): return RegisteredUser.query.filter_by(active=True).join(UserInstitutionMapping, RegisteredUser.id == UserInstitutionMapping.user).filter(UserInstitutionMapping.institution == institution_id).all() diff --git a/templates/solar-admin.html b/templates/solar-admin.html index 023b314..de00a8e 100644 --- a/templates/solar-admin.html +++ b/templates/solar-admin.html @@ -258,50 +258,6 @@ -
ID | -ID uporabnika | -ID institucije | -Vloga | -Šolsko leto | -Besedilo značke | -
---|---|---|---|---|---|
{{item.id}} | -{{item.user}} | -{{item.institution}} | -{{item.role}} | -{{item.school_year}} | -{{item.badge_text}} | -