diff --git a/app/__init__.py b/app/__init__.py
index 11c90a0a9..a131ae4fb 100755
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -1,9 +1,9 @@
import os
-
-from flask import Flask
-from flask_restful import Api
+from datetime import date
+from flask import Flask, g, request, session
from flask_bootstrap import Bootstrap
-from playhouse.shortcuts import model_to_dict, dict_to_model
+from flask_restful import Api
+from playhouse.shortcuts import dict_to_model, model_to_dict
app = Flask(__name__)
@@ -55,17 +55,27 @@ def new_execute(*args, **kwargs):
from app.controllers.api_routes.routes import initializeApiRoutes
initializeApiRoutes(api)
-from flask import g
from app.models.user import User
-from app.login_manager import require_login
+from app.login_manager import getUsernameFromEnv, require_login
@app.before_request
def load_user():
- try:
- g.currentUser = dict_to_model(User, session['currentUser'])
+ requestUsername = getUsernameFromEnv(request.environ)
+ try:
+ cachedUser = session['currentUser']
+
+ if cachedUser.get('username') == requestUsername:
+ g.currentUser = dict_to_model(User, cachedUser)
+ return
+
+ session.pop('currentUser', None)
+ session.pop('username', None)
+
except Exception as e:
- user = require_login()
- session['currentUser'] = model_to_dict(user)
- g.currentUser = user
+ pass
+
+ user = require_login()
+ session['currentUser'] = model_to_dict(user)
+ g.currentUser = user
from app.models.term import Term
from app.login_manager import getOpenTerm
@@ -79,6 +89,20 @@ def load_openTerm():
session['openTerm'] = model_to_dict(term)
g.openTerm = term
+def getCurrentYear():
+ today = date.today()
+ year = today.year
+
+ if today.month < 7:
+ return year - 1, year
+
+ return year, year + 1
+
+@app.before_request
+def load_currentYear():
+ g.currentYear = getCurrentYear()
+
+
@app.context_processor
def inject_environment():
return dict(env=app.config['ENV'])
@@ -87,4 +111,3 @@ def inject_environment():
def queryCount():
if session:
session['querycount'] = 0
-
diff --git a/app/controllers/admin_routes/manageDepartments.py b/app/controllers/admin_routes/manageDepartments.py
index c202513a9..ec1aef0a4 100644
--- a/app/controllers/admin_routes/manageDepartments.py
+++ b/app/controllers/admin_routes/manageDepartments.py
@@ -1,6 +1,6 @@
from datetime import date
-from flask import g, request, redirect, jsonify, abort
+from flask import g, request, redirect, jsonify, abort, flash
from app.controllers.admin_routes import *
from app.login_manager import require_login
@@ -16,11 +16,13 @@
from app.models.laborStatusForm import *
from app.logic.manageDepartments import *
+from app.logic.allocationManager import allocationExists
+from app.logic.academicYearManager import getCurrentAndNextAY
@admin.route('/admin/manageDepartments/', methods=['GET'])
-def manageDepartments(academicYear = None):
+def manageDepartments():
"""
Returns the Manage Departments page, which allows the admin to view all the departments
and their allocations.
@@ -36,16 +38,8 @@ def manageDepartments(academicYear = None):
elif currentUser.supervisor:
return render_template('errors/403.html'), 403
-
- # The condition below may be deleted if the routing to the Manage Departments page is changed.
- if academicYear == None:
- academicYear = g.openTerm.termCode
- else:
- academicYear = int(academicYear)
-
-
- currentAY, nextAY = generateAdjacentYears(academicYear)
- chosenAY = Term.get(Term.termCode == academicYear)
+ currentAY, nextAY = getCurrentAndNextAY()
+ chosenAY = Term.get(Term.termCode == currentAY.termCode)
breakHoursByDepartment = {row["department"]: str(row["totalHours"] or 0) for row in getUsedBreakHours(chosenAY)}
@@ -98,12 +92,14 @@ def allocationReview(org=None, account=None):
the Manage Departments page.
"""
- # Retrieving the departments based on the org and account numbers
+
+ # getting the name of the currently chosen department (based on the org and account numbers)
try:
dept = Department.get(Department.ORG == org, Department.ACCOUNT == account)
except (NameError, DoesNotExist):
abort(404)
+
# Checking admin rights
currentUser = require_login()
if not currentUser: # If the current user is not logged in
@@ -114,9 +110,63 @@ def allocationReview(org=None, account=None):
elif currentUser.supervisor:
return render_template('errors/403.html'), 403
- # Retrieving the next year
- # DON'T DELETE THE UNDERSCORES
- _, _, nextAY = generateAdjacentYears()
- # The generateAdjacentYears() function returns a tuple of three elements, and we only need the third value
- return render_template('admin/allocationReview.html', department = dept, nextAY = nextAY)
\ No newline at end of file
+ # Retrieving the current and following academic years
+ currentAY, nextAY = getCurrentAndNextAY()
+
+
+ # checking if the allocation has already been approved
+ if allocationExists(nextAY.termCode, dept, isFinal=True):
+ flash("You cannot reapprove an allocation request.", "info")
+ return redirect('/admin/manageDepartments/')
+
+
+ # checking if the department has requested any allocation review
+ if not allocationExists(nextAY.termCode, dept, isFinal=False):
+ flash(f"The {dept.DEPT_NAME} department has not requested an allocation review yet.", "info")
+ return redirect('/admin/manageDepartments/')
+
+
+ # getting the current and the requested allocations
+ currentAlloc = Allocation.get_or_none(Allocation.termCode == currentAY.termCode, Allocation.department == dept, Allocation.isFinal == True)
+ requestedAlloc = Allocation.get(Allocation.termCode == nextAY.termCode, Allocation.department == dept, Allocation.isFinal == False)
+
+
+ return render_template('admin/allocationReview.html',
+ department = dept,
+ nextAY = nextAY,
+ currentAlloc = currentAlloc,
+ requestedAlloc = requestedAlloc
+ )
+
+
+
+@admin.route('/admin/allocationReview/approve', methods=['POST'])
+def approveAllocationReview():
+
+ # Retrieving the current and following academic years
+ currentAY, nextAY = getCurrentAndNextAY()
+
+ # getting the ID of the user who approves the request
+ approverID = require_login().userID
+
+ # getting the name of the requesting department
+ requester = request.form.get("requester", type=int, default=None)
+
+ # saving the newly approved allocation
+ newApprovedAlloc = Allocation.create(termCode = nextAY.termCode,
+ department = requester,
+ isFinal = True,
+ approvedBy = approverID,
+ approvedOn = date.today(),
+ primary_10 = request.form.get("primary_10", type=int, default=None),
+ primary_12 = request.form.get("primary_12", type=int, default=None),
+ primary_15 = request.form.get("primary_15", type=int, default=None),
+ primary_20 = request.form.get("primary_20", type=int, default=None),
+ secondary_5 = request.form.get("secondary_5", type=int, default=None),
+ secondary_10 = request.form.get("secondary_10", type=int, default=None),
+ breakHours = request.form.get("breakHours", type=int, default=None)
+ )
+ newApprovedAlloc.save()
+
+ return redirect("/admin/manageDepartments")
diff --git a/app/controllers/main_routes/departmentPortal.py b/app/controllers/main_routes/departmentPortal.py
index b0c33f5e7..2673a874b 100644
--- a/app/controllers/main_routes/departmentPortal.py
+++ b/app/controllers/main_routes/departmentPortal.py
@@ -1,9 +1,62 @@
-from flask import render_template, g
+from flask import render_template, g, request, redirect, flash
+from app.login_manager import require_login
from app.controllers.main_routes import main_bp
from app.logic.getPositions import getPositions
from peewee import DoesNotExist
from app.models.department import Department
+from app.models.allocation import Allocation
from app.models.supervisorDepartment import SupervisorDepartment
+from app.logic.allocationRequest import getOrUpdateRequestedAllocation
+from app.logic.allocationManager import allocationExists
+from app.logic.academicYearManager import getCurrentAndNextAY
+
+
+@main_bp.route('/department/