Skip to content

Commit 894cb9e

Browse files
authored
Merge pull request #138 from mbillow/co-op
Co-Op Submission Page
2 parents 4e9b599 + 205b00c commit 894cb9e

File tree

14 files changed

+313
-8
lines changed

14 files changed

+313
-8
lines changed

conditional/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def start_of_year():
5050
from conditional.blueprints.member_management import member_management_bp
5151
from conditional.blueprints.slideshow import slideshow_bp
5252
from conditional.blueprints.cache_management import cache_bp
53+
from conditional.blueprints.co_op import co_op_bp
5354

5455
app.register_blueprint(dashboard_bp)
5556
app.register_blueprint(attendance_bp)
@@ -62,6 +63,7 @@ def start_of_year():
6263
app.register_blueprint(member_management_bp)
6364
app.register_blueprint(slideshow_bp)
6465
app.register_blueprint(cache_bp)
66+
app.register_blueprint(co_op_bp)
6567

6668
from conditional.util.ldap import ldap_get_member
6769

conditional/blueprints/attendance.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ def get_non_alumni_non_coop(internal=False):
6767

6868
# Get all active members as a base house meeting attendance.
6969
active_members = ldap_get_active_members()
70-
coop_members = [u.uid for u in CurrentCoops.query.all()]
70+
71+
if datetime.today() < datetime(start_of_year().year, 12, 31):
72+
semester = 'Fall'
73+
else:
74+
semester = 'Spring'
75+
76+
coop_members = [u.uid for u in CurrentCoops.query.filter(
77+
CurrentCoops.date_created > start_of_year(),
78+
CurrentCoops.semester == semester).all()]
7179

7280
eligible_members = [
7381
{

conditional/blueprints/co_op.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import uuid
2+
import structlog
3+
4+
from flask import Blueprint, request, jsonify
5+
6+
from conditional.util.flask import render_template
7+
8+
from conditional.util.ldap import ldap_get_member, ldap_is_eval_director
9+
10+
from conditional.models.models import CurrentCoops
11+
12+
from conditional import db, start_of_year
13+
14+
co_op_bp = Blueprint('co_op_bp', __name__)
15+
16+
logger = structlog.get_logger()
17+
18+
@co_op_bp.route('/co_op/')
19+
def display_co_op_form():
20+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
21+
request_id=str(uuid.uuid4()))
22+
log.info('frontend', action='display co-op submission page')
23+
24+
# get user data
25+
user_name = request.headers.get('x-webauth-user')
26+
co_op = CurrentCoops.query.filter(
27+
CurrentCoops.uid == user_name, CurrentCoops.date_created > start_of_year()).first()
28+
29+
return render_template(request,
30+
'co_op.html',
31+
username=user_name,
32+
year=start_of_year().year,
33+
on_coop=co_op)
34+
35+
36+
@co_op_bp.route('/co_op/submit', methods=['POST'])
37+
def submit_co_op_form():
38+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
39+
request_id=str(uuid.uuid4()))
40+
41+
user_name = request.headers.get('x-webauth-user')
42+
43+
post_data = request.get_json()
44+
semester = post_data['semester']
45+
46+
log.info('api', action='Submit %s Co-Op' % semester)
47+
48+
if CurrentCoops.query.filter(CurrentCoops.uid == user_name, CurrentCoops.date_created > start_of_year()).first():
49+
return "User has already submitted this form!", 403
50+
51+
co_op = CurrentCoops(uid=user_name, semester=semester)
52+
db.session.add(co_op)
53+
db.session.flush()
54+
db.session.commit()
55+
56+
return jsonify({"success": True}), 200
57+
58+
59+
@co_op_bp.route('/co_op/<uid>', methods=['DELETE'])
60+
def delete_co_op(uid):
61+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
62+
request_id=str(uuid.uuid4()))
63+
64+
username = request.headers.get('x-webauth-user')
65+
account = ldap_get_member(username)
66+
67+
if not ldap_is_eval_director(account):
68+
return "must be eval director", 403
69+
70+
log.info('api', action="Delete %s's Co-Op" % uid)
71+
72+
CurrentCoops.query.filter(CurrentCoops.uid == uid, CurrentCoops.date_created > start_of_year()).delete()
73+
74+
db.session.flush()
75+
db.session.commit()
76+
77+
return jsonify({"success": True}), 200

conditional/blueprints/member_management.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from conditional.models.models import EvalSettings
2121
from conditional.models.models import OnFloorStatusAssigned
2222
from conditional.models.models import SpringEval
23+
from conditional.models.models import CurrentCoops
2324

2425
from conditional.blueprints.cache_management import clear_members_cache
2526
from conditional.blueprints.intro_evals import display_intro_evals
@@ -42,7 +43,7 @@
4243
from conditional.models.models import attendance_enum
4344
from conditional.util.member import get_members_info, get_onfloor_members
4445

