From 0eb3bb1f511d94ba425217ea70a10960fd173243 Mon Sep 17 00:00:00 2001 From: fritzj2 Date: Thu, 30 Jul 2026 10:23:43 -0400 Subject: [PATCH 01/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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
Total Break Hours{{breakContracts['total_hours']}}{{breakContracts['total']}} {{allocations["breakHours"]}}
{{allocations["breakHours"]}}
Thanksgiving / Fall BreakFall Break{{breakContracts['fall']}}
Thanksgiving {{breakContracts['thanksgiving']}}