Skip to content
Open
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
0eb3bb1
Added necessary files for the allocationTable
fritzj2 Jul 30, 2026
5ab2dca
added the individual term for each row in the table
fritzj2 Jul 30, 2026
ce23c09
Bootstrap datatable was implemented
fritzj2 Jul 30, 2026
05216d0
added a download button to the page
fritzj2 Jul 30, 2026
c8f12b1
Added accordians instead of a giant table
fritzj2 Jul 31, 2026
beaba49
structured primaries table
fritzj2 Jul 31, 2026
e981118
Formatted the break table
fritzj2 Jul 31, 2026
fd7c2c6
removed an unecessary card from the HTML
fritzj2 Aug 3, 2026
ddad2d2
added logic using the allocationManager
fritzj2 Aug 3, 2026
eb4e0af
Added break contracts to the table
fritzj2 Aug 3, 2026
9eaf061
fixed function calls, added more data for breaks
fritzj2 Aug 3, 2026
64f4dc4
got the contracts to count in page
fritzj2 Aug 4, 2026
c3e9cc1
Request allocation modification button
fritzj2 Aug 4, 2026
5350883
Created the secondaries table
fritzj2 Aug 4, 2026
f9670d3
table now calls allocations
fritzj2 Aug 4, 2026
23e84d1
fixed table sizing
fritzj2 Aug 4, 2026
54a3f13
added arrows to the accordions in th tables
fritzj2 Aug 4, 2026
cc374dc
fixed formatting of html
fritzj2 Aug 4, 2026
827f390
changed allocation req wording
fritzj2 Aug 4, 2026
5978774
fixed the contract index, the total returns correctly now
fritzj2 Aug 4, 2026
32f8f6b
fixed the sum of break hours
fritzj2 Aug 4, 2026
5110359
added the fall break row
fritzj2 Aug 4, 2026
071232b
moved the header to be centered
fritzj2 Aug 4, 2026
0760c5d
Merge branch 'department-portal-base' into allocation_table
fritzj2 Aug 4, 2026
fa4a35c
fixed format of accordions
fritzj2 Aug 4, 2026
5f44de5
Merge branch 'department-portal-base' of https://github.com/BCStudent…
fritzj2 Aug 5, 2026
764db13
fixed the button layout
fritzj2 Aug 5, 2026
b67164b
Added tests for getBreakContracts
fritzj2 Aug 5, 2026
cdfbae5
made getStudents() less brittle
fritzj2 Aug 5, 2026
2736b90
added notes to getBreakContracts test
fritzj2 Aug 5, 2026
22a1856
added a test for changing terms
fritzj2 Aug 5, 2026
2005c87
created date check in allocationManager
fritzj2 Aug 5, 2026
b9f9cc4
fixed comments for date logic
fritzj2 Aug 6, 2026
96ffe5f
fixed current term logic
fritzj2 Aug 6, 2026
ea29109
shortened js significantly.
fritzj2 Aug 6, 2026
73af911
added a check if no break contracts are found
fritzj2 Aug 6, 2026
76a167b
checks if the user is in a department
fritzj2 Aug 6, 2026
f74fb7d
test_allocationManager accurately reflects changes to logic
fritzj2 Aug 6, 2026
e4b2bc0
fixed test_allocationManager.py name
fritzj2 Aug 7, 2026
8c417f7
contractHours != None -> .is_null(False)
fritzj2 Aug 7, 2026
6299820
removed AddUserToDept route again
fritzj2 Aug 7, 2026
4b2ece2
fixed allocationManager import functions
fritzj2 Aug 7, 2026
1e4d1d4
fixed termCode function calls
fritzj2 Aug 7, 2026
18f1abc
added 404 error to no dept allocation view
fritzj2 Aug 7, 2026
7b0cd5a
added more comments to date contContracts
fritzj2 Aug 7, 2026
8ef2325
break table: spring -> spring break
fritzj2 Aug 19, 2026
a38dc46
test_GestSTudents now works correctly, still brittle
fritzj2 Aug 19, 2026
9c7b727
switched the position of total in the tables.
fritzj2 Aug 19, 2026
47f4f57
added case for no allocation being found
fritzj2 Aug 20, 2026
26be0a4
fixed order of table elements
fritzj2 Aug 20, 2026
b3ec72e
removed print statements from tests
fritzj2 Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions app/controllers/main_routes/main_routes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from flask import render_template, request, json, redirect, url_for, send_file, g, flash, jsonify
from peewee import JOIN, DoesNotExist, fn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image the data tables contracted after a bit when the drop down is open. Try looking into why that is happening.

