Finished manage institution site. Redone how cooperation history works.

This commit is contained in:
msinkec 2022-02-14 15:01:03 +01:00
parent 87f067b077
commit f898ee8d31
7 changed files with 197 additions and 123 deletions

138
app.py
View File

@ -229,6 +229,8 @@ def solar_register_post():
user_id = portal.solar.register_new_user(name, email, password, active=False) 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_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) 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.') 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 show_upload_form = True
contract_school = portal.solar.get_institution_contract(current_user_institution.id) contract_school = portal.solar.get_institution_contract(current_user_institution.id)
cooperation_history = portal.solar.get_institution_cooperation_history(current_user_institution.id) cooperation_history = portal.solar.get_institution_cooperation_history(current_user_institution.id)
institution_id = current_user_institution.id institution_id = current_user_institution.id
if portal.solar.is_institution_coordinator(current_user_obj.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) 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() users = portal.solar.get_all_users_join_institutions()
inactive_users = portal.solar.get_all_users_join_institutions(active=False) inactive_users = portal.solar.get_all_users_join_institutions(active=False)
solar_institutions = portal.solar.get_all_institutions() solar_institutions = portal.solar.get_all_institutions()
cooperation_history = portal.solar.get_cooperation_history()
uploads = portal.solar.get_all_upload_history(-1) uploads = portal.solar.get_all_upload_history(-1)
if is_admin: 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) institutions=solar_institutions, inactive_users=inactive_users, uploads=uploads)
elif text.startswith('manage-institution/') or text == 'manage-institution': elif text.startswith('manage-institution/') or text == 'manage-institution':
if portal.solar.is_institution_coordinator(current_user.id, current_user_institution.id): if portal.solar.is_institution_coordinator(current_user.id, current_user_institution.id):
solar_users = portal.solar.get_all_active_users() solar_users = portal.solar.get_all_active_users()
institution_users = portal.solar.get_all_active_institution_users(current_user_institution.id) 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 return '', 404
@app.route('/pogodbe', methods=['POST']) @app.route('/pogodbe', methods=['POST'])
@ -547,41 +557,41 @@ def merge_institutions():
flash('Instituciji uspešno združeni') flash('Instituciji uspešno združeni')
return redirect(redirect_url()) return redirect(redirect_url())
@app.route('/addcooperationhistoryitem', methods=['POST']) #@app.route('/addcooperationhistoryitem', methods=['POST'])
@login_required #@login_required
def add_cooperation_history_item(): #def add_cooperation_history_item():
if not portal.solar.is_admin(current_user.id): # if not portal.solar.is_admin(current_user.id):
return '', 404 # return '', 404
#
user_id = request.form.get('user') # user_id = request.form.get('user')
institution_id = request.form.get('institution') # institution_id = request.form.get('institution')
role = request.form.get('role') # role = request.form.get('role')
school_year = request.form.get('school-year') # school_year = request.form.get('school-year')
badge_text = request.form.get('badge-text') # badge_text = request.form.get('badge-text')
#
user = portal.solar.get_user_obj(user_id) # user = portal.solar.get_user_obj(user_id)
institution = portal.solar.get_institution_obj(institution_id) # institution = portal.solar.get_institution_obj(institution_id)
#
if not user: # if not user:
flash('Uporabnik s tem ID-jem ne obstaja.') # flash('Uporabnik s tem ID-jem ne obstaja.')
return redirect(redirect_url()) # return redirect(redirect_url())
#
if not institution: # if not institution:
flash('Institucija s tem ID-jem ne obstaja.') # flash('Institucija s tem ID-jem ne obstaja.')
return redirect(redirect_url()) # return redirect(redirect_url())
#
if not role in ['coordinator', 'mentor', 'other']: # if not role in ['coordinator', 'mentor', 'other']:
flash('Neveljavna vloga "{}".'.format(role)) # flash('Neveljavna vloga "{}".'.format(role))
return redirect(redirect_url()) # return redirect(redirect_url())
#
if not school_year or not re.match('[0-9]{4}/[0-9]{2}', school_year): # if not school_year or not re.match('[0-9]{4}/[0-9]{2}', school_year):
flash('Šolsko leto mora biti formata "2021/22".') # flash('Šolsko leto mora biti formata "2021/22".')
return redirect(redirect_url()) # return redirect(redirect_url())
#
portal.solar.add_cooperation_history_item(user_id, institution_id, role, school_year, badge_text) # portal.solar.add_cooperation_history_item(user_id, institution_id, role, school_year, badge_text)
#
flash('Vnos dodan.') # flash('Vnos dodan.')
return redirect(redirect_url()) # return redirect(redirect_url())
@app.route('/updateuploaditem', methods=['POST']) @app.route('/updateuploaditem', methods=['POST'])
@login_required @login_required
@ -622,17 +632,17 @@ def update_upload_item():
return redirect(redirect_url()) return redirect(redirect_url())
@app.route('/delcooperationhistoryitem', methods=['POST']) #@app.route('/delcooperationhistoryitem', methods=['POST'])
@login_required #@login_required
def del_cooperation_history_item(): #def del_cooperation_history_item():
if not portal.solar.is_admin(current_user.id): # if not portal.solar.is_admin(current_user.id):
return '', 404 # return '', 404
#
entry_id = request.form.get('entry-id') # entry_id = request.form.get('entry-id')
portal.solar.del_cooperation_history_item(entry_id) # portal.solar.del_cooperation_history_item(entry_id)
#
flash('Vnos odstranjen.') # flash('Vnos odstranjen.')
return redirect(redirect_url()) # return redirect(redirect_url())
@app.route('/changeinstitutiondata', methods=['POST']) @app.route('/changeinstitutiondata', methods=['POST'])
@login_required @login_required
@ -678,13 +688,11 @@ def change_user_email():
flash('Email spremenjen.') flash('Email spremenjen.')
return redirect(redirect_url()) return redirect(redirect_url())
@app.route('/changeuserrole-institution', methods=['POST'])
@app.route('/changeuserrole', methods=['POST'])
@login_required @login_required
def change_user_role(): def change_user_role_institution():
institution = portal.solar.get_user_institution(current_user.id) institution = portal.solar.get_user_institution(current_user.id)
if not portal.solar.is_admin(current_user.id): if not portal.solar.is_admin(current_user.id):
# Institution coordinators can only assign roles of users in their own # Institution coordinators can only assign roles of users in their own
# institution. # institution.
if institution and portal.solar.is_institution_coordinator(current_user.id, institution.id): 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') user_id = request.form.get('user-id')
role = request.form.get('role') 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']: if not role in ['admin', 'user']:
flash('Neveljavna vloga.') flash('Neveljavna vloga.')
return redirect(redirect_url()) return redirect(redirect_url())
@ -740,6 +769,7 @@ def add_user_institution_mapping():
return redirect(redirect_url()) return redirect(redirect_url())
portal.solar.add_user_to_institution(user_id, institution_id, role) 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.') flash('Uporabnik je bil dodeljen instituciji.')
return redirect(redirect_url()) return redirect(redirect_url())