45-
from conditional import db
46+
from conditional import db, start_of_year
4647

4748
logger = structlog.get_logger()
4849

@@ -64,6 +65,11 @@ def display_member_management():
6465
member_list = get_members_info()
6566
onfloor_list = get_onfloor_members()
6667

68+
co_op_list = [(ldap_get_member(member.uid).displayName, member.semester, member.uid) \
69+
for member in CurrentCoops.query.filter(
70+
CurrentCoops.date_created > start_of_year(),
71+
CurrentCoops.semester != "Neither")]
72+
6773
freshmen = FreshmanAccount.query
6874
freshmen_list = []
6975

@@ -92,6 +98,7 @@ def display_member_management():
9298
num_fresh=len(freshmen_list),
9399
num_onfloor=len(onfloor_list),
94100
freshmen=freshmen_list,
101+
co_op=co_op_list,
95102
site_lockdown=lockdown,
96103
intro_form=intro_form)
97104

conditional/models/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,14 @@ class CurrentCoops(db.Model):
191191
__tablename__ = 'current_coops'
192192
id = Column(Integer, primary_key=True)
193193
uid = Column(String(32), nullable=False)
194-
active = Column(Boolean, nullable=False)
195194
date_created = Column(Date, nullable=False)
195+
semester = Column(Enum('Fall', 'Spring', name="co_op_enum"), nullable=False)
196196

197-
def __init__(self, uid):
197+
def __init__(self, uid, semester):
198198
self.uid = uid
199199
self.active = True
200200
self.date_created = datetime.now()
201+
self.semester = semester
201202

202203

203204
class OnFloorStatusAssigned(db.Model):

conditional/templates/co_op.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{% extends "nav.html" %}
2+
{% block title %}
3+
Co-Op Submission
4+
{% endblock %}
5+
{% block body %}
6+
<div class="container main">
7+
<h3 class="page-title">Co-Op Submission</h3>
8+
<div class="row">
9+
<div class="col-xs-12 col-sm-12 col-md-12">
10+
<div class="panel panel-default">
11+
<div class="panel-body" style="padding-top:25px">
12+
{% if not on_coop %}
13+
<p>Please select one of the following options below if you are going to be on co-op during either semester this year. In the case you are going to be on co-op for both semesters, please contact the Evaluations Director and have them remove you from Active status.</p>
14+
<p>By selecting an option and submitting this form you are forfeiting your right to vote in house matters during the selected period. You are not required to attend house meetings but are still eligable for directorship meeting attendance.</p>
15+
<form data-module="coopSubmitForm">
16+
<div class="co-op-group">
17+
<div class="col-xs-12 col-sm-6">
18+
<div class="radio co-op-radio">
19+
<label>
20+
<input type="radio" name="semester" id="fall" value="Fall">
21+
<div class="co-op-option">
22+
<h4 class="list-group-item-heading">Fall Semester</h4>
23+
<p class='co-op-description'>August - December {{year}}</p>
24+
</div>
25+
</label>
26+
</div>
27+
</div>
28+
<div class="col-xs-12 col-sm-6">
29+
<div class="radio co-op-radio">
30+
<label>
31+
<input type="radio" name="semester" id="spring" value="Spring">
32+
<div class="co-op-option">
33+
<h4 class="list-group-item-heading">Spring Semester</h4>
34+
<p class='co-op-description'>January - May {{year + 1}}</p>
35+
</div>
36+
</label>
37+
</div>
38+
</div>
39+
</div>
40+
<input type="submit" role="button" class="btn btn-raised btn-primary" style="width:100%;" value="Submit Form"/>
41+
</form>
42+
{% else %}
43+
<p class="align-center">Thank you for submitting this form. Good luck on your {{on_coop.semester}} co-op!</p>
44+
<p class="align-center">If you submitted this form by mistake or your plans have changed, please contact the Evaluations Director.</p>
45+
{% endif %}
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</div>
51+
{% endblock %}