from functools import reduce
from datetime import datetime, date

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total Contracts row should have a tooltip or event like Primary + Secondary total Contract to show that total contracts mean a combination of both as here you have for both primary and secondary table and that can confuse anyone who are not familiar with the term contract as this isn't labor who is using it is all the departments and supervisor who might not be familiar with the term.

Image

import operator

from app.models.department import Department
Expand All @@ -11,6 +12,7 @@
from app.models.formHistory import FormHistory
from app.models.term import Term
from app.models.positionHistory import PositionHistory
from app.models.allocation import Allocation

from app.controllers.admin_routes.allPendingForms import checkAdjustment
from app.controllers.main_routes import main_bp
Expand All @@ -22,6 +24,7 @@
from app.logic.banner import Banner
from app.logic.getSupervisors import getSupervisors
from app.logic.getPositions import getActivePositions
from app.logic.allocationManager import *
Comment thread
fritzj2 marked this conversation as resolved.
Outdated


@main_bp.route('/logout', methods=['GET'])
Expand Down Expand Up @@ -82,6 +85,71 @@ def departmentPortal(org=None,account=None):
positions = positionsList,
posURL = posURL)

@main_bp.route('/department/<org>/<account>/allocations', methods=['GET'])
def allocationTable(org=None, account=None):
currentUser = g.currentUser
try:
dept = Department.get(Department.ORG == org, Department.ACCOUNT == account)
except (NameError, DoesNotExist):
Comment thread
fritzj2 marked this conversation as resolved.
dept = None

if not currentUser.isLaborAdmin:
allowedDepartmentIds = [d.departmentID for d in getDepartmentsForSupervisor(currentUser)]
if dept.departmentID not in allowedDepartmentIds:
return render_template('errors/403.html'), 403


currentDate = date.today()
if currentDate.month <= 6:
# If it is the spring semester, then the term code is 1 year behind. e.g. 2025-2026 term code is 202500. Thus the - 100 in the spring term.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be in a logic file and have test, I am not going to require you as this is simple logic but many simple logic. However having different combination of math after currentDate.year means this can be turn into a logic function that determines the termcode and we will see similar termcode logic being use in other branches like allocation request.

# The (year * 100) turns the year into an AY term code, 2025 -> 202500. The + 12/11 turns it into a fall or spring term.
springTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 12 - 100).get()
currentAY = Term.select().where(Term.termCode == currentDate.year * 100 - 100).get()
fallTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 11 - 100).get()

else:
fallTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 11).get()
currentAY = Term.select().where(Term.termCode == currentDate.year * 100).get()
springTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 12).get()

allocationDict = getTotalAllocations(currentAY, dept)
Comment thread
fritzj2 marked this conversation as resolved.
Outdated
fallContracts = getContractedAllocations(fallTerm, dept)
springContracts = getContractedAllocations(springTerm, dept)

breakContracts = {
"total": 0,
"thanksgiving":getBreakContracts(currentAY.termCode + 1, dept),
"winter": getBreakContracts(currentAY.termCode + 2, dept),
"spring": getBreakContracts(currentAY.termCode + 3, dept),
"fall":getBreakContracts(currentAY.termCode + 4, dept),
"summer": getBreakContracts(currentAY.termCode + 13, dept)
}
breakContracts["total"] = sum(breakContracts.values())
return render_template('main/allocationTable.html',
department = dept,
currentAY = currentAY,
allocations = allocationDict,
fallContracts = fallContracts,
springContracts = springContracts,
breakContracts = breakContracts)


@main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST'])
def addUserToDept():
Comment thread
fritzj2 marked this conversation as resolved.
Outdated
userDeptData = request.form
supervisorDeptRecord = SupervisorDepartment.get_or_none(supervisor = userDeptData['supervisorID'], department = userDeptData['departmentID'])
try:
if supervisorDeptRecord:
return "False"

else:
SupervisorDepartment.create(supervisor=userDeptData['supervisorID'], department=userDeptData['departmentID'])
return "True"

except Exception as e:
print(f'Could not add user to department: {e}')
return "", 500