View File

@ -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 ###

View File

@ -71,8 +71,7 @@ class UserCooperationHistory(db.Model):
user = db.Column(db.Integer, sqlalchemy.ForeignKey('registered_user.id'), nullable=False) user = db.Column(db.Integer, sqlalchemy.ForeignKey('registered_user.id'), nullable=False)
institution = db.Column(db.Integer, sqlalchemy.ForeignKey('institution.id'), nullable=False) institution = db.Column(db.Integer, sqlalchemy.ForeignKey('institution.id'), nullable=False)
role = db.Column(db.String, nullable=False) role = db.Column(db.String, nullable=False)
school_year = db.Column(db.String, nullable=False) timestamp = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
badge_text = db.Column(db.String, nullable=True)
class Institution(db.Model): class Institution(db.Model):

View File

@ -300,7 +300,6 @@ class UploadHandlerSolar():
@staticmethod @staticmethod
def check_form(form): def check_form(form):
logging.info(form)
region = form['regija'] region = form['regija']
program = form['program'] program = form['program']
predmet = form['predmet'] predmet = form['predmet']
@ -529,10 +528,10 @@ def get_institution_contract(institution_id):
def get_institution_cooperation_history(institution_id): def get_institution_cooperation_history(institution_id):
return db.session.query(UserCooperationHistory.role, items = db.session.query(UserCooperationHistory.role,
UserCooperationHistory.school_year, UserCooperationHistory.timestamp,
UserCooperationHistory.badge_text, RegisteredUser.id,
RegisteredUser.name, RegisteredUser.name
).select_from( ).select_from(
UserCooperationHistory, UserCooperationHistory,
).join( ).join(
@ -540,28 +539,59 @@ def get_institution_cooperation_history(institution_id):
UserCooperationHistory.user == RegisteredUser.id, UserCooperationHistory.user == RegisteredUser.id,
).filter( ).filter(
UserCooperationHistory.institution == institution_id, 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(): def get_cooperation_history():
return UserCooperationHistory.query.all() 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( model_obj = UserCooperationHistory(
user=user_id, user=user_id,
institution=institution_id, institution=institution_id,
role=role, role=role,
school_year=school_year, timestamp=datetime.now()
badge_text=badge_text
) )
db.session.add(model_obj) db.session.add(model_obj)
db.session.commit() db.session.commit()
return model_obj.id return model_obj.id
def del_cooperation_history_item(entry_id): #def del_cooperation_history_item(entry_id):
db.session.query(UserCooperationHistory).filter_by(id=entry_id).delete() # db.session.query(UserCooperationHistory).filter_by(id=entry_id).delete()
db.session.commit() # db.session.commit()
def has_user_corpus_access(user_id, corpus_name): def has_user_corpus_access(user_id, corpus_name):
user = RegisteredUser.query.filter_by(id=user_id).first() 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): def get_institution_obj(institution_id):
return Institution.query.filter_by(id=institution_id).first() return Institution.query.filter_by(id=institution_id).first()
def get_institution_obj_by_name(institution_name): def get_institution_obj_by_name(institution_name):
return Institution.query.filter_by(name=institution_name).first() return Institution.query.filter_by(name=institution_name).first()
@ -666,6 +695,12 @@ def update_user_role(user_id, role):
return rowcount 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): def update_user_email(user_id, new_email):
rowcount = db.session.query(RegisteredUser).filter_by(id=user_id).update({'email': new_email}) rowcount = db.session.query(RegisteredUser).filter_by(id=user_id).update({'email': new_email})
db.session.commit() db.session.commit()
@ -708,6 +743,22 @@ def del_user_from_institution(user_id, institution_id):
db.session.commit() 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(): def get_all_active_users():
return RegisteredUser.query.filter_by(active=True).order_by(RegisteredUser.id).all() 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() RegisteredUser.id == UserInstitutionMapping.user).filter(RegisteredUser.active == active).order_by(RegisteredUser.id).all()
def get_all_active_institution_users(institution_id): def get_all_active_institution_users(institution_id):
return RegisteredUser.query.filter_by(active=True).join(UserInstitutionMapping, return RegisteredUser.query.filter_by(active=True).join(UserInstitutionMapping,
RegisteredUser.id == UserInstitutionMapping.user).filter(UserInstitutionMapping.institution == institution_id).all() RegisteredUser.id == UserInstitutionMapping.user).filter(UserInstitutionMapping.institution == institution_id).all()