conditional/templates/member_management.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,43 @@ <h3 class="panel-title">Administration</h3>
3838
</div>
3939
</div>
4040
</div>
41+
{% if co_op and is_eval_director%}
42+
<div class="panel panel-default">
43+
<div class="panel-heading">
44+
<h3 class="panel-title">Co-Op Management</h3>
45+
</div>
46+
<div class="panel-body table-fill">
47+
<div class="table-responsive">
48+
<table class="table table-striped no-bottom-margin" data-module="table" data-searchable="false" data-sort-column="1" data-sort-order="asc" data-length-changable="true" data-paginated="false">
49+
<thead>
50+
<tr>
51+
<th>Name</th>
52+
<th>Semester</th>
53+
<th>Delete</th>
54+
</tr>
55+
</thead>
56+
<tbody>
57+
{% for c in co_op %}
58+
<tr id="coop-{{c[2]}}">
59+
<td>
60+
<img class="table-img mobile-hide" src="https://profiles.csh.rit.edu/image/{{c[2]}}"> {{c[0]}}
61+
</td>
62+
<td>
63+
{{c[1]}}
64+
</td>
65+
<td width=100px>
66+
<a href="#" data-module="coopDelete" data-uid="{{c[2]}}">
67+
<span class="glyphicon glyphicon-trash red align-center" style="width: 100%"></span>
68+
</a>
69+
</td>
70+
</tr>
71+
{% endfor %}
72+
</tbody>
73+
</table>
74+
</div>
75+
</div>
76+
</div>
77+
{% endif %}
4178

4279
{% if is_eval_director %}
4380
<div class="panel panel-default">

conditional/templates/nav.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-list-alt"></span> Forms <span class="caret"></span></a>
2626
<ul class="dropdown-menu">
2727
<li><a href="/major_project"><span class="glyphicon glyphicon-star"></span> Major Project</a></li>
28+
<li><a href="/co_op"><span class="glyphicon glyphicon-briefcase"></span> Co-Op Submission</a></li>
2829
{% if is_intromember %}
2930
<li><a href="/intro_evals_form"><span class="glyphicon glyphicon-blackboard"></span> Introductory Evaluations</a></li>
3031
{% endif %}
@@ -40,7 +41,7 @@
4041
{% endif %}
4142
<span class="caret"></span></a>
4243
<ul class="dropdown-menu">
43-
<li><a href="/attendance_cm"><span class="glyphicon glyphicon-briefcase"></span> Directorship Meeting </a></li>
44+
<li><a href="/attendance_cm"><span class="glyphicon glyphicon-user"></span> Directorship Meeting </a></li>
4445
<li><a href="/attendance_ts"><span class="glyphicon glyphicon-blackboard"></span> Technical Seminar</a></li>
4546
{% if is_eboard %}
4647
<li><a href="/attendance/history"><span class="glyphicon glyphicon-calendar"></span> Attendance History</a></li>

conditional/util/member.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from functools import lru_cache
2+
from datetime import datetime
23

34
from conditional.util.ldap import ldap_get_active_members
45
from conditional.util.ldap import ldap_get_intro_members
@@ -15,21 +16,34 @@
1516
from conditional.models.models import MemberCommitteeAttendance
1617
from conditional.models.models import TechnicalSeminar
1718
from conditional.models.models import HouseMeeting
19+
from conditional.models.models import CurrentCoops
1820

1921
from conditional import start_of_year
2022

2123

2224
@lru_cache(maxsize=1024)
2325
def get_voting_members():
24-
voting_list = [uid for uid in [member.uid for member in ldap_get_active_members()]
25-
if uid not in [member.uid for member in ldap_get_intro_members()]]
26+
27+
if datetime.today() < datetime(start_of_year().year, 12, 31):
28+
semester = 'Fall'
29+
else:
30+
semester = 'Spring'
31+
32+
active_members = set(member.uid for member in ldap_get_active_members())
33+
intro_members = set(member.uid for member in ldap_get_intro_members())
34+
on_coop = set(member.uid for member in CurrentCoops.query.filter(
35+
CurrentCoops.date_created > start_of_year(),
36+
CurrentCoops.semester == semester).all())
37+
38+
voting_list = list(active_members - intro_members - on_coop)
2639

2740
passed_fall = FreshmanEvalData.query.filter(
2841
FreshmanEvalData.freshman_eval_result == "Passed"
2942
).distinct()
3043

3144
for intro_member in passed_fall:
32-
voting_list.append(intro_member.uid)
45+
if intro_member.uid not in voting_list:
46+
voting_list.append(intro_member.uid)
3347

3448
return voting_list
3549

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import FetchUtil from "../utils/fetchUtil";
2+
3+
export default class coopDelete {
4+
constructor(link) {
5+
this.link = link;
6+
this.uid = this.link.dataset.uid;
7+
this.endpoint = '/co_op/' + this.uid;
8+
this.render();
9+
}
10+
11+
render() {
12+
this.link.addEventListener('click', e => this._delete(e));
13+
}
14+
15+
_delete(e) {
16+
e.preventDefault();
17+
18+
FetchUtil.fetchWithWarning(this.endpoint, {
19+
method: 'DELETE',
20+
warningText: "This co-op entry will be deleted and the user will no" +
21+
" longer be excluded from attendance and vote counts.",
22+
successText: "Co-op has been deleted."
23+
}, () => {
24+
document.getElementById('coop-' + this.uid).remove();
25+
});
26+
}
27+
}

0 commit comments

Comments
 (0)