diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index b3af06c9..3dd3fa40 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -1,8 +1,9 @@ from flask import render_template, request, json, redirect, url_for, send_file, g, flash, jsonify -from peewee import JOIN +from peewee import JOIN, DoesNotExist, fn from functools import reduce import operator from app.models.department import Department +from app.models.allocation import Allocation from app.models.supervisor import Supervisor from app.models.supervisorDepartment import SupervisorDepartment from app.models.student import Student @@ -16,6 +17,7 @@ from app.login_manager import require_login, logout from app.logic.getTableData import getDatatableData from app.logic.banner import Banner +from app.logic.tracy import Tracy @main_bp.route('/logout', methods=['GET']) def triggerLogout(): @@ -47,6 +49,56 @@ def supervisorPortal(): currentUser = currentUser ) +@main_bp.route('/department', methods=['GET']) +@main_bp.route('/department/', methods=['GET']) +@main_bp.route('/department//', methods=['GET']) +def departmentPortal(org=None,account=None): + try: + dept = Department.get(Department.ORG == org, Department.ACCOUNT == account) + except (NameError, DoesNotExist): + dept = None + + + + if g.currentUser.isLaborAdmin: + departments = list(Department.select().order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) + else: + departments = list(getDepartmentsForSupervisor(g.currentUser).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) + + pos = Tracy().getPositionsFromDepartment(org, account) + positions = [] + for i in pos: + positions.append(i.POSN_TITLE + "" + "(" + i.WLS + ")") + + staff = Tracy().getSupervisors() + supervisors = [] + + for i in staff: + if i.DEPT_NAME == Department.DEPT_NAME: + supervisors.append(i.FIRST_NAME + " " + i.LAST_NAME + " (" + i.EMAIL + ")") + + allocation = None + positionsUsed = 0 + breakHoursUsed = 0 + if dept and g.openTerm: + allocation = Allocation.get_or_none(Allocation.department == dept, Allocation.term == g.openTerm) + usage = (LaborStatusForm + .select(fn.COUNT(LaborStatusForm.laborStatusFormID).alias('positionCount'), + fn.SUM(LaborStatusForm.contractHours).alias('hoursSum')) + .where(LaborStatusForm.department == dept, LaborStatusForm.termCode == g.openTerm) + .get()) + positionsUsed = usage.positionCount or 0 + breakHoursUsed = usage.hoursSum or 0 + + return render_template('main/departmentPortal.html', + departments = departments, + department = dept, + positions = positions, + supervisors = supervisors, + allocation = allocation, + positionsUsed = positionsUsed, + breakHoursUsed = breakHoursUsed) + @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) def addUserToDept(): userDeptData = request.form @@ -113,4 +165,4 @@ def submitToBanner(formHistoryId): if save_form_status: return "Form successfully submitted to Banner.", 200 else: - return "Submitting to Banner failed.", 500 \ No newline at end of file + return "Submitting to Banner failed.", 500 diff --git a/app/models/allocation.py b/app/models/allocation.py new file mode 100644 index 00000000..f67b61e3 --- /dev/null +++ b/app/models/allocation.py @@ -0,0 +1,9 @@ +from app.models import * +from app.models.department import Department +from app.models.term import Term + +class Allocation(baseModel): + department = ForeignKeyField(Department, on_delete="cascade") + term = ForeignKeyField(Term, on_delete="cascade") + totalPositions = IntegerField() + totalBreakHours = IntegerField() diff --git a/app/static/css/base.css b/app/static/css/base.css index 916fb4db..940f8d6e 100755 --- a/app/static/css/base.css +++ b/app/static/css/base.css @@ -191,3 +191,76 @@ a { font-size:1.2em; z-index:999; } + +.card { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} + +.card-body { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem 1rem; +} + +.card-title { + margin-bottom: 0.5rem; + font-size: 1.25rem; + font-weight: 500; +} + +.card-subtitle { + margin-top: -0.25rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link + .card-link { + margin-left: 1rem; +} + +.card-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-footer { + padding: 0.5rem 1rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-img, .card-img-top { + width: 100%; +} + +.card-img-top { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} diff --git a/app/static/js/departmentPortal.js b/app/static/js/departmentPortal.js new file mode 100644 index 00000000..cb2023a3 --- /dev/null +++ b/app/static/js/departmentPortal.js @@ -0,0 +1,6 @@ +$(document).ready(function() { + $("#selectedDepartment").on("change",function() { + deptData = $(this).find('option:selected').data(); + window.location = `/department/${deptData.org}/${deptData.account}`; + }); +}); diff --git a/app/templates/main/departmentPortal.html b/app/templates/main/departmentPortal.html new file mode 100644 index 00000000..94f1c46b --- /dev/null +++ b/app/templates/main/departmentPortal.html @@ -0,0 +1,165 @@ +{% extends "base.html" %} + +{% block scripts %} +{{super()}} + + +{% endblock %} +{% block app_content %} +

{% if department %} {{department.DEPT_NAME}} Portal {% else %} Choose a Department: {% endif %}

+ + + +
+ + +
+ +{% if department %} +
+ +
+
+
+
+ +

+ Current Allocation +

+
+
+
+
+
+

AY 26/27

15/20 Positions

+
+
    +
  • 10 HR : 2
  • +
  • 12 HR : 3
  • +
  • 15 HR : 5
  • +
  • 20 HR : 5
  • +
+
+
+

Break Hours

0 of 200 Hrs.

+
+
+ + + +
+ +
+
+
+
+ +
+
+

+ Members +

+
+
+

Labor Coordinator(s)

+

Dr. Jones

+ +

Supervisors

+ {% for s in supervisors %} + {% if 3 > loop.index0 %} +

{{ s }}

+ {% elif 4 > loop.index0 %} +

and {{ supervisors | length}} more...

+ {% endif %} + {% endfor %} +
+ + +
+ +
+
+

Positions

+ {% for p in positions %} + {% if 10 > loop.index0 %} +

{{ p }}

+ {% endif %} + {% endfor %} + View Details +
+
+
+ +{% endif %} + + + + +{% endblock %}\ + + + + diff --git a/app/templates/main/supervisorPortal.html b/app/templates/main/supervisorPortal.html index 78383566..3ab521a5 100644 --- a/app/templates/main/supervisorPortal.html +++ b/app/templates/main/supervisorPortal.html @@ -227,7 +227,7 @@

Form Search


-
+