View File

@ -258,50 +258,6 @@
</select> </select>
<input type="submit" value="Spremeni"> <input type="submit" value="Spremeni">
</form> </form>
<h2>Zgodovina sodelovanja</h2>
<div class="tableFixHead">
<table>
<thead>
<tr>
<th>ID</th>
<th>ID uporabnika</th>
<th>ID institucije</th>
<th>Vloga</th>
<th>Šolsko leto</th>
<th>Besedilo značke</th>
</tr>
</thead>
<tbody>
{% for item in user_cooperation_history %}
<tr>
<td>{{item.id}}</td>
<td>{{item.user}}</td>
<td>{{item.institution}}</td>
<td>{{item.role}}</td>
<td>{{item.school_year}}</td>
<td>{{item.badge_text}}</td>
</tr>
{% endfor %}
</table>
</div>
<h3>Dodaj vnos</h3>
<form action="../addcooperationhistoryitem" method="post">
<label for="user">ID uporabnika</label>
<input type="text" id="user" name="user"><br>
<label for="institution">ID institucije</label>
<input type="text" id="institution" name="institution"><br>
<label for="role">Vloga</label>
<select name="role" id="role">
<option value="coordinator">Koordinator/-ka</option>
<option value="mentor">Mentor/-ica</option>
<option value="other">Druga vloga</option>
</select><br>
<label for="school-year">Šolsko leto (npr. "2021/22")</label>
<input type="text" id="school-year" name="school-year"><br>
<label for="badge-text">Besedilo značke</label>
<input type="text" id="badge-text" name="badge-text"><br>
<input type="submit" value="Dodaj">
</form>
<h3>Odstrani vnos</h3> <h3>Odstrani vnos</h3>
<form action="../delcooperationhistoryitem" method="post"> <form action="../delcooperationhistoryitem" method="post">
<label for="entry-id">ID vnosa</label> <label for="entry-id">ID vnosa</label>

