From 0eb3bb1f511d94ba425217ea70a10960fd173243 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 30 Jul 2026 10:23:43 -0400 Subject: [PATCH 01/60] Added necessary files for the allocationTable --- .../main_routes/departmentPortal.py | 19 +++++- app/controllers/main_routes/main_routes.py | 10 +++ app/static/css/allocationTable.css | 0 app/templates/main/allocationTable.html | 62 +++++++++++++++++++ app/templates/main/departmentPortal.html | 2 +- 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 app/static/css/allocationTable.css create mode 100644 app/templates/main/allocationTable.html diff --git a/app/controllers/main_routes/departmentPortal.py b/app/controllers/main_routes/departmentPortal.py index 351757701..b6b246ab7 100644 --- a/app/controllers/main_routes/departmentPortal.py +++ b/app/controllers/main_routes/departmentPortal.py @@ -1 +1,18 @@ -from flask import render_template +from flask import render_template, g +from peewee import DoesNotExist + +from app.models.department import Department +from app.models.allocation import Allocation +from app.models.laborStatusForm import LaborStatusForm +from app.models.formHistory import formHistory + +from app.controllers.main_routes import main_bp + +@main_bp.route('/department///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): + dept = None + diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index b2c62d1f2..cc4375979 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -82,6 +82,16 @@ def departmentPortal(org=None,account=None): positions = positionsList, posURL = posURL) +@main_bp.route('/department///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): + dept = None + + return render_template('main/allocationTable.html') + @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) def addUserToDept(): userDeptData = request.form diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css new file mode 100644 index 000000000..e69de29bb diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html new file mode 100644 index 000000000..028bc2f79 --- /dev/null +++ b/app/templates/main/allocationTable.html @@ -0,0 +1,62 @@ +{% extends "base.html" %} +{% block styles %} + {{super()}} + +{% endblock %} + +{% block scripts %} + {{super()}} + +{% endblock %} + +{% block app_content %} + +

Aaaaa

+ + + +
+ + + + + + + + + {% for i in [1,2,3,4]%} + + + + + {% endfor %} + +
DepartmentStatus
name(org, account) + +
+
+ +
+ + + + + + + + {% for i in [1,2,3,4] %} + + + + {% endfor %} + +
Department
name(aaa, numbers)
+
+ + +{% endblock %} diff --git a/app/templates/main/departmentPortal.html b/app/templates/main/departmentPortal.html index 549ab272f..06cc7adb4 100644 --- a/app/templates/main/departmentPortal.html +++ b/app/templates/main/departmentPortal.html @@ -36,7 +36,7 @@

{% if department %} {{department.DEPT_NAME}} Portal {% e

Insert Allocations Card Here

From 5ab2dca77fe1b007e8ea7d6e2f53f27baf3a9057 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 30 Jul 2026 13:59:43 -0400 Subject: [PATCH 02/60] added the individual term for each row in the table --- .../main_routes/departmentPortal.py | 1 + app/controllers/main_routes/main_routes.py | 33 +++++++- app/templates/main/allocationTable.html | 78 ++++++++++--------- 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/app/controllers/main_routes/departmentPortal.py b/app/controllers/main_routes/departmentPortal.py index b6b246ab7..74c5d2f0f 100644 --- a/app/controllers/main_routes/departmentPortal.py +++ b/app/controllers/main_routes/departmentPortal.py @@ -16,3 +16,4 @@ def allocationTable(org=None, account=None): except (NameError, DoesNotExist): dept = None + return render_template('main/') \ No newline at end of file diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index cc4375979..ee50fa032 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -11,6 +11,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 @@ -90,7 +91,37 @@ def allocationTable(org=None, account=None): except (NameError, DoesNotExist): dept = None - return render_template('main/allocationTable.html') + returnTerms = [] + terms = Term.select().order_by(Term.termCode.desc()) + + testAllocationDict = {"primary_10": 1, + "primary_12": 2, + "primary_15": 3, + "primary_20": 4, + "secondary_5": 5, + "secondary_10": 6, + "breakHours": 500, + "totalPrimaries": 10, + "totalSecondaries": 11, + "totalAllocations": 21 } + allocationDict = {} + for term in terms: + if str(term.termCode).endswith("00"): + returnTerms.append(term.termName) + + try: + allocationObject = allocationObject = Allocation.select().where( + Allocation.termCode == term.termCode, + Allocation.department == 3,).dicts().get() + allocationDict[term.termName] = testAllocationDict + + except Exception as e: + allocationDict[term.termName] = {} + + return render_template('main/allocationTable.html', + department = dept, + terms = returnTerms, + allocations = allocationDict) @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) def addUserToDept(): diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 028bc2f79..8d24fb866 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -11,52 +11,60 @@ {% block app_content %} -

Aaaaa

+

View Allocations for {{department.DEPT_NAME}}

+
*Position allocations are placed (contracted/allocated) in the table
-
- +
+
- - - + + + + + + + + + + + + + + - - {% for i in [1,2,3,4]%} - - - - + + {% for term in terms%} + {% if allocations[term] != {} %} + + + + + + + + + + + + + + + + {% else %} + + + + {% endif %} {% endfor %}
DepartmentStatus
TermTotal Position AllocationTotal Break Allocations10 hour12 Hour15 Hour20 Hour5 Hour Secondary10 Hour SecondaryFall BreakWinter BreakSpring BreakSummer Break
name(org, account) - -
{{term}}{{allocations[term]["totalAllocations"]}}{{allocations[term]["breakHours"]}}{{allocations[term]["primary_10"]}}{{ allocations[term]["primary_12"]}}{{allocations[term]["primary_15"]}}{{allocations[term]["primary_20"]}}{{allocations[term]["secondary_5"]}}{{allocations[term]["secondary_10"]}}Fall BreakWinter BreakSpring BreakSummer Break
No allocation data for {{term}}
-
- - - - - - - - {% for i in [1,2,3,4] %} - - - - {% endfor %} - -
Department
name(aaa, numbers)
-
+ {% endblock %} From ce23c09b13919cac94d308cb4ced8b0f1cd5fcde Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 30 Jul 2026 14:58:22 -0400 Subject: [PATCH 03/60] Bootstrap datatable was implemented --- app/static/js/allocationTable.js | 7 +++++++ app/templates/main/allocationTable.html | 12 +++++------- 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 app/static/js/allocationTable.js diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js new file mode 100644 index 000000000..53f5dfbde --- /dev/null +++ b/app/static/js/allocationTable.js @@ -0,0 +1,7 @@ +$(document).ready( function(){ + allocationTable = $('#allocationTable'); + allocationTable.DataTable({ + searching: true, + pageLength: 25 + }); +}); \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 8d24fb866..c3fc221c1 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -1,11 +1,14 @@ {% extends "base.html" %} {% block styles %} {{super()}} + {% endblock %} {% block scripts %} {{super()}} + + {% endblock %} @@ -17,7 +20,7 @@
*Position allocations are placed (contracted/alloca
- @@ -38,7 +41,6 @@
*Position allocations are placed (contracted/alloca
{% for term in terms%} - {% if allocations[term] != {} %} @@ -54,11 +56,7 @@
*Position allocations are placed (contracted/alloca
- {% else %} - - - - {% endif %} + {% endfor %}
{{term}} {{allocations[term]["totalAllocations"]}}Spring Break Summer Break
No allocation data for {{term}}
From 05216d031c9281ede0d70206ff88284f516c1f75 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 30 Jul 2026 16:29:57 -0400 Subject: [PATCH 04/60] added a download button to the page --- app/static/css/allocationTable.css | 11 +++++++++++ app/static/js/allocationTable.js | 10 +++++++++- app/templates/main/allocationTable.html | 5 +++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index e69de29bb..4d596f8c2 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -0,0 +1,11 @@ +.grid-container { + display: grid; + grid-template-columns: 1fr 1fr; +} +.btn-success{ + justify-self:end; + align-self: center; + margin-left:8rem; + width:fit-content; + height:fit-content +} \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 53f5dfbde..6087cf49e 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -1,7 +1,15 @@ $(document).ready( function(){ + const entriesPerYear = 5; + allocationTable = $('#allocationTable'); allocationTable.DataTable({ + paging: true, searching: true, - pageLength: 25 + pageLength: 5, + lengthMenu:[[5,10,20,50,-1], + ['5', '10', '20', '50', 'All']], + "order": [ + 0, "desc" + ] }); }); \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index c3fc221c1..61fed782a 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -13,10 +13,11 @@ {% endblock %} {% block app_content %} - +

View Allocations for {{department.DEPT_NAME}}

+
*Position allocations are placed (contracted/allocated) in the table
- +
From c8f12b1aa382c11fec7572ba08ea474874745347 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 31 Jul 2026 14:41:10 -0400 Subject: [PATCH 05/60] Added accordians instead of a giant table --- app/controllers/main_routes/main_routes.py | 25 ++--- app/static/css/allocationTable.css | 10 ++ app/static/js/allocationTable.js | 16 +-- app/templates/main/allocationTable.html | 108 ++++++++++++--------- 4 files changed, 79 insertions(+), 80 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index ee50fa032..9bacf0091 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -91,10 +91,9 @@ def allocationTable(org=None, account=None): except (NameError, DoesNotExist): dept = None - returnTerms = [] - terms = Term.select().order_by(Term.termCode.desc()) + currentTerm = Term.select().where(Term.termCode == 202500).get() #FIXME - testAllocationDict = {"primary_10": 1, + allocationDict = {"primary_10": 1, "primary_12": 2, "primary_15": 3, "primary_20": 4, @@ -103,24 +102,12 @@ def allocationTable(org=None, account=None): "breakHours": 500, "totalPrimaries": 10, "totalSecondaries": 11, - "totalAllocations": 21 } - allocationDict = {} - for term in terms: - if str(term.termCode).endswith("00"): - returnTerms.append(term.termName) - - try: - allocationObject = allocationObject = Allocation.select().where( - Allocation.termCode == term.termCode, - Allocation.department == 3,).dicts().get() - allocationDict[term.termName] = testAllocationDict - - except Exception as e: - allocationDict[term.termName] = {} - + "totalAllocations": 21} + print("\n\n\n\n\n") + print(allocationDict) return render_template('main/allocationTable.html', department = dept, - terms = returnTerms, + term = currentTerm, allocations = allocationDict) @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 4d596f8c2..bc1bdbebf 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -8,4 +8,14 @@ margin-left:8rem; width:fit-content; height:fit-content +} +.card-header { + background-color: #efebeb; + margin-bottom: 7px; +} +.mb-0, .collapsed { + outline-color: none; + color: black; + font-size: 18px; + font-weight: 525; } \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 6087cf49e..566dc174a 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -1,15 +1 @@ -$(document).ready( function(){ - const entriesPerYear = 5; - - allocationTable = $('#allocationTable'); - allocationTable.DataTable({ - paging: true, - searching: true, - pageLength: 5, - lengthMenu:[[5,10,20,50,-1], - ['5', '10', '20', '50', 'All']], - "order": [ - 0, "desc" - ] - }); -}); \ No newline at end of file +$("#admin").collapse("show"); diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 61fed782a..a5e20d591 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -13,57 +13,73 @@ {% endblock %} {% block app_content %} -
-

View Allocations for {{department.DEPT_NAME}}

- + + +
+

View {{department.DEPT_NAME}} Allocations

+
*Position allocations are placed (contracted/allocated) in the table
- -
- - - - - - - - - - - - - - - - - - - - {% for term in terms%} - - - - - - - - - - - - - - - +
+
+

Current Term: {{term.termName}}

+

Total AY Positions: {{allocations['totalAllocations']}}

+
+ - {% endfor %} - -
TermTotal Position AllocationTotal Break Allocations10 hour12 Hour15 Hour20 Hour5 Hour Secondary10 Hour SecondaryFall BreakWinter BreakSpring BreakSummer Break
{{term}}{{allocations[term]["totalAllocations"]}}{{allocations[term]["breakHours"]}}{{allocations[term]["primary_10"]}}{{ allocations[term]["primary_12"]}}{{allocations[term]["primary_15"]}}{{allocations[term]["primary_20"]}}{{allocations[term]["secondary_5"]}}{{allocations[term]["secondary_10"]}}Fall BreakWinter BreakSpring BreakSummer Break
-
+
+ + +
+
+ + +
+
+
+ Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. +
+
+
- + +
+
+ + +
+
+
+ Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. +
+
+
+ +
+
+ + +
+
+
+ Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. +
+
+
+
{% endblock %} From beaba49b382ae93db30e4d00554527a9e1f72cfc Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 31 Jul 2026 16:11:08 -0400 Subject: [PATCH 06/60] structured primaries table --- app/static/css/allocationTable.css | 8 ++++ app/static/js/allocationTable.js | 11 ++++- app/templates/main/allocationTable.html | 60 +++++++++++++++++++------ 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index bc1bdbebf..23296bca0 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -18,4 +18,12 @@ color: black; font-size: 18px; font-weight: 525; +} +.collapse{ + padding-left: 5% ; + padding-right: 5%; +} +.accordion{ + padding-left: 5%; + padding-right: 5%; } \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 566dc174a..d8260015a 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -1 +1,10 @@ -$("#admin").collapse("show"); +$(document).ready( function(){ + fallTermTable = $('#fallTermTable'); + fallTermTable.DataTable({ + pageLength: 25, + info: false, + lengthChange: false, + searching: false, + paging: false + }); +}); \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index a5e20d591..46acb7c7a 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -28,26 +28,58 @@

Total AY Positions: {{allocations['totalAllocations']}}

-
+
- +
-
+
-
-
-
- Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrimariesContractedAllocated
Total Primariesnot implemented{{allocations["totalPrimaries"]}}
10 Hournot implemented{{allocations["primary_10"]}}
12 Hournot implemented{{allocations["primary_12"]}}
15 Hournot implemented{{allocations["primary_15"]}}
20 Hournot implemented{{allocations["primary_20"]}}
-
- +
@@ -64,17 +96,17 @@

- +
-
+
-
-
+
Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi.
From e9811183e61bb5cd96b9b156c53254ed94490773 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 31 Jul 2026 16:56:28 -0400 Subject: [PATCH 07/60] Formatted the break table --- app/static/css/allocationTable.css | 3 + app/static/js/allocationTable.js | 17 ++++++ app/templates/main/allocationTable.html | 73 ++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 23296bca0..a908d4f4a 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -26,4 +26,7 @@ .accordion{ padding-left: 5%; padding-right: 5%; +} +.table-striped tbody tr:nth-of-type(odd) { + background-color: #f2f2f2; /* Your custom color */ } \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index d8260015a..946a7a300 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -7,4 +7,21 @@ $(document).ready( function(){ searching: false, paging: false }); + + springTermTable = $('#springTermTable'); + springTermTable.DataTable({ + pageLength: 25, + info: false, + lengthChange: false, + searching: false, + paging: false + }); + breakTable = $('#breakTable'); + breakTable.DataTable({ + pageLength: 25, + info: false, + lengthChange: false, + searching: false, + paging: false + }); }); \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 46acb7c7a..f139dbc72 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -91,7 +91,41 @@

- Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrimariesContractedAllocated
Total Primariesnot implemented{{allocations["totalPrimaries"]}}
10 Hournot implemented{{allocations["primary_10"]}}
12 Hournot implemented{{allocations["primary_12"]}}
15 Hournot implemented{{allocations["primary_15"]}}
20 Hournot implemented{{allocations["primary_20"]}}
@@ -108,7 +142,42 @@

- Distinctio, architecto ab quasi aut eius inventore placeat natus voluptatem sit excepturi. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrimariesContractedAllocated
Total Break Hoursnot implemented{{allocations["breakHours"]}}
Thanksgiving / Fall Breaknot implemented
Winter Breaknot implemented
Springnot implemented
Summer Breaknot implemented
From fd7c2c66920dac19bb1777ad84cbd61b12d98bb5 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 3 Aug 2026 09:16:23 -0400 Subject: [PATCH 08/60] removed an unecessary card from the HTML --- app/templates/main/allocationTable.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index f139dbc72..c287f994c 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -90,7 +90,6 @@

-
@@ -126,7 +125,6 @@

-
@@ -141,7 +139,6 @@

-
@@ -178,7 +175,6 @@

-
From ddad2d27bf27f0d841d9e8902c677853347850ab Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 3 Aug 2026 11:22:14 -0400 Subject: [PATCH 09/60] added logic using the allocationManager --- app/controllers/main_routes/main_routes.py | 50 +++++++- app/logic/allocationManager.py | 129 +++++++++++++++++++++ app/static/js/allocationTable.js | 9 +- app/templates/main/allocationTable.html | 33 +++--- 4 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 app/logic/allocationManager.py diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 9bacf0091..75f010caa 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -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 from functools import reduce +from datetime import datetime, date import operator from app.models.department import Department @@ -23,6 +24,8 @@ from app.logic.banner import Banner from app.logic.getSupervisors import getSupervisors from app.logic.getPositions import getActivePositions +from app.logic.allocationManager import * + @main_bp.route('/logout', methods=['GET']) @@ -91,8 +94,21 @@ def allocationTable(org=None, account=None): except (NameError, DoesNotExist): dept = None - currentTerm = Term.select().where(Term.termCode == 202500).get() #FIXME + if currentUser.isLaborAdmin: + pass + else: + departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) + currentDate = date.today() + print(f"current datae \n\n\n\n\n\n\n{str(currentDate)[:4]} \n\n\n") + currentAY = currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "00")).get() + + if currentDate.month >= 1 and currentDate.month <= 6: + pass + currentTerm = Term.select().where(Term.termCode == int(str(2025)[:4] + "12")).get() + else: + pass + currentTerm = Term.select().where(Term.termCode == int(str(2025)[:4] + "11")).get() allocationDict = {"primary_10": 1, "primary_12": 2, "primary_15": 3, @@ -103,12 +119,40 @@ def allocationTable(org=None, account=None): "totalPrimaries": 10, "totalSecondaries": 11, "totalAllocations": 21} + fallContracts = { + "used_10": 4, + "used_12": 4, + "used_15": 4, + "used_20": 4, + "used_5_sec": 4, + "used_10_sec": 4, + "used_total": 0, + "break_hours": "3" + } + springContracts = { + "used_10": 4, + "used_12": 4, + "used_15": 4, + "used_20": 4, + "used_5_sec": 4, + "used_10_sec": 4, + "used_total": 0, + "break_hours": "3" + } + breakContracts = { + "coolContract": getBreakContracts(202500, dept) + } + print(f"\n\n\n coolcontract {breakContracts}\n\n\n") + print("\n\n\n\n\n") print(allocationDict) return render_template('main/allocationTable.html', department = dept, - term = currentTerm, - allocations = allocationDict) + currentAY = currentAY, + allocations = allocationDict, + fallContracts = fallContracts, + springContracts = springContracts) + @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) def addUserToDept(): diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py new file mode 100644 index 000000000..3da0c6222 --- /dev/null +++ b/app/logic/allocationManager.py @@ -0,0 +1,129 @@ +from app.models.allocation import Allocation +from app.models.laborStatusForm import * +from app.models.department import * +from app.models.term import * +from app.models.formHistory import FormHistory +from peewee import JOIN + + +def getAllocation(termCode, dept): + academicYearCode = int(str(termCode)[:5] + "00") + allocationObject = Allocation.select().where( + Allocation.termCode.in_([termCode,academicYearCode]), + Allocation.department == dept, + Allocation.isFinal == True).dicts().get() + return allocationObject + + +def getAllocationNonFinal(termCode, dept): + academicYearCode = int(str(termCode)[:5] + "00") + allocationObject = Allocation.select().where( + Allocation.termCode.in_([termCode,academicYearCode]), + Allocation.department == dept, + Allocation.isFinal == False).dicts().get() + return allocationObject + + + +def getTotalAllocations(termCode, dept): + allocationObject = getAllocation(termCode, dept) + allocationDict = {"primary_10": allocationObject["primary_10"], + "primary_12": allocationObject["primary_12"], + "primary_15": allocationObject["primary_15"], + "primary_20": allocationObject["primary_20"], + "secondary_5": allocationObject["secondary_5"], + "secondary_10": allocationObject["secondary_10"], + "breakHours": allocationObject["breakHours"], + "totalPrimaries": (allocationObject["primary_10"] + allocationObject["primary_12"] + allocationObject["primary_15"] + allocationObject["primary_20"]), + "totalSecondaries": (allocationObject["secondary_5"] + allocationObject["secondary_10"]), + "totalAllocations": (allocationObject["primary_10"] + allocationObject["primary_12"] + allocationObject["primary_15"] + allocationObject["primary_20"] + allocationObject["secondary_5"] + allocationObject["secondary_10"] )} + return allocationDict + +def countContracts(jobType, weeklyContractHours, termCode, dept): + academicYearCode = int(str(termCode)[:5] + "00") + lsfCountPrimaries = FormHistory.select( + ).join(LaborStatusForm + ).join(Department + ).where( + FormHistory.historyType == "Labor Status Form", + FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), + LaborStatusForm.termCode.in_([termCode,academicYearCode]), + LaborStatusForm.jobType == jobType, + LaborStatusForm.weeklyHours == weeklyContractHours, + Department.departmentID == dept, + ).count() + return lsfCountPrimaries + +def getContractedAllocations(termCode, dept): + academicYearCode = int(str(termCode)[:5] + "00") + allocationObject = getAllocation(termCode, dept) + break_allocation = FormHistory.select( + LaborStatusForm.department, + LaborStatusForm.termCode, + fn.SUM(LaborStatusForm.contractHours).alias('total_hours') + ).join( + LaborStatusForm, + on=(FormHistory.formID == LaborStatusForm.laborStatusFormID), + ).join( + Term, + on = (LaborStatusForm.termCode == Term.termCode ) + ).where( + (FormHistory.historyType == "Labor Status Form") & + (FormHistory.status == "Approved") & + (LaborStatusForm.termCode.in_([termCode,academicYearCode])) + ).group_by( + LaborStatusForm.department, + LaborStatusForm.termCode).dicts() + + breakSum = {"total_hours": 0} + if dept: + for row in break_allocation: + if row["department"] == dept: + breakSum = row + break + + usedPositions = { + "used_10": countContracts("Primary", "10", termCode, dept), + "used_12": countContracts("Primary", "12", termCode, dept), + "used_15": countContracts("Primary", "15", termCode, dept), + "used_20": countContracts("Primary", "20", termCode, dept), + "used_5_sec": countContracts("Secondary", "5", termCode, dept), + "used_10_sec": countContracts("Secondary", "10", termCode, dept), + "used_total": 0, + "break_hours": breakSum["total_hours"] + } + usedPositions["used_total"] = sum(list(usedPositions.values())[:7]) + return usedPositions + +def getBreakContracts(termCode, dept): + academicYearCode = (str(termCode)[:4]) + break_allocaiton = FormHistory.select( + ).join(LaborStatusForm + ).join(Department + ).where( + FormHistory.historyType == "Labor Status Form", + FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), + LaborStatusForm.termCode == [termCode], + LaborStatusForm.weeklyHours == None, + Department.departmentID == dept.departmentID, + ).count() + + + # break_allocation = FormHistory.select( + # LaborStatusForm.department, + # LaborStatusForm.termCode, + # fn.SUM(LaborStatusForm.contractHours).alias('total_hours') + # ).join( + # LaborStatusForm, + # on=(FormHistory.formID == LaborStatusForm.laborStatusFormID), + # ).join( + # Term, + # on = (LaborStatusForm.termCode == Term.termCode ) + # ).where( + # (FormHistory.historyType == "Labor Status Form") & + # (FormHistory.status == "Approved") & + # (LaborStatusForm.termCode.in_([termCode])) + # ).group_by( + # LaborStatusForm.department, + # LaborStatusForm.termCode).dicts() + return break_allocaiton \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 946a7a300..bd3a5b910 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -5,7 +5,8 @@ $(document).ready( function(){ info: false, lengthChange: false, searching: false, - paging: false + paging: false, + "order": [] }); springTermTable = $('#springTermTable'); @@ -14,7 +15,8 @@ $(document).ready( function(){ info: false, lengthChange: false, searching: false, - paging: false + paging: false, + "order": [] }); breakTable = $('#breakTable'); breakTable.DataTable({ @@ -22,6 +24,7 @@ $(document).ready( function(){ info: false, lengthChange: false, searching: false, - paging: false + paging: false, + "order": [] }); }); \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index c287f994c..97310db71 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -23,8 +23,7 @@
*Position allocations are placed (contracted/alloca
-

Current Term: {{term.termName}}

-

Total AY Positions: {{allocations['totalAllocations']}}

+

Current Term: {{currentAY.termName}}

@@ -36,7 +35,7 @@

Total AY Positions: {{allocations['totalAllocations']}}

@@ -52,26 +51,26 @@

Total Primaries - not implemented + {{fallContracts["used_total"]}} {{allocations["totalPrimaries"]}} 10 Hour - not implemented + {{fallContracts["used_10"]}} {{allocations["primary_10"]}} 12 Hour - not implemented + {{fallContracts["used_12"]}} {{allocations["primary_12"]}} 15 Hour - not implemented + {{fallContracts["used_15"]}} {{allocations["primary_15"]}} 20 Hour - not implemented + {{fallContracts["used_20"]}} {{allocations["primary_20"]}} @@ -85,7 +84,7 @@

@@ -101,26 +100,26 @@

Total Primaries - not implemented + {{springContracts["used_total"]}} {{allocations["totalPrimaries"]}} 10 Hour - not implemented + {{springContracts["used_10"]}} {{allocations["primary_10"]}} 12 Hour - not implemented + {{springContracts["used_12"]}} {{allocations["primary_12"]}} - 15 Hour - not implemented + 15 Hour + {{springContracts["used_15"]}} {{allocations["primary_15"]}} - 20 Hour - not implemented + 20 Hour + {{springContracts["used_20"]}} {{allocations["primary_20"]}} @@ -134,7 +133,7 @@

From eb4e0af105fdc633365cf1544de4022b719b3ae0 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 3 Aug 2026 15:28:09 -0400 Subject: [PATCH 10/60] Added break contracts to the table --- app/controllers/main_routes/main_routes.py | 22 ++-- app/logic/allocationManager.py | 13 +-- app/templates/main/allocationTable.html | 12 +-- database/demo_data.py | 119 ++++++++++++++++++++- 4 files changed, 140 insertions(+), 26 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 75f010caa..607479166 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -103,12 +103,14 @@ def allocationTable(org=None, account=None): print(f"current datae \n\n\n\n\n\n\n{str(currentDate)[:4]} \n\n\n") currentAY = currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "00")).get() + # currentAY = currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "00")).get() + if currentDate.month >= 1 and currentDate.month <= 6: pass - currentTerm = Term.select().where(Term.termCode == int(str(2025)[:4] + "12")).get() + currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "12")).get() else: pass - currentTerm = Term.select().where(Term.termCode == int(str(2025)[:4] + "11")).get() + currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "11")).get() allocationDict = {"primary_10": 1, "primary_12": 2, "primary_15": 3, @@ -140,18 +142,20 @@ def allocationTable(org=None, account=None): "break_hours": "3" } breakContracts = { - "coolContract": getBreakContracts(202500, dept) - } - print(f"\n\n\n coolcontract {breakContracts}\n\n\n") - - print("\n\n\n\n\n") - print(allocationDict) + "thanksgiving":getBreakContracts(202201, dept),#FIXME + "winter": getBreakContracts(202202, dept), + "spring": getBreakContracts(202203, dept), + "fall":getBreakContracts(202204, dept), + "summer": getBreakContracts(202213, dept) + } + return render_template('main/allocationTable.html', department = dept, currentAY = currentAY, allocations = allocationDict, fallContracts = fallContracts, - springContracts = springContracts) + springContracts = springContracts, + breakContracts = breakContracts) @main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 3da0c6222..a9935920e 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -3,7 +3,7 @@ from app.models.department import * from app.models.term import * from app.models.formHistory import FormHistory -from peewee import JOIN +from peewee import JOIN, fn def getAllocation(termCode, dept): @@ -97,17 +97,14 @@ def getContractedAllocations(termCode, dept): def getBreakContracts(termCode, dept): academicYearCode = (str(termCode)[:4]) - break_allocaiton = FormHistory.select( + break_allocaiton = FormHistory.select(fn.SUM(LaborStatusForm.contractHours) ).join(LaborStatusForm - ).join(Department ).where( FormHistory.historyType == "Labor Status Form", FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), - LaborStatusForm.termCode == [termCode], - LaborStatusForm.weeklyHours == None, - Department.departmentID == dept.departmentID, - ).count() - + LaborStatusForm.termCode == termCode, + LaborStatusForm.department == dept, + LaborStatusForm.weeklyHours == None).scalar() # break_allocation = FormHistory.select( # LaborStatusForm.department, diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 97310db71..03aa702aa 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -149,27 +149,27 @@

Total Break Hours - not implemented + {{breakContracts['total_hours']}} {{allocations["breakHours"]}} Thanksgiving / Fall Break - not implemented + {{breakContracts['thanksgiving']}} Winter Break - not implemented + {{breakContracts['winter']}} Spring - not implemented + {{breakContracts['spring']}} - Summer Break - not implemented + Summer Term + {{breakContracts['summer']}} diff --git a/database/demo_data.py b/database/demo_data.py index 54910f412..e9e45d6e0 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -40,8 +40,37 @@ "STU_CPO":"700", "LAST_POSN":"Media Technician", "LAST_SUP_PIDM":"7" + }, + { + "ID":"B00741361", + "PIDM":"99", + "FIRST_NAME":"Antonia", + "LAST_NAME":"Schmith", + "CLASS_LEVEL":"Freshman", + "ACADEMIC_FOCUS":"Computer Science", + "MAJOR":"Computer Science", + "PROBATION":"0", + "ADVISOR":"Scott Heggen", + "STU_EMAIL":"schmitha@berea.edu", + "STU_CPO":"777", + "LAST_POSN":"TA", + "LAST_SUP_PIDM":"7" + }, + { + "ID":"B00732363", + "PIDM":"58", + "FIRST_NAME":"Barbara", + "LAST_NAME":"Williams", + "CLASS_LEVEL":"Junior", + "ACADEMIC_FOCUS":"Computer Science", + "MAJOR":"Computer Science", + "PROBATION":"0", + "ADVISOR":"Jasmine Jones", + "STU_EMAIL":"williamsb@berea.edu", + "STU_CPO":"118", + "LAST_POSN":"TA", + "LAST_SUP_PIDM":"7" }, - { "ID":"B00730361", "PIDM":"1", @@ -104,7 +133,16 @@ "LAST_POSN":"Student Manager", "LAST_SUP_PIDM":"7" }, - ] + {"ID": "B00811617", "legal_name": "Chris Georgiev", "isActive": True, "PIDM": "8", "FIRST_NAME": "Chris", "LAST_NAME": "Georgiev"}, + {"ID": "B00815474", "legal_name": "Julius Fritz", "isActive": True, "PIDM": "9", "FIRST_NAME": "Julius", "LAST_NAME": "Fritz"}, + {"ID": "B12345223", "legal_name": "Subaru Natsuki", "isActive": True, "PIDM": "10", "FIRST_NAME": "Subaru", "LAST_NAME": "Natsuki"}, + {"ID": "B12345003", "legal_name": "Hatsune Miku", "isActive": True, "PIDM": "11", "FIRST_NAME": "Hatsune", "LAST_NAME": "Miku"}, + {"ID": "B12345772", "legal_name": "Michael Jackson", "isActive": True, "PIDM": "12", "FIRST_NAME": "Michael", "LAST_NAME": "Jackson"}, + {"ID": "B12345756", "legal_name": "Genji Overwatch", "isActive": True, "PIDM": "13", "FIRST_NAME": "Genji", "LAST_NAME": "Overwatch"}, + {"ID": "B12345759", "legal_name": "Mister Marlowe", "isActive": True, "PIDM": "14", "FIRST_NAME": "Mister", "LAST_NAME": "Marlowe"}, + {"ID": "B11231123", "legal_name": "Mister Thanksgiving", "isActive": True, "PIDM": "15", "FIRST_NAME": "Mister", "LAST_NAME": "Thanksgiving"} + + ] tracyStudents = [ { "ID":"B00785329", @@ -641,7 +679,82 @@ "createdBy_id": 1, "createdDate": f"2025-04-14", "status_id": "Approved" - }]).on_conflict_replace().execute() + }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + + "laborStatusFormID": 9, + "termCode_id": f"202500", + "studentName": "Genji Overwatch", + "studentSupervisee_id": "B12345756", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "overwtahc guy", + "POSN_CODE": "S61410", + "contractHours": 15, + "startDate": f"2025-04-01", + "endDate": "2025-09-01" + + }]).on_conflict_replace().execute() +FormHistory.insert([{ + "formHistoryID": 9, + "formID_id": "9", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": f"2025-04-14", + "status_id": "Approved" + }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + + "laborStatusFormID": 60, + "termCode_id": f"202500", + "studentName": "Mister Marlowe", + "studentSupervisee_id": "B12345759", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Break Worker", + "POSN_CODE": "S61412", + "contractHours": 400, + "startDate": f"2025-04-01", + "endDate": "2025-09-01" + + }]).on_conflict_replace().execute() +FormHistory.insert([{ + "formHistoryID": 60, + "formID_id": "60", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": f"2025-04-14", + "status_id": "Approved" + }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + + "laborStatusFormID": 61, + "termCode_id": f"202501", + "studentName": "Mister Thanksgiving", + "studentSupervisee_id": "B11231123", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Thanksgiving Worker", + "POSN_CODE": "S61412", + "contractHours": 50, + "startDate": f"2025-11-23", + "endDate": "2025-12-01" + + }]).on_conflict_replace().execute() +FormHistory.insert([{ + "formHistoryID": 61, + "formID_id": "61", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": f"2025-11-01", + "status_id": "Approved" + }]).on_conflict_replace().execute() From 9eaf06176eba5a0d1cf9611e7862fb0647d433e9 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 3 Aug 2026 16:56:17 -0400 Subject: [PATCH 11/60] fixed function calls, added more data for breaks --- app/controllers/main_routes/main_routes.py | 28 +- database/demo_data.py | 314 ++++++++++++++++++++- 2 files changed, 326 insertions(+), 16 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 607479166..4a3001089 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -99,18 +99,15 @@ def allocationTable(org=None, account=None): else: departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) - currentDate = date.today() - print(f"current datae \n\n\n\n\n\n\n{str(currentDate)[:4]} \n\n\n") - currentAY = currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "00")).get() + currentDate = str(date.today()) - # currentAY = currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "00")).get() - - if currentDate.month >= 1 and currentDate.month <= 6: - pass - currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "12")).get() + if currentDate.month <= 6: + currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() + currentAY = currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "00").get() else: - pass - currentTerm = Term.select().where(Term.termCode == int(str(currentDate)[:4] + "11")).get() + currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "11").get() + currentAY = Term.select().where(Term.termCode == currentDate[:4] + "00").get() + allocationDict = {"primary_10": 1, "primary_12": 2, "primary_15": 3, @@ -121,6 +118,7 @@ def allocationTable(org=None, account=None): "totalPrimaries": 10, "totalSecondaries": 11, "totalAllocations": 21} + # fallContracts = getContractedAllocations(currentTerm, dept) fallContracts = { "used_10": 4, "used_12": 4, @@ -142,11 +140,11 @@ def allocationTable(org=None, account=None): "break_hours": "3" } breakContracts = { - "thanksgiving":getBreakContracts(202201, dept),#FIXME - "winter": getBreakContracts(202202, dept), - "spring": getBreakContracts(202203, dept), - "fall":getBreakContracts(202204, dept), - "summer": getBreakContracts(202213, dept) + "thanksgiving":getBreakContracts(202401, dept),#FIXME + "winter": getBreakContracts(202402, dept), + "spring": getBreakContracts(202403, dept), + "fall":getBreakContracts(202404, dept), + "summer": getBreakContracts(202413, dept) } return render_template('main/allocationTable.html', diff --git a/database/demo_data.py b/database/demo_data.py index e9e45d6e0..7ad8493fe 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -140,7 +140,17 @@ {"ID": "B12345772", "legal_name": "Michael Jackson", "isActive": True, "PIDM": "12", "FIRST_NAME": "Michael", "LAST_NAME": "Jackson"}, {"ID": "B12345756", "legal_name": "Genji Overwatch", "isActive": True, "PIDM": "13", "FIRST_NAME": "Genji", "LAST_NAME": "Overwatch"}, {"ID": "B12345759", "legal_name": "Mister Marlowe", "isActive": True, "PIDM": "14", "FIRST_NAME": "Mister", "LAST_NAME": "Marlowe"}, - {"ID": "B11231123", "legal_name": "Mister Thanksgiving", "isActive": True, "PIDM": "15", "FIRST_NAME": "Mister", "LAST_NAME": "Thanksgiving"} + {"ID": "B11231123", "legal_name": "Mister Thanksgiving", "isActive": True, "PIDM": "15", "FIRST_NAME": "Mister", "LAST_NAME": "Thanksgiving"}, + {"ID": "B12345762", "legal_name": "Alex Carter", "isActive": True, "PIDM": "16", "FIRST_NAME": "Alex", "LAST_NAME": "Carter"}, + {"ID": "B12345763", "legal_name": "Morgan Hayes", "isActive": True, "PIDM": "17", "FIRST_NAME": "Morgan", "LAST_NAME": "Hayes"}, + {"ID": "B12345764", "legal_name": "Jordan Brooks", "isActive": True, "PIDM": "18", "FIRST_NAME": "Jordan", "LAST_NAME": "Brooks"}, + {"ID": "B12345765", "legal_name": "Taylor Morgan", "isActive": True, "PIDM": "19", "FIRST_NAME": "Taylor", "LAST_NAME": "Morgan"}, + {"ID": "B12345766", "legal_name": "Casey Turner", "isActive": True, "PIDM": "20", "FIRST_NAME": "Casey", "LAST_NAME": "Turner"}, + {"ID": "B12345767", "legal_name": "Jamie Foster", "isActive": True, "PIDM": "21", "FIRST_NAME": "Jamie", "LAST_NAME": "Foster"}, + {"ID": "B12345768", "legal_name": "Riley Cooper", "isActive": True, "PIDM": "22", "FIRST_NAME": "Riley", "LAST_NAME": "Cooper"}, + {"ID": "B12345769", "legal_name": "Drew Bennett", "isActive": True, "PIDM": "23", "FIRST_NAME": "Drew", "LAST_NAME": "Bennett"}, + {"ID": "B12345770", "legal_name": "Logan Price", "isActive": True, "PIDM": "24", "FIRST_NAME": "Logan", "LAST_NAME": "Price"}, + {"ID": "B12345771", "legal_name": "Avery Sullivan", "isActive": True, "PIDM": "25", "FIRST_NAME": "Avery", "LAST_NAME": "Sullivan"}, ] tracyStudents = [ @@ -623,6 +633,83 @@ "adjustmentCutOff": f"2025-09-01", "isBreak": 1, }, + { + "termCode": "202600", + "termName": "AY 2026-2027", + "termStart": "2026-08-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + }, + { + "termCode": "202601", + "termName": "Thanksgiving Break 2026", + "termStart": "2026-08-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + "isBreak": 1, + }, + { + "termCode": "202602", + "termName": "Christmas Break 2026", + "termStart": "2026-08-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + "isBreak": 1, + }, + { + "termCode": "202603", + "termName": "Spring Break 2027", + "termStart": "2026-08-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + "isBreak": 1, + }, + { + "termCode": "202604", + "termName": "Fall Break 2026", + "termStart": "2026-08-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + "isBreak": 1, + }, + { + "termCode": "202611", + "termName": "Fall 2026", + "termStart": "2026-08-01", + "termEnd": "2026-12-31", + "termState": 0, + "primaryCutOff": "2026-09-01", + "adjustmentCutOff": "2026-10-01", + }, + { + "termCode": "202612", + "termName": "Spring 2027", + "termStart": "2027-01-01", + "termEnd": "2027-05-01", + "termState": 0, + "primaryCutOff": "2027-02-01", + "adjustmentCutOff": "2027-03-01", + }, + { + "termCode": "202613", + "termName": "Summer 2027", + "termStart": "2027-05-02", + "termEnd": "2027-08-01", + "termState": 0, + "primaryCutOff": "2027-06-01", + "adjustmentCutOff": "2027-07-01", + "isSummer": 1, + }, ] Term.insert_many(terms).on_conflict_replace().execute() @@ -756,8 +843,218 @@ "status_id": "Approved" }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + "laborStatusFormID": 62, + "termCode_id": "202611", + "studentName": "Alex Carter", + "studentSupervisee_id": "B12345762", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Office Assistant", + "POSN_CODE": "S61413", + "weeklyHours": 10, + "startDate": "2026-08-15", + "endDate": "2026-12-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 62, + "formID_id": "62", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-08-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +LaborStatusForm.insert([{ + "laborStatusFormID": 63, + "termCode_id": "202611", + "studentName": "Morgan Hayes", + "studentSupervisee_id": "B12345763", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Computer Lab Assistant", + "POSN_CODE": "S61414", + "weeklyHours": 15, + "startDate": "2026-08-15", + "endDate": "2026-12-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 63, + "formID_id": "63", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-08-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + "laborStatusFormID": 64, + "termCode_id": "202611", + "studentName": "Jordan Brooks", + "studentSupervisee_id": "B12345764", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Help Desk Assistant", + "POSN_CODE": "S61415", + "weeklyHours": 20, + "startDate": "2026-08-15", + "endDate": "2026-12-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 64, + "formID_id": "64", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-08-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +LaborStatusForm.insert([{ + "laborStatusFormID": 65, + "termCode_id": "202611", + "studentName": "Taylor Morgan", + "studentSupervisee_id": "B12345765", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Secondary", + "WLS": 0, + "POSN_TITLE": "Reception Assistant", + "POSN_CODE": "S61416", + "weeklyHours": 5, + "startDate": "2026-08-15", + "endDate": "2026-12-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 65, + "formID_id": "65", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-08-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +LaborStatusForm.insert([{ + "laborStatusFormID": 66, + "termCode_id": "202611", + "studentName": "Casey Turner", + "studentSupervisee_id": "B12345766", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Secondary", + "WLS": 0, + "POSN_TITLE": "Library Assistant", + "POSN_CODE": "S61417", + "weeklyHours": 10, + "startDate": "2026-08-15", + "endDate": "2026-12-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 66, + "formID_id": "66", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-08-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +# Break Positions + +LaborStatusForm.insert([{ + "laborStatusFormID": 67, + "termCode_id": "202601", + "studentName": "Jamie Foster", + "studentSupervisee_id": "B12345767", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Thanksgiving Worker", + "POSN_CODE": "S61418", + "contractHours": 40, + "startDate": "2026-11-22", + "endDate": "2026-11-29" +}]).on_conflict_replace().execute() + +LaborStatusForm.insert([{ + "laborStatusFormID": 68, + "termCode_id": "202602", + "studentName": "Riley Cooper", + "studentSupervisee_id": "B12345768", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Christmas Worker", + "POSN_CODE": "S61419", + "contractHours": 120, + "startDate": "2026-12-20", + "endDate": "2027-01-03" +}]).on_conflict_replace().execute() + +LaborStatusForm.insert([{ + "laborStatusFormID": 69, + "termCode_id": "202603", + "studentName": "Drew Bennett", + "studentSupervisee_id": "B12345769", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Spring Break Worker", + "POSN_CODE": "S61420", + "contractHours": 80, + "startDate": "2027-03-07", + "endDate": "2027-03-14" +}]).on_conflict_replace().execute() + +LaborStatusForm.insert([{ + "laborStatusFormID": 70, + "termCode_id": "202604", + "studentName": "Logan Price", + "studentSupervisee_id": "B12345770", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Fall Break Worker", + "POSN_CODE": "S61421", + "contractHours": 24, + "startDate": "2026-10-11", + "endDate": "2026-10-18" +}]).on_conflict_replace().execute() + +LaborStatusForm.insert([{ + "laborStatusFormID": 71, + "termCode_id": "202613", + "studentName": "Avery Sullivan", + "studentSupervisee_id": "B12345771", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Summer Worker", + "POSN_CODE": "S61422", + "contractHours": 320, + "startDate": "2027-05-15", + "endDate": "2027-08-01" +}]).on_conflict_replace().execute() + ############################# # admin Notes ############################# @@ -927,6 +1224,21 @@ "secondary_10": 1, "breakHours": 900, }, + { + "termCode": 202600, + "department": 1, + "isFinal": False, + "approvedOn": None, + "approvedBy": None, + "justification": "Maintaining current staffing levels while allowing for moderate growth in student employment opportunities.", + "primary_10": 6, + "primary_12": 5, + "primary_15": 4, + "primary_20": 2, + "secondary_5": 6, + "secondary_10": 1, + "breakHours": 600, + }, ] Allocation.insert_many(allocations).on_conflict_replace().execute() From 64f4dc48373fb337d10ad4cae9d72c5627506f2b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 10:27:47 -0400 Subject: [PATCH 12/60] got the contracts to count in page --- app/controllers/main_routes/main_routes.py | 66 ++++++++++++---------- app/logic/allocationManager.py | 11 ++-- database/demo_data.py | 47 ++++++++++++++- 3 files changed, 87 insertions(+), 37 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 4a3001089..7116f999c 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -100,13 +100,17 @@ def allocationTable(org=None, account=None): departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) currentDate = str(date.today()) + if int(currentDate[5:7]) <= 6: + # If it is the spring semester, then the term code is 1 year behind. e.g. 2025-2026 term code is 202500. + springTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "12") - 100).get() + currentAY = currentTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "00") - 100).get() + fallTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "11") - 100).get() - if currentDate.month <= 6: - currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() - currentAY = currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "00").get() else: - currentTerm = Term.select().where(Term.termCode == currentDate[:4] + "11").get() + fallTerm = Term.select().where(Term.termCode == currentDate[:4] + "11").get() currentAY = Term.select().where(Term.termCode == currentDate[:4] + "00").get() + springTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() + allocationDict = {"primary_10": 1, "primary_12": 2, @@ -118,33 +122,35 @@ def allocationTable(org=None, account=None): "totalPrimaries": 10, "totalSecondaries": 11, "totalAllocations": 21} - # fallContracts = getContractedAllocations(currentTerm, dept) - fallContracts = { - "used_10": 4, - "used_12": 4, - "used_15": 4, - "used_20": 4, - "used_5_sec": 4, - "used_10_sec": 4, - "used_total": 0, - "break_hours": "3" - } - springContracts = { - "used_10": 4, - "used_12": 4, - "used_15": 4, - "used_20": 4, - "used_5_sec": 4, - "used_10_sec": 4, - "used_total": 0, - "break_hours": "3" - } + fallContracts = getContractedAllocations(fallTerm, dept) + # fallContracts = { + # "used_10": 4, + # "used_12": 4, + # "used_15": 4, + # "used_20": 4, + # "used_5_sec": 4, + # "used_10_sec": 4, + # "used_total": 0, + # "break_hours": "3" + # } + springContracts = getContractedAllocations(springTerm, dept) + + # springContracts = { + # "used_10": 4, + # "used_12": 4, + # "used_15": 4, + # "used_20": 4, + # "used_5_sec": 4, + # "used_10_sec": 4, + # "used_total": 0, + # "break_hours": "3" + # } breakContracts = { - "thanksgiving":getBreakContracts(202401, dept),#FIXME - "winter": getBreakContracts(202402, dept), - "spring": getBreakContracts(202403, dept), - "fall":getBreakContracts(202404, dept), - "summer": getBreakContracts(202413, dept) + "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) } return render_template('main/allocationTable.html', diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index a9935920e..32df313dc 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -7,9 +7,9 @@ def getAllocation(termCode, dept): - academicYearCode = int(str(termCode)[:5] + "00") + academicYearCode = int(str(termCode)[:4] + "00") allocationObject = Allocation.select().where( - Allocation.termCode.in_([termCode,academicYearCode]), + ((Allocation.termCode == termCode) | (Allocation.termCode == academicYearCode)), Allocation.department == dept, Allocation.isFinal == True).dicts().get() return allocationObject @@ -40,14 +40,14 @@ def getTotalAllocations(termCode, dept): return allocationDict def countContracts(jobType, weeklyContractHours, termCode, dept): - academicYearCode = int(str(termCode)[:5] + "00") + academicYearCode = int(str(termCode)[:4] + "999") lsfCountPrimaries = FormHistory.select( ).join(LaborStatusForm ).join(Department ).where( FormHistory.historyType == "Labor Status Form", FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), - LaborStatusForm.termCode.in_([termCode,academicYearCode]), + (LaborStatusForm.termCode == termCode) | (LaborStatusForm.termCode == academicYearCode), LaborStatusForm.jobType == jobType, LaborStatusForm.weeklyHours == weeklyContractHours, Department.departmentID == dept, @@ -96,7 +96,6 @@ def getContractedAllocations(termCode, dept): return usedPositions def getBreakContracts(termCode, dept): - academicYearCode = (str(termCode)[:4]) break_allocaiton = FormHistory.select(fn.SUM(LaborStatusForm.contractHours) ).join(LaborStatusForm ).where( @@ -104,7 +103,7 @@ def getBreakContracts(termCode, dept): FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), LaborStatusForm.termCode == termCode, LaborStatusForm.department == dept, - LaborStatusForm.weeklyHours == None).scalar() + LaborStatusForm.contractHours != None).scalar() # break_allocation = FormHistory.select( # LaborStatusForm.department, diff --git a/database/demo_data.py b/database/demo_data.py index 7ad8493fe..e64ac8c6e 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -1055,6 +1055,51 @@ "endDate": "2027-08-01" }]).on_conflict_replace().execute() +FormHistory.insert([{ + "formHistoryID": 67, + "formID_id": "67", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-11-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 68, + "formID_id": "68", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-12-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 69, + "formID_id": "69", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-02-20", + "status_id": "Approved" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 70, + "formID_id": "70", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2026-10-01", + "status_id": "Approved" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 71, + "formID_id": "71", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-04-15", + "status_id": "Approved" +}]).on_conflict_replace().execute() + ############################# # admin Notes ############################# @@ -1227,7 +1272,7 @@ { "termCode": 202600, "department": 1, - "isFinal": False, + "isFinal": True, "approvedOn": None, "approvedBy": None, "justification": "Maintaining current staffing levels while allowing for moderate growth in student employment opportunities.", From c3e9cc1e7f0d5ac359f40987670f3085cd50f7a6 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 11:06:07 -0400 Subject: [PATCH 13/60] Request allocation modification button --- app/static/css/allocationTable.css | 6 ++++-- app/templates/main/allocationTable.html | 13 ++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index a908d4f4a..2d95f1469 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -3,9 +3,7 @@ grid-template-columns: 1fr 1fr; } .btn-success{ - justify-self:end; align-self: center; - margin-left:8rem; width:fit-content; height:fit-content } @@ -29,4 +27,8 @@ } .table-striped tbody tr:nth-of-type(odd) { background-color: #f2f2f2; /* Your custom color */ +} +.btn-info{ + justify-self:end; + align-self: center; } \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 03aa702aa..14cb2ab22 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -15,10 +15,13 @@ {% block app_content %} -
-

View {{department.DEPT_NAME}} Allocations

- -
*Position allocations are placed (contracted/allocated) in the table
+
+

View {{department.DEPT_NAME}} Allocations

+
+ + Request Allocation Modifications +
+

@@ -131,7 +134,7 @@

-
- +
@@ -52,32 +52,69 @@

+ + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - -
Primaries
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Primaries{{fallContracts["used_primaries"]}}{{allocations["totalPrimaries"]}}
10 Hour{{fallContracts["used_10"]}}{{allocations["primary_10"]}}
12 Hour{{fallContracts["used_12"]}}{{allocations["primary_12"]}}
15 Hour{{fallContracts["used_15"]}}{{allocations["primary_15"]}}
Total Primaries{{fallContracts["used_total"]}}{{allocations["totalPrimaries"]}}
10 Hour{{fallContracts["used_10"]}}{{allocations["primary_10"]}}
12 Hour{{fallContracts["used_12"]}}{{allocations["primary_12"]}}
15 Hour{{fallContracts["used_15"]}}{{allocations["primary_15"]}}
20 Hour {{fallContracts["used_20"]}} {{allocations["primary_20"]}}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SecondariesContractedAllocated
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Secondaries{{fallContracts["used_secondaries"]}}{{allocations["totalSecondaries"]}}
5 Hour{{fallContracts["used_5_sec"]}}{{allocations["secondary_5"]}}
10 Hour{{fallContracts["used_10_sec"]}}{{allocations["secondary_10"]}}
@@ -92,7 +129,7 @@

- +
@@ -101,32 +138,69 @@

+ + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - +
Primaries
Total Contracts{{springContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Primaries{{springContracts["used_primaries"]}}{{allocations["totalPrimaries"]}}
10 Hour{{springContracts["used_10"]}}{{allocations["primary_10"]}}
12 Hour{{springContracts["used_12"]}}{{allocations["primary_12"]}}
15 Hour{{springContracts["used_15"]}}{{allocations["primary_15"]}}
Total Primaries{{springContracts["used_total"]}}{{allocations["totalPrimaries"]}}
10 Hour{{springContracts["used_10"]}}{{allocations["primary_10"]}}
12 Hour{{springContracts["used_12"]}}{{allocations["primary_12"]}}
15 Hour{{springContracts["used_15"]}}{{allocations["primary_15"]}}
20 Hour20 Hour {{springContracts["used_20"]}} {{allocations["primary_20"]}}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SecondariesContractedAllocated
Total Contracts{{springContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Secondaries{{springContracts["used_secondaries"]}}{{allocations["totalSecondaries"]}}
5 Hour{{springContracts["used_5_sec"]}}{{allocations["secondary_5"]}}
10 Hour{{springContracts["used_10_sec"]}}{{allocations["secondary_10"]}}
From f9670d35592560e68ff0be78cfc8e7a668346613 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 11:41:53 -0400 Subject: [PATCH 15/60] table now calls allocations --- app/controllers/main_routes/main_routes.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 8db35c343..d73b34cbb 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -111,17 +111,17 @@ def allocationTable(org=None, account=None): currentAY = Term.select().where(Term.termCode == currentDate[:4] + "00").get() springTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() - - allocationDict = {"primary_10": 1, - "primary_12": 2, - "primary_15": 3, - "primary_20": 4, - "secondary_5": 5, - "secondary_10": 6, - "breakHours": 500, - "totalPrimaries": 10, - "totalSecondaries": 11, - "totalAllocations": 21} + allocationDict = getTotalAllocations(currentAY, dept) + # allocationDict = {"primary_10": 1, + # "primary_12": 2, + # "primary_15": 3, + # "primary_20": 4, + # "secondary_5": 5, + # "secondary_10": 6, + # "breakHours": 500, + # "totalPrimaries": 10, + # "totalSecondaries": 11, + # "totalAllocations": 21} fallContracts = getContractedAllocations(fallTerm, dept) springContracts = getContractedAllocations(springTerm, dept) From 23e84d1ad6834482e13f8414b77c958633cf1e09 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 11:48:59 -0400 Subject: [PATCH 16/60] fixed table sizing --- app/static/css/allocationTable.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 2d95f1469..41b8c6189 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -25,8 +25,12 @@ padding-left: 5%; padding-right: 5%; } +.table-striped { + table-layout:fixed; + width:100%; +} .table-striped tbody tr:nth-of-type(odd) { - background-color: #f2f2f2; /* Your custom color */ + background-color: #f2f2f2; } .btn-info{ justify-self:end; From 54a3f132e69521bbaf612d56340d88a7135532da Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 14:25:12 -0400 Subject: [PATCH 17/60] added arrows to the accordions in th tables --- app/static/css/allocationTable.css | 10 ++++++++++ app/templates/main/allocationTable.html | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 41b8c6189..4455396c6 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -35,4 +35,14 @@ .btn-info{ justify-self:end; align-self: center; +} +.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); } \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index a0e8c13e0..23e832dc6 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -37,9 +37,10 @@

Current Term: {{currentAY.termName}}

@@ -121,11 +122,11 @@

-
@@ -209,9 +210,10 @@

From cc374dc2d0cbd17defb57c3042bffc3968c8fbb2 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 14:43:26 -0400 Subject: [PATCH 18/60] fixed formatting of html --- app/templates/main/allocationTable.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 23e832dc6..ad0424cc6 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -43,7 +43,7 @@

Current Term: {{currentAY.termName}}

-
+
@@ -129,7 +129,7 @@

Current Term: {{currentAY.termName}}

-
+
@@ -216,7 +216,7 @@

Current Term: {{currentAY.termName}}

-
+
From 827f3902b0bf82dfc9f80a42773c515f3f649d42 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 15:04:28 -0400 Subject: [PATCH 19/60] changed allocation req wording --- app/templates/main/allocationTable.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index ad0424cc6..693402791 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -19,7 +19,7 @@

View {{department.DEPT_NAME}} Allocations

- Request Allocation Modifications + Request Allocation
From 597877497cfc645109c56b80b157ae0aa6d2b7c7 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 15:20:04 -0400 Subject: [PATCH 20/60] fixed the contract index, the total returns correctly now --- app/controllers/main_routes/main_routes.py | 10 -- app/logic/allocationManager.py | 8 +- app/templates/main/allocationTable.html | 1 - database/demo_data.py | 105 +++++++++++++++++++++ 4 files changed, 109 insertions(+), 15 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index d73b34cbb..c3717d39d 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -112,16 +112,6 @@ def allocationTable(org=None, account=None): springTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() allocationDict = getTotalAllocations(currentAY, dept) - # allocationDict = {"primary_10": 1, - # "primary_12": 2, - # "primary_15": 3, - # "primary_20": 4, - # "secondary_5": 5, - # "secondary_10": 6, - # "breakHours": 500, - # "totalPrimaries": 10, - # "totalSecondaries": 11, - # "totalAllocations": 21} fallContracts = getContractedAllocations(fallTerm, dept) springContracts = getContractedAllocations(springTerm, dept) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 75dd303d6..d252ade50 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -40,7 +40,7 @@ def getTotalAllocations(termCode, dept): return allocationDict def countContracts(jobType, weeklyContractHours, termCode, dept): - academicYearCode = int(str(termCode)[:4] + "999") + academicYearCode = int(str(termCode)[:5] + "00") lsfCountPrimaries = FormHistory.select( ).join(LaborStatusForm ).join(Department @@ -94,9 +94,9 @@ def getContractedAllocations(termCode, dept): "used_total": 0, "break_hours": breakSum["total_hours"] } - usedPositions["used_primaries"] = sum(list(usedPositions.values())[:5]) - usedPositions["used_secondaries"] = sum(list(usedPositions.values())[5:7]) - usedPositions["used_total"] = sum(list(usedPositions.values())[:7]) + 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 def getBreakContracts(termCode, dept): diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 693402791..c42db5653 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -24,7 +24,6 @@

View {{department.DEPT_NAME}} Allocations

-

Current Term: {{currentAY.termName}}

diff --git a/database/demo_data.py b/database/demo_data.py index e64ac8c6e..a05ada155 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -972,6 +972,111 @@ "status_id": "Approved" }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + "laborStatusFormID": 72, + "termCode_id": "202612", + "studentName": "Alex Carter", + "studentSupervisee_id": "B12345762", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Office Assistant", + "POSN_CODE": "S61413", + "weeklyHours": 10, + "startDate": "2027-01-15", + "endDate": "2027-05-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 72, + "formID_id": "72", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-01-05", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +LaborStatusForm.insert([{ + "laborStatusFormID": 73, + "termCode_id": "202612", + "studentName": "Morgan Hayes", + "studentSupervisee_id": "B12345763", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Computer Lab Assistant", + "POSN_CODE": "S61414", + "weeklyHours": 15, + "startDate": "2027-01-15", + "endDate": "2027-05-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 73, + "formID_id": "73", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-01-05", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +LaborStatusForm.insert([{ + "laborStatusFormID": 74, + "termCode_id": "202612", + "studentName": "Taylor Morgan", + "studentSupervisee_id": "B12345765", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Secondary", + "WLS": 0, + "POSN_TITLE": "Reception Assistant", + "POSN_CODE": "S61416", + "weeklyHours": 5, + "startDate": "2027-01-15", + "endDate": "2027-05-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 74, + "formID_id": "74", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-01-05", + "status_id": "Approved" +}]).on_conflict_replace().execute() + + +# Student had a Fall-only position and receives a new Spring assignment. + +LaborStatusForm.insert([{ + "laborStatusFormID": 75, + "termCode_id": "202612", + "studentName": "Jordan Brooks", + "studentSupervisee_id": "B12345764", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Primary", + "WLS": 1, + "POSN_TITLE": "Technology Assistant", + "POSN_CODE": "S61423", + "weeklyHours": 12, + "startDate": "2027-01-15", + "endDate": "2027-05-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 75, + "formID_id": "75", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-01-05", + "status_id": "Approved" +}]).on_conflict_replace().execute() + # Break Positions From 32f8f6b1180768c68c9e3b195a9efe02ce024185 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 15:36:38 -0400 Subject: [PATCH 21/60] fixed the sum of break hours --- app/controllers/main_routes/main_routes.py | 2 ++ app/templates/main/allocationTable.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index c3717d39d..b228aa5ed 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -116,12 +116,14 @@ def allocationTable(org=None, account=None): 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, diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index c42db5653..6ac3669b7 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -227,7 +227,7 @@

Current Term: {{currentAY.termName}}

- + From 51103592be65dbebcb439a7a5175d0a11ead0e7b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 15:45:08 -0400 Subject: [PATCH 22/60] added the fall break row --- app/templates/main/allocationTable.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 6ac3669b7..2d06173cf 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -18,7 +18,7 @@

View {{department.DEPT_NAME}} Allocations

- + Download Allocation History Request Allocation
@@ -231,7 +231,12 @@

Current Term: {{currentAY.termName}}

- + + + + + + From 071232b77853b3cfe9d5e1768e30b8b9d78a23b8 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 16:09:10 -0400 Subject: [PATCH 23/60] moved the header to be centered --- app/static/css/allocationTable.css | 8 +++++--- app/templates/main/allocationTable.html | 5 ++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 4455396c6..2c935c341 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -4,8 +4,6 @@ } .btn-success{ align-self: center; - width:fit-content; - height:fit-content } .card-header { background-color: #efebeb; @@ -33,7 +31,7 @@ background-color: #f2f2f2; } .btn-info{ - justify-self:end; + justify-self:flex-end; align-self: center; } .accordion-arrow { @@ -45,4 +43,8 @@ } .btn:not(.collapsed) .accordion-arrow { transform: rotate(0deg); +} +.button-container { + display:flex; + justify-content:flex-end; } \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 2d06173cf..fbcd5182d 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -14,14 +14,13 @@ {% block app_content %} +

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

-
-

View {{department.DEPT_NAME}} Allocations

+
From fa4a35cfc44f6b8c046b6372c10814fbecfe8738 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Tue, 4 Aug 2026 16:39:39 -0400 Subject: [PATCH 24/60] fixed format of accordions --- app/static/css/allocationTable.css | 13 +++++++++++-- app/templates/main/allocationTable.html | 2 -- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 2c935c341..2fbe640fa 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -4,10 +4,12 @@ } .btn-success{ align-self: center; + justify-self: end; } .card-header { background-color: #efebeb; margin-bottom: 7px; + height: 6rem; } .mb-0, .collapsed { outline-color: none; @@ -45,6 +47,13 @@ transform: rotate(0deg); } .button-container { - display:flex; - justify-content:flex-end; + display:grid; + justify-content:end; +} +.btn-block{ + align-items: center; + align-self: center; + text-align: center; + justify-content: center; + height: 100% } \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index fbcd5182d..e82c4aa70 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -17,10 +17,8 @@

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

From 764db13f03ddc988fd054b928c43e4356002329b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 10:22:16 -0400 Subject: [PATCH 25/60] fixed the button layout --- app/static/css/allocationTable.css | 6 +++++- app/templates/main/allocationTable.html | 12 ++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 2fbe640fa..dd1812c1d 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -35,6 +35,7 @@ .btn-info{ justify-self:flex-end; align-self: center; + margin-left: 4px } .accordion-arrow { display: inline-block; @@ -47,7 +48,7 @@ transform: rotate(0deg); } .button-container { - display:grid; + display:flex; justify-content:end; } .btn-block{ @@ -56,4 +57,7 @@ text-align: center; justify-content: center; height: 100% +} +.termDisplay{ + margin-right:auto; } \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index e82c4aa70..0e8c8650e 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -16,16 +16,12 @@

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

-
- Download Allocation History - Request Allocation +
+

Current Term: {{currentAY.termName}}

+ Download Allocation History + Request Allocation
- -
-

Current Term: {{currentAY.termName}}

-
-
From b67164b23593f56b1598908ae6f85e66fa357ed8 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 11:51:24 -0400 Subject: [PATCH 26/60] Added tests for getBreakContracts --- tests/code/test_allocationManger.py | 78 ++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/tests/code/test_allocationManger.py b/tests/code/test_allocationManger.py index ea7da6782..3a235451b 100644 --- a/tests/code/test_allocationManger.py +++ b/tests/code/test_allocationManger.py @@ -48,6 +48,15 @@ def testTerm(): #destroy term.delete_instance() +@pytest.fixture +def testBreakTerm(): + #create + term = Term.create(termCode = 200601) + yield term + + #destroy + term.delete_instance() + @pytest.fixture def testAllocation(testDepartment,testTerm): #create @@ -142,6 +151,50 @@ def testLaborStatusForm(testStudent,testSupervisor,testDepartment,testTerm): #destroy laborStatusForm.delete_instance() +@pytest.fixture +def testBreakLaborStatusForm(testStudent,testSupervisor,testDepartment,testBreakTerm): + breakLaborStatusForm = LaborStatusForm.create( + studentName = "John Doe", + laborStatusFormID = 9898, + termCode = testBreakTerm.termCode, + studentSupervisee = testStudent.ID, + supervisor_id = testSupervisor.ID, + department = testDepartment.departmentID, + jobType = "Secondary", + WLS = 1, + POSN_TITLE = "Vacation Worker", + POSN_CODE = "S61412", + contractHours = 168, + weeklyHours = None, + startDate = "2006-04-01", + endDate = "2006-09-01", + supervisorNotes = None, + laborDepartmentNotes = None, + studentConfirmation = True, + confirmationToken = None, + studentExpirationDate = True, + studentResponseDate = True, + ) + + breakFormHistory = FormHistory.create( + formHistoryID = 9898, + formID_id = "9898", + historyType_id = "Labor Status Form", + releaseForm_id = None, + adjustedForm_id = None, + overloadForm_id = None, + createdBy_id = 1, + createdDate = "2006-02-01", + reviewedDate = "2006-03-01", + reviewedBy_id = 1, + status_id = "Approved", + rejectReason = None + ) + + yield breakLaborStatusForm, breakFormHistory + #destroy + breakLaborStatusForm.delete_instance() + @pytest.fixture def testFormHistory(testLaborStatusForm,testUser): formHistory = FormHistory.create( @@ -204,4 +257,27 @@ def test_getContractedAllocations(testLaborStatusForm, testTerm, testDepartment, assert contractedAllocation['used_secondaries'] == 0 assert contractedAllocation['used_total'] == 1 - assert contractedAllocation['break_hours'] == 500 \ No newline at end of file + assert contractedAllocation['break_hours'] == 500 + +@pytest.mark.integration +def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartment): + breakContractHours = getBreakContracts(testBreakTerm, testDepartment) + assert breakContractHours == 168 + + testBreakLaborStatusForm[0].contractHours = 800 + testBreakLaborStatusForm[0].save() + + breakContractHours = getBreakContracts(testBreakTerm, testDepartment) + assert breakContractHours == 800 + + testBreakLaborStatusForm[0].weeklyHours = 9999 + testBreakLaborStatusForm[0].save() + + breakContractHours = getBreakContracts(testBreakTerm, testDepartment) + assert breakContractHours == 800 + + testBreakLaborStatusForm[1].status = "denied by student" + testBreakLaborStatusForm[1].save() + + breakContractHours = getBreakContracts(testBreakTerm, testDepartment) + assert breakContractHours == None \ No newline at end of file From cdfbae51ba713ea6466bd1f34253543697800809 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 11:51:52 -0400 Subject: [PATCH 27/60] made getStudents() less brittle --- tests/code/test_tracy.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/code/test_tracy.py b/tests/code/test_tracy.py index 730547dd5..e26168638 100644 --- a/tests/code/test_tracy.py +++ b/tests/code/test_tracy.py @@ -18,8 +18,11 @@ def test_init(self, tracy): def test_getStudents(self, tracy): with app.app_context(): students = tracy.getStudents() - assert ['Elaheh','Guillermo','Jeremiah','Kat', 'Oluwagbayi', 'Test', 'Tyler'] == [s.FIRST_NAME for s in students] - assert ['718','300','420','420', '883', '700', '420'] == [s.STU_CPO for s in students] + for student in ['Elaheh','Guillermo','Jeremiah','Kat', 'Oluwagbayi', 'Test', 'Tyler']: + assert student in [s.FIRST_NAME for s in students] + for cpo in ['718','300','420','420', '883', '700', '420']: + assert cpo in [s.STU_CPO for s in students] + @pytest.mark.integration def test_getStudentFromBNumber(self, tracy): From 2736b90fa5d788ef7702b2bdb85261c4859e7588 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 11:59:22 -0400 Subject: [PATCH 28/60] added notes to getBreakContracts test --- tests/code/test_allocationManger.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/code/test_allocationManger.py b/tests/code/test_allocationManger.py index 3a235451b..ceef79950 100644 --- a/tests/code/test_allocationManger.py +++ b/tests/code/test_allocationManger.py @@ -261,21 +261,26 @@ def test_getContractedAllocations(testLaborStatusForm, testTerm, testDepartment, @pytest.mark.integration def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartment): + + # Test that the formHistory object exists breakContractHours = getBreakContracts(testBreakTerm, testDepartment) assert breakContractHours == 168 + # Test it with a higher amount of hours testBreakLaborStatusForm[0].contractHours = 800 testBreakLaborStatusForm[0].save() breakContractHours = getBreakContracts(testBreakTerm, testDepartment) assert breakContractHours == 800 + # Test that it works even if weeklyHours and contractHours are set testBreakLaborStatusForm[0].weeklyHours = 9999 testBreakLaborStatusForm[0].save() breakContractHours = getBreakContracts(testBreakTerm, testDepartment) assert breakContractHours == 800 + # Test that if the form is denied to not show up. testBreakLaborStatusForm[1].status = "denied by student" testBreakLaborStatusForm[1].save() From 22a1856ce2f2e16a706fca09d380cec5fca1373f Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 13:54:22 -0400 Subject: [PATCH 29/60] added a test for changing terms --- app/controllers/main_routes/main_routes.py | 1 - tests/code/test_allocationManger.py | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 3cbaf09ef..f7dfbc972 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -27,7 +27,6 @@ from app.logic.allocationManager import * - @main_bp.route('/logout', methods=['GET']) def triggerLogout(): return redirect(logout()) diff --git a/tests/code/test_allocationManger.py b/tests/code/test_allocationManger.py index ceef79950..735f15822 100644 --- a/tests/code/test_allocationManger.py +++ b/tests/code/test_allocationManger.py @@ -260,12 +260,12 @@ def test_getContractedAllocations(testLaborStatusForm, testTerm, testDepartment, assert contractedAllocation['break_hours'] == 500 @pytest.mark.integration -def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartment): +def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartment,testTerm): # Test that the formHistory object exists breakContractHours = getBreakContracts(testBreakTerm, testDepartment) assert breakContractHours == 168 - + # Test it with a higher amount of hours testBreakLaborStatusForm[0].contractHours = 800 testBreakLaborStatusForm[0].save() @@ -285,4 +285,14 @@ def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartme testBreakLaborStatusForm[1].save() breakContractHours = getBreakContracts(testBreakTerm, testDepartment) - assert breakContractHours == None \ No newline at end of file + assert breakContractHours == None + + # Test if the term changes to a non-break term + testBreakLaborStatusForm[0].termCode = testTerm + testBreakLaborStatusForm[0].save() + testBreakLaborStatusForm[1].status = "Approved" + testBreakLaborStatusForm[1].save() + + breakContractHours = getBreakContracts(testBreakTerm, testDepartment) + assert breakContractHours == None + \ No newline at end of file From 2005c87b74d0680c8c47e4e4d351dce8a8ca7753 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 5 Aug 2026 16:31:53 -0400 Subject: [PATCH 30/60] created date check in allocationManager --- app/logic/allocationManager.py | 26 ++++++++++++++++++++++++++ database/demo_data.py | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 0c1bcd5fb..fcf15a5ca 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -44,6 +44,31 @@ 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"] + 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 @@ -54,6 +79,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 diff --git a/database/demo_data.py b/database/demo_data.py index 011d506ff..d1e500bb4 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -1078,6 +1078,31 @@ "status_id": "Approved" }]).on_conflict_replace().execute() +LaborStatusForm.insert([{ + "laborStatusFormID": 76, + "termCode_id": "202600", + "studentName": "Jordan Brooks", + "studentSupervisee_id": "B12345764", + "supervisor_id": "B12361006", + "department_id": 1, + "jobType": "Secondary", + "WLS": 1, + "POSN_TITLE": "Technology Assistant", + "POSN_CODE": "S61423", + "weeklyHours": 10, + "startDate": "2027-01-15", + "endDate": "2027-05-15" +}]).on_conflict_replace().execute() + +FormHistory.insert([{ + "formHistoryID": 76, + "formID_id": "76", + "historyType_id": "Labor Status Form", + "createdBy_id": 1, + "createdDate": "2027-01-05", + "status_id": "Approved" +}]).on_conflict_replace().execute() + # Break Positions From b9f9cc48bfa226421c1a2f7be95fdc41639f460e Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 10:02:27 -0400 Subject: [PATCH 31/60] fixed comments for date logic --- app/logic/allocationManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index fcf15a5ca..dd8bddbc8 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -44,10 +44,9 @@ 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"] springMonths = ["01","02","03","04","05","06"] if str(termCode).endswith("11"): From 96ffe5fb316a6cd8f14404a56b52323116597d80 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 11:00:49 -0400 Subject: [PATCH 32/60] fixed current term logic --- app/controllers/main_routes/main_routes.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index f7dfbc972..b63c6bc4f 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -98,17 +98,19 @@ def allocationTable(org=None, account=None): else: departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) - currentDate = str(date.today()) - if int(currentDate[5:7]) <= 6: - # If it is the spring semester, then the term code is 1 year behind. e.g. 2025-2026 term code is 202500. - springTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "12") - 100).get() - currentAY = currentTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "00") - 100).get() - fallTerm = Term.select().where(Term.termCode == int(currentDate[:4] + "11") - 100).get() + + 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. + # 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[:4] + "11").get() - currentAY = Term.select().where(Term.termCode == currentDate[:4] + "00").get() - springTerm = Term.select().where(Term.termCode == currentDate[:4] + "12").get() + 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) fallContracts = getContractedAllocations(fallTerm, dept) From ea2910906cb9c1f3edaf03635aa31106dc6d8207 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 11:20:33 -0400 Subject: [PATCH 33/60] shortened js significantly. --- app/static/js/allocationTable.js | 62 +++++++++----------------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 2607e1eba..51a344a2c 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -1,48 +1,18 @@ $(document).ready( function(){ - fallTermPrimaries = $('#fallTermPrimaries'); - fallTermPrimaries.DataTable({ - pageLength: 25, - info: false, - lengthChange: false, - searching: false, - paging: false, - "order": [] - }); - fallTermSecondaries = $('#fallTermSecondaries'); - fallTermSecondaries.DataTable({ - pageLength: 25, - info: false, - lengthChange: false, - searching: false, - paging: false, - "order": [] - }); - - springTermPrimaries = $('#springTermPrimaries'); - springTermPrimaries.DataTable({ - pageLength: 25, - info: false, - lengthChange: false, - searching: false, - paging: false, - "order": [] - }); - springTermSecondaries = $('#springTermSecondaries'); - springTermSecondaries.DataTable({ - pageLength: 25, - info: false, - lengthChange: false, - searching: false, - paging: false, - "order": [] - }); - breakTable = $('#breakTable'); - breakTable.DataTable({ - pageLength: 25, - info: false, - lengthChange: false, - searching: false, - paging: false, - "order": [] - }); + 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'); }); \ No newline at end of file From 73af911abf42c8b0be2035a241550e423a5fdc3c Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 12:00:10 -0400 Subject: [PATCH 34/60] added a check if no break contracts are found --- app/controllers/main_routes/main_routes.py | 3 +-- app/logic/allocationManager.py | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index b63c6bc4f..84d3e4ea2 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -96,7 +96,7 @@ def allocationTable(org=None, account=None): if currentUser.isLaborAdmin: pass else: - departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) + departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) #FIXME currentDate = date.today() @@ -125,7 +125,6 @@ def allocationTable(org=None, account=None): "summer": getBreakContracts(currentAY.termCode + 13, dept) } breakContracts["total"] = sum(breakContracts.values()) - return render_template('main/allocationTable.html', department = dept, currentAY = currentAY, diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index dd8bddbc8..69ee9cb78 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -141,4 +141,7 @@ def getBreakContracts(termCode, dept): LaborStatusForm.termCode == termCode, LaborStatusForm.department == dept, LaborStatusForm.contractHours != None).scalar() - return break_allocation \ No newline at end of file + if break_allocation != None: + return break_allocation + else: + return 0 \ No newline at end of file From 76a167b8e3f928032b572cc21fba16890e7f5e81 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 13:35:58 -0400 Subject: [PATCH 35/60] checks if the user is in a department --- app/controllers/main_routes/main_routes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 84d3e4ea2..1b9fa9f44 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -93,10 +93,10 @@ def allocationTable(org=None, account=None): except (NameError, DoesNotExist): dept = None - if currentUser.isLaborAdmin: - pass - else: - departments = list(Department.select().join(SupervisorDepartment).where(SupervisorDepartment.supervisor == currentUser.supervisor).order_by(Department.isActive.desc(), Department.DEPT_NAME.asc())) #FIXME + 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() From f74fb7dd867a62ac8612d9e509f826e8b896b5db Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 6 Aug 2026 13:49:32 -0400 Subject: [PATCH 36/60] test_allocationManager accurately reflects changes to logic --- tests/code/test_allocationManger.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/code/test_allocationManger.py b/tests/code/test_allocationManger.py index 735f15822..eb3a149f6 100644 --- a/tests/code/test_allocationManger.py +++ b/tests/code/test_allocationManger.py @@ -137,8 +137,8 @@ def testLaborStatusForm(testStudent,testSupervisor,testDepartment,testTerm): POSN_CODE = "S61412", contractHours = 500, weeklyHours = 15, - startDate = "2025-04-01", - endDate = "2025-09-01", + startDate = "2006-08-01", + endDate = "2007-5-01", supervisorNotes = None, laborDepartmentNotes = None, studentConfirmation = True, @@ -285,7 +285,7 @@ def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartme testBreakLaborStatusForm[1].save() breakContractHours = getBreakContracts(testBreakTerm, testDepartment) - assert breakContractHours == None + assert breakContractHours == 0 # Test if the term changes to a non-break term testBreakLaborStatusForm[0].termCode = testTerm @@ -294,5 +294,5 @@ def test_getBreakContracts(testBreakLaborStatusForm, testBreakTerm, testDepartme testBreakLaborStatusForm[1].save() breakContractHours = getBreakContracts(testBreakTerm, testDepartment) - assert breakContractHours == None + assert breakContractHours == 0 \ No newline at end of file From e4b2bc0b72d4ee6bc11a19dd448a4c165464448b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 09:51:37 -0400 Subject: [PATCH 37/60] fixed test_allocationManager.py name --- .../code/{test_allocationManger.py => test_allocationManager.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/code/{test_allocationManger.py => test_allocationManager.py} (100%) diff --git a/tests/code/test_allocationManger.py b/tests/code/test_allocationManager.py similarity index 100% rename from tests/code/test_allocationManger.py rename to tests/code/test_allocationManager.py From 8c417f7b23dc22c42da83e3a45e686f207fe09aa Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 09:56:21 -0400 Subject: [PATCH 38/60] contractHours != None -> .is_null(False) --- app/logic/allocationManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 69ee9cb78..390d2b92e 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -140,7 +140,7 @@ def getBreakContracts(termCode, dept): FormHistory.status.in_(["Approved", "Pending", "Pre-Student Approval"]), LaborStatusForm.termCode == termCode, LaborStatusForm.department == dept, - LaborStatusForm.contractHours != None).scalar() + LaborStatusForm.contractHours.is_null(False)).scalar() if break_allocation != None: return break_allocation else: From 62998206ca8387bafa0c9578aed911b6583e6595 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 10:00:15 -0400 Subject: [PATCH 39/60] removed AddUserToDept route again --- app/controllers/main_routes/main_routes.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 1b9fa9f44..601bc58b2 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -134,22 +134,6 @@ def allocationTable(org=None, account=None): breakContracts = breakContracts) -@main_bp.route('/supervisorPortal/addUserToDept', methods=['GET', 'POST']) -def addUserToDept(): - 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(): ''' From 4b2ece2f364231911f2da219cd7ebb5394b8615f Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 10:12:46 -0400 Subject: [PATCH 40/60] fixed allocationManager import functions --- app/controllers/main_routes/main_routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 601bc58b2..0eb84425e 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -24,7 +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 * +from app.logic.allocationManager import getBreakContracts, getContractedAllocations, getTotalAllocations @main_bp.route('/logout', methods=['GET']) From 1e4d1d4d10cfdb49134d23aa05c26f29c87a9092 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 10:29:44 -0400 Subject: [PATCH 41/60] fixed termCode function calls --- app/controllers/main_routes/main_routes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 0eb84425e..97a427f89 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -112,9 +112,9 @@ def allocationTable(org=None, account=None): 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) - fallContracts = getContractedAllocations(fallTerm, dept) - springContracts = getContractedAllocations(springTerm, dept) + allocationDict = getTotalAllocations(currentAY.termCode, dept) + fallContracts = getContractedAllocations(fallTerm.termCode, dept) + springContracts = getContractedAllocations(springTerm.termCode, dept) breakContracts = { "total": 0, From 18f1abc7c20451924e0d2f64fc2124d7d15fc28a Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 10:34:16 -0400 Subject: [PATCH 42/60] added 404 error to no dept allocation view --- app/controllers/main_routes/main_routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 97a427f89..560d02fa7 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -91,8 +91,8 @@ def allocationTable(org=None, account=None): try: dept = Department.get(Department.ORG == org, Department.ACCOUNT == account) except (NameError, DoesNotExist): - dept = None - + return render_template('errors/404.html'), 404 + if not currentUser.isLaborAdmin: allowedDepartmentIds = [d.departmentID for d in getDepartmentsForSupervisor(currentUser)] if dept.departmentID not in allowedDepartmentIds: From 7b0cd5a2a143c2d823acd6603a92d6c8bd47c42d Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 7 Aug 2026 11:37:16 -0400 Subject: [PATCH 43/60] added more comments to date contContracts --- app/logic/allocationManager.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 390d2b92e..794d0cf6d 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -37,7 +37,7 @@ def getTotalAllocations(termCode: int, dept: int): "totalAllocations": (allocationObject["primary_10"] + allocationObject["primary_12"] + allocationObject["primary_15"] + allocationObject["primary_20"] + allocationObject["secondary_5"] + allocationObject["secondary_10"] )} return allocationDict -def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept: int): +def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept: int, AYtermCode: int = None): ''' This function counts the number of positions of a given type in a given department. For example, countContracts('secondary', 5, 202511, 1) returns the number of secondary @@ -52,21 +52,20 @@ def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept: if str(termCode).endswith("11"): dateCondition = ( (LaborStatusForm.endDate.month.in_(fallMonths)) | - (LaborStatusForm.startDate.month.in_(fallMonths) & + (LaborStatusForm.startDate.month.in_(fallMonths) & # Reused check for year-long positions 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 From 8ef23254fb7d0f862d4109b475c1597c8d2a88b8 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 19 Aug 2026 09:21:20 -0400 Subject: [PATCH 44/60] break table: spring -> spring break --- app/templates/main/allocationTable.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 0e8c8650e..24f2a90ec 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -239,7 +239,7 @@

Current Term: {{currentAY.termName}}

- + From a38dc4645dbfbc0b4b82c7f2aa61450a0d914ac4 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 19 Aug 2026 10:37:12 -0400 Subject: [PATCH 45/60] test_GestSTudents now works correctly, still brittle --- tests/code/test_tracy.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/code/test_tracy.py b/tests/code/test_tracy.py index e26168638..631c6eacd 100644 --- a/tests/code/test_tracy.py +++ b/tests/code/test_tracy.py @@ -18,10 +18,10 @@ def test_init(self, tracy): def test_getStudents(self, tracy): with app.app_context(): students = tracy.getStudents() - for student in ['Elaheh','Guillermo','Jeremiah','Kat', 'Oluwagbayi', 'Test', 'Tyler']: - assert student in [s.FIRST_NAME for s in students] - for cpo in ['718','300','420','420', '883', '700', '420']: - assert cpo in [s.STU_CPO for s in students] + for s in students: + print(s.STU_CPO) + assert ['Antonia','Barbara','Elaheh','Guillermo','Jeremiah','Kat', 'Oluwagbayi', 'Test', 'Tyler'] == [s.FIRST_NAME for s in students] + assert ['777','118','718','300','420','420', '883', '700', '420'] == [s.STU_CPO for s in students] @pytest.mark.integration From 9c7b727bc02c5ac1a8c7bd0384f222b85ed953d4 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Wed, 19 Aug 2026 11:15:00 -0400 Subject: [PATCH 46/60] switched the position of total in the tables. --- app/templates/main/allocationTable.html | 120 ++++++++++++------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 24f2a90ec..39ca61016 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -45,16 +45,6 @@

Current Term: {{currentAY.termName}}

- - - - - - - - - - @@ -75,6 +65,16 @@

Current Term: {{currentAY.termName}}

+ + + + + + + + + +
Total Break Hours{{breakContracts['total_hours']}}{{breakContracts['total']}} {{allocations["breakHours"]}}
{{allocations["breakHours"]}}
Thanksgiving / Fall BreakFall Break{{breakContracts['fall']}}
Thanksgiving {{breakContracts['thanksgiving']}}
SpringSpring Break {{breakContracts['spring']}}
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Primaries{{fallContracts["used_primaries"]}}{{allocations["totalPrimaries"]}}
10 Hour {{fallContracts["used_10"]}} {{fallContracts["used_20"]}} {{allocations["primary_20"]}}
Total Primaries{{fallContracts["used_primaries"]}}{{allocations["totalPrimaries"]}}
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
@@ -86,16 +86,6 @@

Current Term: {{currentAY.termName}}

- - - - - - - - - - @@ -106,6 +96,16 @@

Current Term: {{currentAY.termName}}

+ + + + + + + + + +
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
Total Secondaries{{fallContracts["used_secondaries"]}}{{allocations["totalSecondaries"]}}
5 Hour {{fallContracts["used_5_sec"]}} {{fallContracts["used_10_sec"]}} {{allocations["secondary_10"]}}
Total Secondaries{{fallContracts["used_secondaries"]}}{{allocations["totalSecondaries"]}}
Total Contracts{{fallContracts["used_total"]}}{{allocations["totalAllocations"]}}
@@ -131,16 +131,6 @@

Current Term: {{currentAY.termName}}

- - Total Contracts - {{springContracts["used_total"]}} - {{allocations["totalAllocations"]}} - - - Total Primaries - {{springContracts["used_primaries"]}} - {{allocations["totalPrimaries"]}} - 10 Hour {{springContracts["used_10"]}} @@ -161,6 +151,16 @@

Current Term: {{currentAY.termName}}

{{springContracts["used_20"]}} {{allocations["primary_20"]}} + + Total Primaries + {{springContracts["used_primaries"]}} + {{allocations["totalPrimaries"]}} + + + Total Contracts + {{springContracts["used_total"]}} + {{allocations["totalAllocations"]}} + @@ -218,36 +218,36 @@

Current Term: {{currentAY.termName}}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Total Break Hours{{breakContracts['total']}}{{allocations["breakHours"]}}
Fall Break{{breakContracts['fall']}}
Thanksgiving{{breakContracts['thanksgiving']}}
Winter Break{{breakContracts['winter']}}
Spring Break{{breakContracts['spring']}}
Summer Term{{breakContracts['summer']}}
Fall Break{{breakContracts['fall']}}
Thanksgiving{{breakContracts['thanksgiving']}}
Winter Break{{breakContracts['winter']}}
Spring Break{{breakContracts['spring']}}
Summer Term{{breakContracts['summer']}}
Total Break Hours{{breakContracts['total']}}{{allocations["breakHours"]}}
From 47f4f57f4d0ac7dbef2c7716863ac4ee2e48f925 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 20 Aug 2026 14:43:14 -0400 Subject: [PATCH 47/60] added case for no allocation being found --- app/logic/allocationManager.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/app/logic/allocationManager.py b/app/logic/allocationManager.py index 794d0cf6d..dbd35c18d 100644 --- a/app/logic/allocationManager.py +++ b/app/logic/allocationManager.py @@ -12,20 +12,24 @@ def getAllocation(termCode: int, dept: int, isFinal = True): This function returns a peewee object containing the selected allocation for given department and term. If you want the pending allocation, pass in False for isFinal. ''' - academicYearCode = int(str(termCode)[:4] + "00") - allocationObject = Allocation.select().where( - Allocation.termCode.in_([termCode,academicYearCode]), - Allocation.department == dept, - Allocation.isFinal == isFinal).dicts().get() - return allocationObject + try: + academicYearCode = int(str(termCode)[:4] + "00") + allocationObject = Allocation.select().where( + Allocation.termCode.in_([termCode,academicYearCode]), + Allocation.department == dept, + Allocation.isFinal == isFinal).dicts().get() + return allocationObject + except: + return 0 def getTotalAllocations(termCode: int, dept: int): ''' This function returns a dictionary representation of the given department's allocation for the given term. ''' - allocationObject = getAllocation(termCode, dept) - allocationDict = {"primary_10": allocationObject["primary_10"], + try: + allocationObject = getAllocation(termCode, dept) + allocationDict = {"primary_10": allocationObject["primary_10"], "primary_12": allocationObject["primary_12"], "primary_15": allocationObject["primary_15"], "primary_20": allocationObject["primary_20"], @@ -35,6 +39,17 @@ def getTotalAllocations(termCode: int, dept: int): "totalPrimaries": (allocationObject["primary_10"] + allocationObject["primary_12"] + allocationObject["primary_15"] + allocationObject["primary_20"]), "totalSecondaries": (allocationObject["secondary_5"] + allocationObject["secondary_10"]), "totalAllocations": (allocationObject["primary_10"] + allocationObject["primary_12"] + allocationObject["primary_15"] + allocationObject["primary_20"] + allocationObject["secondary_5"] + allocationObject["secondary_10"] )} + except: + allocationDict = {"primary_10": "", + "primary_12": "", + "primary_15": "", + "primary_20": "", + "secondary_5": "", + "secondary_10": "", + "breakHours": "No Allocations Found", + "totalPrimaries": "", + "totalSecondaries": "", + "totalAllocations": "No Allocations Found"} return allocationDict def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept: int, AYtermCode: int = None): From 26be0a487f125d4c579f6c54cbce3524a4f9441a Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 20 Aug 2026 14:51:24 -0400 Subject: [PATCH 48/60] fixed order of table elements --- app/templates/main/allocationTable.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 39ca61016..72e82bc2e 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -172,16 +172,6 @@

Current Term: {{currentAY.termName}}

- - Total Contracts - {{springContracts["used_total"]}} - {{allocations["totalAllocations"]}} - - - Total Secondaries - {{springContracts["used_secondaries"]}} - {{allocations["totalSecondaries"]}} - 5 Hour {{springContracts["used_5_sec"]}} @@ -192,6 +182,16 @@

Current Term: {{currentAY.termName}}

{{springContracts["used_10_sec"]}} {{allocations["secondary_10"]}} + + Total Secondaries + {{springContracts["used_secondaries"]}} + {{allocations["totalSecondaries"]}} + + + Total Contracts + {{springContracts["used_total"]}} + {{allocations["totalAllocations"]}} +

From b3ec72e55828b40b53b415d26ebf4bb99342e88b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 20 Aug 2026 14:51:54 -0400 Subject: [PATCH 49/60] removed print statements from tests --- tests/code/test_tracy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/code/test_tracy.py b/tests/code/test_tracy.py index 631c6eacd..f09eb5aee 100644 --- a/tests/code/test_tracy.py +++ b/tests/code/test_tracy.py @@ -19,7 +19,6 @@ def test_getStudents(self, tracy): with app.app_context(): students = tracy.getStudents() for s in students: - print(s.STU_CPO) assert ['Antonia','Barbara','Elaheh','Guillermo','Jeremiah','Kat', 'Oluwagbayi', 'Test', 'Tyler'] == [s.FIRST_NAME for s in students] assert ['777','118','718','300','420','420', '883', '700', '420'] == [s.STU_CPO for s in students] From d374990552a8daf35a11800d6bc109dfe3090ec9 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 09:27:19 -0400 Subject: [PATCH 50/60] fixed table resizing issue --- app/static/css/allocationTable.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index dd1812c1d..80e0d820a 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -17,10 +17,6 @@ font-size: 18px; font-weight: 525; } -.collapse{ - padding-left: 5% ; - padding-right: 5%; -} .accordion{ padding-left: 5%; padding-right: 5%; From 4cc64c912cd931dc16ae8656c1355a6996649300 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 09:51:21 -0400 Subject: [PATCH 51/60] added tooltips to the Total Contracts Table --- app/static/css/allocationTable.css | 6 ++++++ app/static/js/allocationTable.js | 6 +++++- app/templates/main/allocationTable.html | 8 ++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index 80e0d820a..fa43d0205 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -56,4 +56,10 @@ } .termDisplay{ margin-right:auto; +} +.bi-info-circle { + padding: 3px 3.5px 1.5px 3.5px; + font-size: 1.5rem; + vertical-align: middle; + color:#6e6e6e; } \ No newline at end of file diff --git a/app/static/js/allocationTable.js b/app/static/js/allocationTable.js index 51a344a2c..8bda5cd19 100644 --- a/app/static/js/allocationTable.js +++ b/app/static/js/allocationTable.js @@ -15,4 +15,8 @@ $(document).ready( function(){ const springTermPrimaries = initTable('#springTermPrimaries'); const springTermSecondaries = initTable('#springTermSecondaries'); const breakTable = initTable('#breakTable'); -}); \ No newline at end of file +}); + +$(function () { + $('[data-toggle="tooltip"]').tooltip() +}) \ No newline at end of file diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index 72e82bc2e..ddc182b42 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -71,7 +71,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalPrimaries"]}} - Total Contracts + Total Contracts {{fallContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -102,7 +102,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalSecondaries"]}} - Total Contracts + Total Contracts {{fallContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -157,7 +157,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalPrimaries"]}} - Total Contracts + Total Contracts {{springContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -188,7 +188,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalSecondaries"]}} - Total Contracts + Total Contracts {{springContracts["used_total"]}} {{allocations["totalAllocations"]}} From da3268030ff56dfcfdad70bc67e27bcbeda84ff1 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 10:15:21 -0400 Subject: [PATCH 52/60] centered the text for the accordions --- app/static/css/allocationTable.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/static/css/allocationTable.css b/app/static/css/allocationTable.css index fa43d0205..ec2485838 100644 --- a/app/static/css/allocationTable.css +++ b/app/static/css/allocationTable.css @@ -50,7 +50,7 @@ .btn-block{ align-items: center; align-self: center; - text-align: center; + text-align: left; justify-content: center; height: 100% } From 8d32fe207e919fdd3f680c2627682baed0c833b4 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 10:15:50 -0400 Subject: [PATCH 53/60] added a tooltip for the break allocations --- app/templates/main/allocationTable.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/templates/main/allocationTable.html b/app/templates/main/allocationTable.html index ddc182b42..e7ccafcb0 100644 --- a/app/templates/main/allocationTable.html +++ b/app/templates/main/allocationTable.html @@ -71,7 +71,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalPrimaries"]}} - Total Contracts + Total Contracts {{fallContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -102,7 +102,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalSecondaries"]}} - Total Contracts + Total Contracts {{fallContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -157,7 +157,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalPrimaries"]}} - Total Contracts + Total Contracts {{springContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -188,7 +188,7 @@

Current Term: {{currentAY.termName}}

{{allocations["totalSecondaries"]}} - Total Contracts + Total Contracts {{springContracts["used_total"]}} {{allocations["totalAllocations"]}} @@ -244,7 +244,7 @@

Current Term: {{currentAY.termName}}

- Total Break Hours + Total Break Hours {{breakContracts['total']}} {{allocations["breakHours"]}} From 187a5b660ac742eea5d26dc6ea40d13cb8bc4c77 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 10:37:37 -0400 Subject: [PATCH 54/60] added a logic file to get all Current Terms --- app/controllers/main_routes/main_routes.py | 17 +++------------ app/logic/getCurrentTerms.py | 24 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 app/logic/getCurrentTerms.py diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 560d02fa7..4205c6b3b 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -25,6 +25,7 @@ from app.logic.getSupervisors import getSupervisors from app.logic.getPositions import getActivePositions from app.logic.allocationManager import getBreakContracts, getContractedAllocations, getTotalAllocations +from app.logic.getCurrentTerms import getCurrentTerms @main_bp.route('/logout', methods=['GET']) @@ -98,20 +99,8 @@ def allocationTable(org=None, account=None): 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. - # 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() - + currentAY, fallTerm, springTerm = getCurrentTerms() + allocationDict = getTotalAllocations(currentAY.termCode, dept) fallContracts = getContractedAllocations(fallTerm.termCode, dept) springContracts = getContractedAllocations(springTerm.termCode, dept) diff --git a/app/logic/getCurrentTerms.py b/app/logic/getCurrentTerms.py new file mode 100644 index 000000000..6d26da809 --- /dev/null +++ b/app/logic/getCurrentTerms.py @@ -0,0 +1,24 @@ +from app.models.term import Term +from datetime import datetime, date + +def getCurrentTerms(): + ''' + Gets 3 primary terms for the current Academic Year (AY) + This means it attempt to get an AY, fall term, and spring term + This returns all three objects individually for each of the terms. + ''' + 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. + # 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() + return currentAY, fallTerm, springTerm + + 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() + return currentAY, fallTerm, springTerm + From 8747fdad811da8f0606f6ec273ddee38f2653375 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 11:16:26 -0400 Subject: [PATCH 55/60] removed unecessary import --- app/controllers/main_routes/main_routes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 4205c6b3b..4a0199ec9 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -1,7 +1,6 @@ from flask import render_template, request, json, redirect, url_for, send_file, g, flash, jsonify from peewee import JOIN, DoesNotExist, fn from functools import reduce -from datetime import datetime, date import operator from app.models.department import Department @@ -100,7 +99,7 @@ def allocationTable(org=None, account=None): return render_template('errors/403.html'), 403 currentAY, fallTerm, springTerm = getCurrentTerms() - + allocationDict = getTotalAllocations(currentAY.termCode, dept) fallContracts = getContractedAllocations(fallTerm.termCode, dept) springContracts = getContractedAllocations(springTerm.termCode, dept) From dd2516f51967734d18e2aa63fecdc404fd61969e Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Fri, 21 Aug 2026 11:16:57 -0400 Subject: [PATCH 56/60] began writing test getCurrentTerms.py --- tests/code/test_getCurrentTerms.py | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/code/test_getCurrentTerms.py diff --git a/tests/code/test_getCurrentTerms.py b/tests/code/test_getCurrentTerms.py new file mode 100644 index 000000000..1171981c8 --- /dev/null +++ b/tests/code/test_getCurrentTerms.py @@ -0,0 +1,55 @@ +import pytest +from app import app + +from app.models.term import Term +from app.logic.getCurrentTerms import getCurrentTerms +from datetime import datetime, date + +@pytest.fixture +def test_terms(): + + currentYear = date.today().year - 12 + print(currentYear) + + test_currentAY = Term.create( + termCode = f"{currentYear}00", + termName = f"AY {currentYear}-2001", + termStart = f"{currentYear}-08-01", + termEnd = f"{currentYear + 1}-05-01", + termState = 1, + primaryCutOff = f"{currentYear + 1}-09-01", + adjustmentCutOff = f"2002-10-01" + ) + test_fallTerm = Term.create( + termCode = f"{currentYear}11", + termName = f"Fall {currentYear}", + termStart = f"{currentYear}-08-01", + termEnd = f"{currentYear}-12-12", + termState = 1, + primaryCutOff = f"{currentYear}-09-01", + adjustmentCutOff = f"{currentYear}-10-01" + ) + test_springTerm = Term.create( + termCode = f"{currentYear}12", + termName = f"Spring {currentYear + 1}", + termStart = f"{currentYear + 1}-01-01", + termEnd = f"{currentYear + 1}-05-01", + termState = 1, + primaryCutOff = f"{currentYear + 1}-02-01", + adjustmentCutOff = f"{currentYear + 1}-3-01" + ) + yield test_currentAY, test_fallTerm, test_springTerm + + #destroy all created data + test_currentAY.delete_instance() + test_fallTerm.delete_instance() + test_springTerm.delete_instance() + +@pytest.mark.integration +def test_getCurrentTerms(test_terms): + currentAY, fallTerm, springTerm = getCurrentTerms() + assert currentAY != test_terms[0] + assert fallTerm != test_terms[1] + assert springTerm != test_terms[2] + + return 1 \ No newline at end of file From 784f429901dc2dc9293aea533ae50e0afc1dc4c1 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 24 Aug 2026 09:51:42 -0400 Subject: [PATCH 57/60] reworked getCurrentTerms to allow for all terms --- app/controllers/main_routes/main_routes.py | 2 +- app/logic/getCurrentTerms.py | 24 ------------ app/logic/getTerms.py | 39 +++++++++++++++++++ ...st_getCurrentTerms.py => test_getTerms.py} | 25 ++++++------ 4 files changed, 52 insertions(+), 38 deletions(-) delete mode 100644 app/logic/getCurrentTerms.py create mode 100644 app/logic/getTerms.py rename tests/code/{test_getCurrentTerms.py => test_getTerms.py} (70%) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 4a0199ec9..267b98561 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -24,7 +24,7 @@ from app.logic.getSupervisors import getSupervisors from app.logic.getPositions import getActivePositions from app.logic.allocationManager import getBreakContracts, getContractedAllocations, getTotalAllocations -from app.logic.getCurrentTerms import getCurrentTerms +from app.logic.getTerms import getCurrentTerms @main_bp.route('/logout', methods=['GET']) diff --git a/app/logic/getCurrentTerms.py b/app/logic/getCurrentTerms.py deleted file mode 100644 index 6d26da809..000000000 --- a/app/logic/getCurrentTerms.py +++ /dev/null @@ -1,24 +0,0 @@ -from app.models.term import Term -from datetime import datetime, date - -def getCurrentTerms(): - ''' - Gets 3 primary terms for the current Academic Year (AY) - This means it attempt to get an AY, fall term, and spring term - This returns all three objects individually for each of the terms. - ''' - 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. - # 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() - return currentAY, fallTerm, springTerm - - 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() - return currentAY, fallTerm, springTerm - diff --git a/app/logic/getTerms.py b/app/logic/getTerms.py new file mode 100644 index 000000000..9e4503a08 --- /dev/null +++ b/app/logic/getTerms.py @@ -0,0 +1,39 @@ +from app.models.term import Term +from datetime import datetime, date + +def getCurrentTerms(year: int = None, month: int = None): + ''' + Gets 3 primary terms for the current Academic Year (AY) + This means it attempt to get an AY, fall term, and spring term + This returns all three objects individually for each of the terms. + Leaving no input variables means that it will check for the current year instead of a given one. + ''' + if year and month: + if 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. + # 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 == year * 100 + 12 - 100).get() + currentAY = Term.select().where(Term.termCode == year * 100 - 100).get() + fallTerm = Term.select().where(Term.termCode == year * 100 + 11 - 100).get() + return currentAY, fallTerm, springTerm + else: + fallTerm = Term.select().where(Term.termCode == year * 100 + 11).get() + currentAY = Term.select().where(Term.termCode == year * 100).get() + springTerm = Term.select().where(Term.termCode == year * 100 + 12).get() + + return currentAY, fallTerm, springTerm + else: + # The check for the current year, not a given one + currentDate = date.today() + if month <= 6: + 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() + return currentAY, fallTerm, springTerm + + 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() + return currentAY, fallTerm, springTerm + diff --git a/tests/code/test_getCurrentTerms.py b/tests/code/test_getTerms.py similarity index 70% rename from tests/code/test_getCurrentTerms.py rename to tests/code/test_getTerms.py index 1171981c8..a268568fb 100644 --- a/tests/code/test_getCurrentTerms.py +++ b/tests/code/test_getTerms.py @@ -2,18 +2,18 @@ from app import app from app.models.term import Term -from app.logic.getCurrentTerms import getCurrentTerms +from app.logic.getTerms import getCurrentTerms from datetime import datetime, date @pytest.fixture def test_terms(): - currentYear = date.today().year - 12 + currentYear = date.today().year - 2000 print(currentYear) test_currentAY = Term.create( - termCode = f"{currentYear}00", - termName = f"AY {currentYear}-2001", + termCode = int(f"{currentYear}00"), + termName = f"AY {currentYear}-{currentYear - 1}", termStart = f"{currentYear}-08-01", termEnd = f"{currentYear + 1}-05-01", termState = 1, @@ -21,7 +21,7 @@ def test_terms(): adjustmentCutOff = f"2002-10-01" ) test_fallTerm = Term.create( - termCode = f"{currentYear}11", + termCode = int(f"{currentYear}11"), termName = f"Fall {currentYear}", termStart = f"{currentYear}-08-01", termEnd = f"{currentYear}-12-12", @@ -30,7 +30,7 @@ def test_terms(): adjustmentCutOff = f"{currentYear}-10-01" ) test_springTerm = Term.create( - termCode = f"{currentYear}12", + termCode = int(f"{currentYear}12"), termName = f"Spring {currentYear + 1}", termStart = f"{currentYear + 1}-01-01", termEnd = f"{currentYear + 1}-05-01", @@ -38,7 +38,7 @@ def test_terms(): primaryCutOff = f"{currentYear + 1}-02-01", adjustmentCutOff = f"{currentYear + 1}-3-01" ) - yield test_currentAY, test_fallTerm, test_springTerm + yield test_currentAY, test_fallTerm, test_springTerm, currentYear #destroy all created data test_currentAY.delete_instance() @@ -47,9 +47,8 @@ def test_terms(): @pytest.mark.integration def test_getCurrentTerms(test_terms): - currentAY, fallTerm, springTerm = getCurrentTerms() - assert currentAY != test_terms[0] - assert fallTerm != test_terms[1] - assert springTerm != test_terms[2] - - return 1 \ No newline at end of file + currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3], 8) + + assert currentAY == test_terms[0] + assert fallTerm == test_terms[1] + assert springTerm == test_terms[2] \ No newline at end of file From 11a152b6aac515b9e8c4f6785e7ce67d58c2654b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 24 Aug 2026 09:57:49 -0400 Subject: [PATCH 58/60] fixed logic month check for current year --- app/logic/getTerms.py | 2 +- tests/code/test_getTerms.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/logic/getTerms.py b/app/logic/getTerms.py index 9e4503a08..2d9acbe2e 100644 --- a/app/logic/getTerms.py +++ b/app/logic/getTerms.py @@ -25,7 +25,7 @@ def getCurrentTerms(year: int = None, month: int = None): else: # The check for the current year, not a given one currentDate = date.today() - if month <= 6: + if currentDate.month <= 6: 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() diff --git a/tests/code/test_getTerms.py b/tests/code/test_getTerms.py index a268568fb..6a6c979ec 100644 --- a/tests/code/test_getTerms.py +++ b/tests/code/test_getTerms.py @@ -7,6 +7,7 @@ @pytest.fixture def test_terms(): + # Make terms and get a set year, its far enough back that the test won't break other data. currentYear = date.today().year - 2000 print(currentYear) @@ -47,7 +48,7 @@ def test_terms(): @pytest.mark.integration def test_getCurrentTerms(test_terms): - currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3], 8) + currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3], 8) # Get terms for the year that is selected. assert currentAY == test_terms[0] assert fallTerm == test_terms[1] From fe8edc5eb43c06e3f9fbce318d9cf2b37745e96b Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 24 Aug 2026 10:19:59 -0400 Subject: [PATCH 59/60] fixed spring/fall check when given an AY --- app/logic/getTerms.py | 26 +++++++++++--------------- tests/code/test_getTerms.py | 9 +++++---- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/app/logic/getTerms.py b/app/logic/getTerms.py index 2d9acbe2e..ea3b60da6 100644 --- a/app/logic/getTerms.py +++ b/app/logic/getTerms.py @@ -1,29 +1,25 @@ from app.models.term import Term from datetime import datetime, date -def getCurrentTerms(year: int = None, month: int = None): +def getTerms(academicYear: str = None): ''' - Gets 3 primary terms for the current Academic Year (AY) + Gets 3 primary terms for the current/given Academic Year (AY) This means it attempt to get an AY, fall term, and spring term This returns all three objects individually for each of the terms. Leaving no input variables means that it will check for the current year instead of a given one. ''' - if year and month: - if 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. - # 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 == year * 100 + 12 - 100).get() - currentAY = Term.select().where(Term.termCode == year * 100 - 100).get() - fallTerm = Term.select().where(Term.termCode == year * 100 + 11 - 100).get() + if academicYear: + # Uses only the first half of the AY since term codes are split by year. + # i.e. Fall 2026 -> 202611, while Spring 2027 -> 202612. + springTerm = Term.select().where(Term.termCode == int(academicYear[:4]) * 100 + 12).get() + currentAY = Term.select().where(Term.termCode == int(academicYear[:4]) * 100).get() + fallTerm = Term.select().where(Term.termCode == int(academicYear[:4]) * 100 + 11).get() return currentAY, fallTerm, springTerm - else: - fallTerm = Term.select().where(Term.termCode == year * 100 + 11).get() - currentAY = Term.select().where(Term.termCode == year * 100).get() - springTerm = Term.select().where(Term.termCode == year * 100 + 12).get() - return currentAY, fallTerm, springTerm + else: - # The check for the current year, not a given one + # 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. + # The (year * 100) turns the year into an AY term code, 2025 -> 202500. The + 12/11 turns it into a fall or spring term. currentDate = date.today() if currentDate.month <= 6: springTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 12 - 100).get() diff --git a/tests/code/test_getTerms.py b/tests/code/test_getTerms.py index 6a6c979ec..5016a5c44 100644 --- a/tests/code/test_getTerms.py +++ b/tests/code/test_getTerms.py @@ -9,12 +9,13 @@ def test_terms(): # Make terms and get a set year, its far enough back that the test won't break other data. - currentYear = date.today().year - 2000 + currentYear = 2000 + AcademicYear = f"{currentYear}-{currentYear + 1}" print(currentYear) test_currentAY = Term.create( termCode = int(f"{currentYear}00"), - termName = f"AY {currentYear}-{currentYear - 1}", + termName = f"AY {currentYear}-{currentYear + 1}", termStart = f"{currentYear}-08-01", termEnd = f"{currentYear + 1}-05-01", termState = 1, @@ -39,7 +40,7 @@ def test_terms(): primaryCutOff = f"{currentYear + 1}-02-01", adjustmentCutOff = f"{currentYear + 1}-3-01" ) - yield test_currentAY, test_fallTerm, test_springTerm, currentYear + yield test_currentAY, test_fallTerm, test_springTerm, AcademicYear #destroy all created data test_currentAY.delete_instance() @@ -48,7 +49,7 @@ def test_terms(): @pytest.mark.integration def test_getCurrentTerms(test_terms): - currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3], 8) # Get terms for the year that is selected. + currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3]) # Get terms for the year that is selected. assert currentAY == test_terms[0] assert fallTerm == test_terms[1] From 4357e6256db0f9a1db95dab7ef0d4dcba9d8b202 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Mon, 24 Aug 2026 10:25:47 -0400 Subject: [PATCH 60/60] refactored function names: getCurrentTerms() -> getTerms() --- app/controllers/main_routes/main_routes.py | 4 ++-- tests/code/test_getTerms.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/main_routes/main_routes.py b/app/controllers/main_routes/main_routes.py index 267b98561..b651fe495 100755 --- a/app/controllers/main_routes/main_routes.py +++ b/app/controllers/main_routes/main_routes.py @@ -24,7 +24,7 @@ from app.logic.getSupervisors import getSupervisors from app.logic.getPositions import getActivePositions from app.logic.allocationManager import getBreakContracts, getContractedAllocations, getTotalAllocations -from app.logic.getTerms import getCurrentTerms +from app.logic.getTerms import getTerms @main_bp.route('/logout', methods=['GET']) @@ -98,7 +98,7 @@ def allocationTable(org=None, account=None): if dept.departmentID not in allowedDepartmentIds: return render_template('errors/403.html'), 403 - currentAY, fallTerm, springTerm = getCurrentTerms() + currentAY, fallTerm, springTerm = getTerms() allocationDict = getTotalAllocations(currentAY.termCode, dept) fallContracts = getContractedAllocations(fallTerm.termCode, dept) diff --git a/tests/code/test_getTerms.py b/tests/code/test_getTerms.py index 5016a5c44..eaca2be64 100644 --- a/tests/code/test_getTerms.py +++ b/tests/code/test_getTerms.py @@ -2,7 +2,7 @@ from app import app from app.models.term import Term -from app.logic.getTerms import getCurrentTerms +from app.logic.getTerms import getTerms from datetime import datetime, date @pytest.fixture @@ -49,7 +49,7 @@ def test_terms(): @pytest.mark.integration def test_getCurrentTerms(test_terms): - currentAY, fallTerm, springTerm = getCurrentTerms(test_terms[3]) # Get terms for the year that is selected. + currentAY, fallTerm, springTerm = getTerms(test_terms[3]) # Get terms for the year that is selected. assert currentAY == test_terms[0] assert fallTerm == test_terms[1]