@main_bp.route('/supervisorPortal/download', methods=['POST'])
def downloadSupervisorPortalResults():
'''
Expand Down
41 changes: 40 additions & 1 deletion app/logic/allocationManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept:
5-hour positions in the CS department for the 2025 Fall term.
'''
academicYearCode = int(str(termCode)[:4] + "00")

# This sets the date condition to determine whether the form is within the boundaries of the term
# Fall only contracts end before spring, spring contracts start after fall.
fallMonths = ["07","08","09","10","11","12"]
Comment thread
MImran2002 marked this conversation as resolved.
springMonths = ["01","02","03","04","05","06"]
if str(termCode).endswith("11"):
dateCondition = (
(LaborStatusForm.endDate.month.in_(fallMonths)) |
(LaborStatusForm.startDate.month.in_(fallMonths) &
LaborStatusForm.endDate.month.in_(springMonths))
)
elif str(termCode).endswith("12"):
dateCondition = (
(LaborStatusForm.startDate.month.in_(springMonths)) |
(LaborStatusForm.startDate.month.in_(fallMonths) &
LaborStatusForm.endDate.month.in_(springMonths))
)
else:
dateCondition = (
(LaborStatusForm.startDate.month.in_(fallMonths) &
LaborStatusForm.endDate.month.in_(springMonths))

)

lsfCountPositions = FormHistory.select(
).join(LaborStatusForm
).join(Department
Expand All @@ -54,6 +78,7 @@ def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept:
LaborStatusForm.jobType == jobType, # 'primary' or 'secondary'
LaborStatusForm.weeklyHours == weeklyContractHours, # 5, 10, 12, 15, or 20
Department.departmentID == dept,
dateCondition,
).count()
return lsfCountPositions

Expand Down Expand Up @@ -105,4 +130,18 @@ def getContractedAllocations(termCode: int, dept: int):
usedPositions["used_primaries"] = sum(list(usedPositions.values())[:4])
usedPositions["used_secondaries"] = sum(list(usedPositions.values())[4:6])
usedPositions["used_total"] = sum(list(usedPositions.values())[:6])
return usedPositions
return usedPositions

def getBreakContracts(termCode, dept):
break_allocation = FormHistory.select(fn.SUM(LaborStatusForm.contractHours)
).join(LaborStatusForm
).where(
FormHistory.historyType == "Labor Status Form",
FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]),
LaborStatusForm.termCode == termCode,
LaborStatusForm.department == dept,
LaborStatusForm.contractHours != None).scalar()
Comment thread
fritzj2 marked this conversation as resolved.
Outdated
if break_allocation != None:
return break_allocation
else:
return 0
63 changes: 63 additions & 0 deletions app/static/css/allocationTable.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.btn-success{
align-self: center;
justify-self: end;
}
.card-header {
background-color: #efebeb;
margin-bottom: 7px;
height: 6rem;
}
.mb-0, .collapsed {
outline-color: none;
color: black;
font-size: 18px;
font-weight: 525;
}
.collapse{
padding-left: 5% ;
padding-right: 5%;
}
.accordion{
padding-left: 5%;
padding-right: 5%;
}
.table-striped {
table-layout:fixed;
width:100%;
}
.table-striped tbody tr:nth-of-type(odd) {
background-color: #f2f2f2;
}
.btn-info{
justify-self:flex-end;
align-self: center;
margin-left: 4px
}
.accordion-arrow {
display: inline-block;
transition: transform 0.2s ease-in-out;
}
.btn.collapsed .accordion-arrow {
transform: rotate(-90deg);
}
.btn:not(.collapsed) .accordion-arrow {
transform: rotate(0deg);
}
.button-container {
display:flex;
justify-content:end;
}
.btn-block{
align-items: center;
align-self: center;
text-align: center;
justify-content: center;
height: 100%
}
.termDisplay{
margin-right:auto;
}
18 changes: 18 additions & 0 deletions app/static/js/allocationTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$(document).ready( function(){
function initTable(selector) {
return $(selector).DataTable({
pageLength: 25,
info: false,
lengthChange: false,
searching: false,
paging: false,
order: []
});
}

const fallTermPrimaries = initTable('#fallTermPrimaries');
const fallTermSecondaries = initTable('#fallTermSecondaries');
const springTermPrimaries = initTable('#springTermPrimaries');
const springTermSecondaries = initTable('#springTermSecondaries');
const breakTable = initTable('#breakTable');
});
Loading