View File

@ -44,7 +44,7 @@
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<h1>TODO ime institucije</h1> <h1>{{institution.name}}</h1>
<h3>Seznam uporabnikov v vaši instituciji</h3> <h3>Seznam uporabnikov v vaši instituciji</h3>
<table class="tableFixHead"> <table class="tableFixHead">
<thead> <thead>
@ -62,11 +62,12 @@
<td>{{item.email}}</td> <td>{{item.email}}</td>
<td> <td>
<div> <div>
TODO: izpiši vlogo <a href="javascript:void(0);" onclick="toggleEditForm(this)" class="toggle-edit-role">Spremeni</a> <a href="javascript:void(0);" onclick="toggleEditForm(this)" class="toggle-edit-role">Spremeni</a>
{{role_map[item.id]}}
</div> </div>
<form action="../changeuserrole" method="post" style="display:none;"> <form action="../changeuserrole-institution" method="post" style="display:none;">
<input type="hidden" id="user-id" name="user-id" value="{{item.id}}"/> <input type="hidden" id="user-id" name="user-id" value="{{item.id}}"/>
<select class="role"> <select class="role" name="role">
<option value="coordinator">Koordinator/-ka</option> <option value="coordinator">Koordinator/-ka</option>
<option value="mentor">Mentor/-ica</option> <option value="mentor">Mentor/-ica</option>
<option value="other">Druga vloga</option> <option value="other">Druga vloga</option>

View File

@ -69,22 +69,24 @@
</div> </div>
{% set vars = {'prev_schoolyear': ''} %} {% set vars = {'prev_schoolyear': ''} %}
{% for item in cooperation_history %} {% for item in cooperation_history %}
{% if item.school_year != vars.prev_schoolyear %} {% if item[0] != vars.prev_schoolyear %}
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<h2>Šolsko leto {{item.school_year}}</h2> <h2>Šolsko leto {{item[0]}}</h2>
</div> </div>
</div> </div>
{% if vars.update({'prev_schoolyear': item.school_year}) %} {% endif %} {% if vars.update({'prev_schoolyear': item[0]}) %} {% endif %}
{% endif %} {% endif %}
{% for entry in item[1] %}
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<div class="team-item"> <div class="team-item">
<div class="team-item-name">{{item.name}} <span class="team-item-role">{%if item.role == "mentor" %}Mentor{%elif item.role == "coordinator" %}Koordinator{%elif item.role == "other" %}{{item.badge_text}}{%endif%}</span></div> <div class="team-item-name">{{entry.name}} <span class="team-item-role">{%if entry.role == "mentor" %}Mentor{%elif entry.role == "coordinator" %}Koordinator{%elif entry.role == "other" %}Druga vloga{%endif%}</span></div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %}
{% endfor %} {% endfor %}