From 9d4acbfc556df1ff9eb45d879467e0fc630aef5b Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Thu, 2 Jul 2026 20:56:48 +0000 Subject: [PATCH 01/45] Started working on HTML design --- app/templates/admin/manageDepartments.html | 215 ++++++++++++--------- 1 file changed, 121 insertions(+), 94 deletions(-) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index ddb1b0431..95ed236e7 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -2,15 +2,17 @@ {% block styles %} {{super()}} - - + + {% endblock %} {% block scripts %} {{super()}} - - - + + + {% endblock %} {% block app_content %} @@ -19,118 +21,143 @@
-
- Click to Skip -
-
-

Manage Departments

+
+ Click to Skip +
+
+

Manage Departments

-

Position descriptions are up to date.

-

Position descriptions are not up to date

+

Monitor allocation usage, compliance, and department position needs across + campus.

-
-
-
+

+ Position descriptions are up to date.

+

Position descriptions are not up to date

+ +
-
- +
+
+
+ +
-
-
- - -
-
- - - - - - - - - {% for department in activeDepartments %} - - - - - {% endfor %} - -
DepartmentStatus
{{department.DEPT_NAME}}({{department.ORG}}, {{department.ACCOUNT}}) - -
-
- -
- - - - - - - - {% for department in inactiveDepartments %} - - - - {% endfor %} - -
Department
{{department.DEPT_NAME}}({{department.ORG}}, {{department.ACCOUNT}})
-
+
+ + +
+ +
+ + +
+
+
+ + + +
+
+
+ + +
+
+ + + + + + + + + {% for department in activeDepartments %} + + + + + {% endfor %} + +
DepartmentStatus
{{department.DEPT_NAME}}({{department.ORG}}, + {{department.ACCOUNT}}) + +
+
+ + + +
+ + + + + + + + {% for department in inactiveDepartments %} + + + + {% endfor %} + +
Department
{{department.DEPT_NAME}}({{department.ORG}}, + {{department.ACCOUNT}})
+
-
-
+
+
- -{% endblock %} +{% endblock %} \ No newline at end of file From 8deecb550f554f47fa1d5a2a8cda8fc9d2c76cb4 Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Sat, 4 Jul 2026 21:26:22 +0000 Subject: [PATCH 02/45] Finished initial design of the department page --- app/templates/admin/manageDepartments.html | 59 +++++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 95ed236e7..4b726e798 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -41,22 +41,19 @@

Manage Departments


-
-
-
- - -
+
-
- - -
-
+
+ +
+
+ + +
+
- - +
@@ -67,8 +64,9 @@

Manage Departments

  • Inactive Departments
  • + - +
    @@ -76,6 +74,10 @@

    Manage Departments

    + + + + @@ -92,8 +94,37 @@

    Manage Departments

    value="{{department.departmentID}}">{% if department.departmentCompliance == True %}In Compliance{% else %}Not in Compliance{% endif %} + + + + + {% endfor %} +
    Department StatusPositionsAllocation approval statusBreak Hours Used/GivenActions
    +

    Prim: 6 of 16

    +

    Sec: 12 of 16

    +
    + + +

    271 hrs / 500 hrs

    +
    +
    + + + +
    From 9a14e6df3fbf33416a8f20a7b13db18129296537 Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Mon, 6 Jul 2026 13:15:03 +0000 Subject: [PATCH 03/45] Fixed current year button position --- app/templates/admin/manageDepartments.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 4b726e798..9359ab032 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -64,7 +64,10 @@

    Manage Departments

  • Inactive Departments
  • - +
  • + +
  • +
    From 6a5fec70fce2775c3c866d2394d55d2010e1905d Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Mon, 6 Jul 2026 14:51:40 +0000 Subject: [PATCH 04/45] centered data in the table and div container --- app/static/css/manageDepartments.css | 6 + app/templates/admin/manageDepartments.html | 288 +++++++++++++-------- 2 files changed, 192 insertions(+), 102 deletions(-) diff --git a/app/static/css/manageDepartments.css b/app/static/css/manageDepartments.css index 81fcfb05a..df77648f9 100755 --- a/app/static/css/manageDepartments.css +++ b/app/static/css/manageDepartments.css @@ -34,4 +34,10 @@ h1 { #flasher{ z-index: 999999; +} + +#activeDepartmentsTable th, +#activeDepartmentsTable td { + vertical-align: middle; + text-align: center; } \ No newline at end of file diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 9359ab032..8626bf687 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -1,78 +1,108 @@ -{% extends "base.html" %} - -{% block styles %} -{{super()}} - - -{% endblock %} - -{% block scripts %} -{{super()}} +{% extends "base.html" %} {% block styles %} {{super()}} + + +{% endblock %} {% block scripts %} {{super()}} - - -{% endblock %} - -{% block app_content %} + + +{% endblock %} {% block app_content %}
    - Click to Skip -
    -
    + Click to Skip +
    +

    Manage Departments

    -

    Monitor allocation usage, compliance, and department position needs across - campus.

    +

    + Monitor allocation usage, compliance, and department position needs + across campus. +

    -

    - Position descriptions are up to date.

    -

    Position descriptions are not up to date

    +

    + + Position descriptions are up to date. +

    +

    + + Position descriptions are not up to date +


    -
    +

    -
    - -
    - - -
    -
    - - +
    +
    + + +
    +
    + + +
    -
    -
    +
    -
    - -{% endblock %} \ No newline at end of file +{% endblock %} From 7341b74d6582741d6235f8fca09c824c2acc9893 Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Tue, 7 Jul 2026 15:19:40 +0000 Subject: [PATCH 05/45] Fixed actions button: made it similar to the other dropdown menus --- app/templates/admin/manageDepartments.html | 33 ++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 8626bf687..bf4d0ffd6 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -155,27 +155,18 @@

    Manage Departments

    271 hrs / 500 hrs

    -
    - - - +
    From 25b6251363e1f5940b7087b718778d28bcfb269c Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Tue, 7 Jul 2026 15:29:07 +0000 Subject: [PATCH 06/45] Finished requested UI changes: renaming some elements --- app/templates/admin/manageDepartments.html | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index bf4d0ffd6..b7614f0ba 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -70,7 +70,7 @@

    Manage Departments

    -
    @@ -108,7 +103,7 @@

    Manage Departments

    Department Status Positions - Allocation approval status + Allocation Approval Status AY 26-27 Break Hours Used/Given Actions From c6c7293d728d3c2a037720c3f392efb292800d11 Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Tue, 7 Jul 2026 20:56:49 +0000 Subject: [PATCH 07/45] Added brake hours from the database to the UI --- .../admin_routes/manage_departments.py | 10 +++++++++- app/templates/admin/manageDepartments.html | 16 +++++++++++++--- database/demo_data.py | 15 ++++++++------- database/reset_database.sh | 10 +++++----- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/app/controllers/admin_routes/manage_departments.py b/app/controllers/admin_routes/manage_departments.py index 6b16877cb..44ef9d938 100644 --- a/app/controllers/admin_routes/manage_departments.py +++ b/app/controllers/admin_routes/manage_departments.py @@ -9,11 +9,13 @@ from app.models.term import * from flask_bootstrap import bootstrap_find_resource from app.models.department import * +from app.models.allocation import * from flask import request, redirect from flask import jsonify from playhouse.shortcuts import model_to_dict from app.logic.tracy import Tracy + @admin.route('/admin/manageDepartments', methods=['GET']) # @login_required def manage_departments(): @@ -34,17 +36,23 @@ def manage_departments(): activeDepartments = Department.select().where(Department.isActive == True) inactiveDepartments = Department.select().where(Department.isActive == False) + allAllocations = Allocation.select() + print("Something",allAllocations, "\n\n\n\n\n","Something") + allSupervisors= Supervisor.select().order_by(Supervisor.LAST_NAME) return render_template( 'admin/manageDepartments.html', title = ("Manage Departments"), activeDepartments = activeDepartments, inactiveDepartments = inactiveDepartments, - allSupervisors = allSupervisors + allSupervisors = allSupervisors, + allAllocations = allAllocations ) except Exception as e: print("Error Loading all Departments", e) return render_template('errors/500.html'), 500 + + @admin.route("/admin/manageDepartments/", methods=['GET']) def getSupervisorsInDepartment(departmentID): currentUser = require_login() diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index b7614f0ba..86d42a6ac 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -110,6 +110,7 @@

    Manage Departments

    {% for department in activeDepartments %} + Manage Departments Approved - -

    271 hrs / 500 hrs

    - + + + + {% for allocation in allAllocations %} + {% if allocation.department == department %} + {{ allocation.breakHours }} + {% endif %} + {% endfor %} + + + diff --git a/database/demo_data.py b/database/demo_data.py index ade1c6379..8ef27c266 100644 --- a/database/demo_data.py +++ b/database/demo_data.py @@ -17,15 +17,12 @@ from app.models.laborStatusForm import LaborStatusForm from app.models.formHistory import FormHistory from app.models.notes import Notes -<<<<<<< HEAD from app.models.supervisorDepartment import SupervisorDepartment -======= from app.models.allocation import Allocation from app.models.positionHistory import PositionHistory from app.models.supervisorDepartment import SupervisorDepartment from app.models.allocation import Allocation ->>>>>>> PeeWeeAttribute print("Inserting data for demo and testing purposes") @@ -472,28 +469,32 @@ "DEPT_NAME": "Computer Science", "ACCOUNT": "6740", "ORG": "2114", - "departmentCompliance": 1 + "departmentCompliance": 1, + "isActive": 1 }, { "departmentID":2, "DEPT_NAME": "Technology and Applied Design", "ACCOUNT": "6740", "ORG": "2147", - "departmentCompliance": 1 + "departmentCompliance": 1, + "isActive": 1 }, { "departmentID":3, "DEPT_NAME": "Mathematics", "ACCOUNT": "6740", "ORG": "2150", - "departmentCompliance": 1 + "departmentCompliance": 1, + "isActive": 1 }, { "departmentID":4, "DEPT_NAME": "Biology", "ACCOUNT": "6740", "ORG": "2107", - "departmentCompliance": 1 + "departmentCompliance": 1, + "isActive": 1 }, { "departmentID":5, diff --git a/database/reset_database.sh b/database/reset_database.sh index 82f6cff53..33283062d 100755 --- a/database/reset_database.sh +++ b/database/reset_database.sh @@ -22,12 +22,12 @@ if [ "$1" == "from-backup" ]; then fi echo "Dropping databases" -mysql -u root -proot --execute="DROP DATABASE \`lsf\`; DROP USER 'lsf_user';" -mysql -u root -proot --execute="DROP DATABASE \`UTE\`; DROP USER 'tracy_user';" +mysql -u root -proot --skip-ssl --execute="DROP DATABASE \`lsf\`; DROP USER 'lsf_user';" +mysql -u root -proot --skip-ssl --execute="DROP DATABASE \`UTE\`; DROP USER 'tracy_user';" echo "Recreating databases and users" -mysql -u root -proot --execute="CREATE DATABASE IF NOT EXISTS \`lsf\`; CREATE USER IF NOT EXISTS 'lsf_user'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'lsf_user'@'%';" -mysql -u root -proot --execute="CREATE DATABASE IF NOT EXISTS \`UTE\`; CREATE USER IF NOT EXISTS 'tracy_user'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'tracy_user'@'%';" +mysql -u root -proot --skip-ssl --execute="CREATE DATABASE IF NOT EXISTS \`lsf\`; CREATE USER IF NOT EXISTS 'lsf_user'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'lsf_user'@'%';" +mysql -u root -proot --skip-ssl --execute="CREATE DATABASE IF NOT EXISTS \`UTE\`; CREATE USER IF NOT EXISTS 'tracy_user'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'tracy_user'@'%';" cd database @@ -38,7 +38,7 @@ rm -rf migrations.json echo "Creating database objects" if [ $BACKUP -eq 1 ]; then echo " from backup" - mysql -u root -proot lsf < prod-backup.sql + mysql -u root -proot --skip-ssl lsf < prod-backup.sql else echo " empty" ./migrate_db.sh From 636dd71ddf6a39584c9dc93e237cc99d244622ce Mon Sep 17 00:00:00 2001 From: zhytkovd Date: Wed, 8 Jul 2026 18:08:21 +0000 Subject: [PATCH 08/45] Fixed brake hours given: removed double loop and filtered by AY --- .../admin_routes/manage_departments.py | 26 ++++++++++++++++--- app/templates/admin/manageDepartments.html | 8 ++---- database/demo_data.py | 5 +++- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin_routes/manage_departments.py b/app/controllers/admin_routes/manage_departments.py index 44ef9d938..1031b8fc0 100644 --- a/app/controllers/admin_routes/manage_departments.py +++ b/app/controllers/admin_routes/manage_departments.py @@ -10,6 +10,7 @@ from flask_bootstrap import bootstrap_find_resource from app.models.department import * from app.models.allocation import * +from app.models.laborStatusForm import * #Do we need to import all? from flask import request, redirect from flask import jsonify from playhouse.shortcuts import model_to_dict @@ -33,11 +34,28 @@ def manage_departments(): elif currentUser.supervisor: return render_template('errors/403.html'), 403 + #FIXME: hardcoded term year for the testing purposes + currentTerm = "202500" - activeDepartments = Department.select().where(Department.isActive == True) + print("Current term: ", currentTerm) + + + # activeDepartments = Department.select().where(Department.isActive == True) + # allAllocations = Allocation.select().where(Allocation.termCode == currentTerm) inactiveDepartments = Department.select().where(Department.isActive == False) - allAllocations = Allocation.select() - print("Something",allAllocations, "\n\n\n\n\n","Something") + + + activeDepartments = ( + Department + .select(Department, Allocation) + .join(Allocation) + .where( + Department.isActive == True, + Allocation.termCode == currentTerm + ) + + +) allSupervisors= Supervisor.select().order_by(Supervisor.LAST_NAME) return render_template( 'admin/manageDepartments.html', @@ -45,7 +63,7 @@ def manage_departments(): activeDepartments = activeDepartments, inactiveDepartments = inactiveDepartments, allSupervisors = allSupervisors, - allAllocations = allAllocations + currentTerm = currentTerm ) except Exception as e: print("Error Loading all Departments", e) diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 86d42a6ac..1b7ec91c1 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -69,7 +69,7 @@

    Manage Departments

    - + @@ -156,7 +159,7 @@

    Manage Departments

    + +
    + + + + + + + + {% for department in inactiveDepartments %} + + + + {% endfor %} + +
    Department
    + {{department.DEPT_NAME}}({{department.ORG}}, + {{department.ACCOUNT}}) +
    -
    +
    +
    - -
    +
    +
    @@ -154,7 +154,7 @@

    Manage Departments

    {{ breakHoursByDepartment.get(department.departmentID, 0) }} / {{ department.allocation.breakHours }} @@ -181,31 +181,31 @@

    Manage Departments

    {% endfor %} - + -
    +
    - - - - - - - {% for department in inactiveDepartments %} - - + + + + + + {% for department in inactiveDepartments %} + + - - {% endfor %} - -
    Department
    +
    Department
    {{department.DEPT_NAME}}({{department.ORG}}, {{department.ACCOUNT}}) -
    + + + {% endfor %} + + +
    - -
    +
    From d77c410cb6c761de7008e21f60257bde64c5a3c6 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Tue, 21 Jul 2026 11:55:39 -0400 Subject: [PATCH 38/45] Improved termManagement.py to all for creating terms via a list based on the selected academic year. Implemented this into manage_departments for all relevent term types. This will ensure that, if a term isn't created already, that it will still exist so that future allocations can be implemented. Added comments for future groups working on this issue and implemented these dates into the HTML. --- .../admin_routes/manage_departments.py | 77 +++++++++++-------- .../admin_routes/termManagement.py | 34 +++++--- app/templates/admin/manageDepartments.html | 23 ++++-- 3 files changed, 86 insertions(+), 48 deletions(-) diff --git a/app/controllers/admin_routes/manage_departments.py b/app/controllers/admin_routes/manage_departments.py index 94fb374cf..0f2dd2993 100644 --- a/app/controllers/admin_routes/manage_departments.py +++ b/app/controllers/admin_routes/manage_departments.py @@ -19,11 +19,11 @@ from datetime import date from flask import g from app.logic.manageDepartments import * # Reorganize imports to avoid circular import issues. This is a temporary fix, but it works for now. - +from app.controllers.admin_routes.termManagement import createTerms @admin.route('/admin/manageDepartments/', methods=['GET']) -@admin.route('/admin/manageDepartments/', methods=['GET']) +@admin.route('/admin/manageDepartments/', methods=['GET']) # FIXME: The default value year should be the current academic year (Rather than waiting to be clicked it should be on the current year by default). # @login_required -def manage_departments(academic_year = None): # FIXME +def manage_departments(academic_year = None): """ Updates the Labor Status Forms database with any new departments in the Tracy database on page load. Returns the departments to be used in the HTML for the manage departments page. @@ -42,54 +42,63 @@ def manage_departments(academic_year = None): # FIXME # Sets academic_year to the current open term if no academic year is provided in the URL. Current solution. WILL change in the future. if not academic_year: academic_year = g.openTerm.termCode - - fall_suffix = 11 # Ex.) Fall 2025 = 202511 - spring_suffix = 12 # Ex.) Spring 2026 = 202512 - summer_suffix = 13 # Ex.) Summer 2026 = 202513 - - currentTerm = Term.get(Term.termCode == academic_year) - previousTerm = Term.get(Term.termCode == academic_year - 100) - nextTerm = Term.get(Term.termCode == academic_year + 100) - - - - # Works. Just use production data to test. Add demo data for this later. (This was a request from Labor Office to have the ability to view based on term.) - # fallTerm = Term.get(Term.termCode == academic_year + fall_suffix) - # springTerm = Term.get(Term.termCode == academic_year + spring_suffix) - # summerTerm = Term.get(Term.termCode == academic_year + summer_suffix) - - # print("******************",fallTerm.termName, springTerm.termName, summerTerm.termName, "**********************") - # print("******************",previousTerm.termName, nextTerm.termName, currentTerm.termName, "**********************") + else: + academic_year = int(academic_year) - # totalBreakSum = getUsedBreakHours(currentTerm) + currentAY = Term.get(Term.termCode == academic_year) + print("Current Term:", currentAY.termName) - # print("Something\n\n") + previousAcademicYear = (academic_year - 100) // 100 + createPreviousAY = createTerms(previousAcademicYear) + previousAY = createPreviousAY[0] + print("Previous Term:", previousAY.termName) + nextAcademicYear = (academic_year + 100) // 100 + createNextAY = createTerms(nextAcademicYear) + nextAY = createNextAY[0] + print("Next Term:", nextAY.termName) + # Works. Should work without production data now. + # We've also thought about having a drop down menu to select the term once the academic year is selected. This should also include the ability to view the entire academic year. + # Given the new implementation of the term management page, we can now use the term management page to create terms for the academic year and then use this page to view the departments for that academic year. This will be a much more efficient way to manage the terms and departments. + # A concept of Currently Selected Term does not exist, yet. Implementing it here will make it so that the user can select a term and then view the departments for that term. This will be a much more efficient way to manage the terms and departments. + plainAcademicYear = academic_year // 100 # Might be a good idea to create a function for // 100 since it appears in multiple places. This will make it easier to change the implementation in the future if needed. + createdTerms = createTerms(plainAcademicYear) #FIXME: Use the selected academic year to create the terms for that year. This will be a much more efficient way to manage the terms and departments. + fallTerm = createdTerms[1] + springTerm = createdTerms[4] + summerTerm = createdTerms[6] + + print("******************",fallTerm.termName, springTerm.termName, summerTerm.termName, "**********************") + print("******************",previousAY.termName, nextAY.termName, currentAY.termName, "**********************") + + # For Testing Purposes. This will be removed once the term management page is fully implemented and the terms are created for the academic year. + # totalBreakSum = getUsedBreakHours(currentAY) # for row in totalBreakSum: # print(row['department'],int(row['totalHours']),row['termCode']) # print(totalBreakSum) - breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(currentTerm)} # I think Scott wanted this to say NULL not zero, unsure. + breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(currentAY)} # I think Scott wanted this to say NULL not zero, unsure. # print(breakHoursByDepartment) # print("\n\nSomething") + # This was left just incase anything went wrong. Delete this if everything works as expected. Not nessicary in current implementation. # activeDepartments = Department.select().where(Department.isActive == True) - # allAllocations = Allocation.select().where(Allocation.termCode == currentTerm) + # allAllocations = Allocation.select().where(Allocation.termCode == currentAY) + inactiveDepartments = Department.select().where(Department.isActive == False) - activeDepartments = getActiveDepartmentsWithAllocation(currentTerm) + activeDepartments = getActiveDepartmentsWithAllocation(currentAY) - # Move some of this to Logic (maybe). + # Move some of this to Logic. for dept in activeDepartments: dept.totalPrimaries = (dept.allocation.primary_10 + dept.allocation.primary_12 + dept.allocation.primary_15 + dept.allocation.primary_20) dept.totalSecondaries = (dept.allocation.secondary_5 + dept.allocation.secondary_10) - lsfCountPrimaries = getLSFCountPrimaries(currentTerm, dept) - lsfCountSecondaries = getLSFCountSecondaries(currentTerm, dept) + lsfCountPrimaries = getLSFCountPrimaries(currentAY, dept) + lsfCountSecondaries = getLSFCountSecondaries(currentAY, dept) dept.lsfCountPrimaries = lsfCountPrimaries dept.lsfCountSecondaries = lsfCountSecondaries # print("######################") @@ -98,7 +107,7 @@ def manage_departments(academic_year = None): # FIXME # print([lsf.formID for lsf in lsfCountSecondaries]) allocationStatus = { - department.departmentID: getAllocationStatus(currentTerm, department) + department.departmentID: getAllocationStatus(currentAY, department) for department in activeDepartments } @@ -114,10 +123,10 @@ def manage_departments(academic_year = None): # FIXME activeDepartments = activeDepartments, inactiveDepartments = inactiveDepartments, allSupervisors = allSupervisors, - currentTerm = currentTerm.termName, - previousTerm = previousTerm.termName, - nextTerm = nextTerm.termName, - academicYear = currentTerm.termName, + currentAY = currentAY.termName, + previousAY = previousAY.termName, + nextAY = nextAY.termName, + academicYear = currentAY.termName, # totalBreakSum = totalBreakSum breakHoursByDepartment = breakHoursByDepartment, allocationStatus = allocationStatus diff --git a/app/controllers/admin_routes/termManagement.py b/app/controllers/admin_routes/termManagement.py index 8a17d169f..30e7673f1 100644 --- a/app/controllers/admin_routes/termManagement.py +++ b/app/controllers/admin_routes/termManagement.py @@ -37,26 +37,42 @@ def createTerms(termYear): This function creates the terms for the given Academic Year """ code = termYear * 100 + createdTerms = [] for i in range(8): try: if i == 0: - Term.create(termCode = code, termName = "AY {}-{}".format(termYear, termYear + 1), isAcademicYear=True) + term = Term.create(termCode = code, termName = "AY {}-{}".format(termYear, termYear + 1), isAcademicYear=True) elif i == 1: - Term.create(termCode = (code + 11), termName = "Fall {}".format(termYear)) + term = Term.create(termCode = (code + 11), termName = "Fall {}".format(termYear)) elif i == 7: - Term.create(termCode = (code + 4), termName = "Fall Break {}".format(termYear), isBreak=True) + term = Term.create(termCode = (code + 4), termName = "Fall Break {}".format(termYear), isBreak=True) elif i == 2: - Term.create(termCode = (code + 1), termName = "Thanksgiving Break {}".format(termYear), isBreak=True) + term = Term.create(termCode = (code + 1), termName = "Thanksgiving Break {}".format(termYear), isBreak=True) elif i == 3: - Term.create(termCode = (code + 2), termName = "Christmas Break {}".format( termYear), isBreak=True) + term = Term.create(termCode = (code + 2), termName = "Christmas Break {}".format( termYear), isBreak=True) elif i == 4: - Term.create(termCode = (code + 12), termName = "Spring {}".format(termYear + 1)) + term = Term.create(termCode = (code + 12), termName = "Spring {}".format(termYear + 1)) elif i == 5: - Term.create(termCode = (code + 3), termName = "Spring Break {}".format(termYear + 1), isBreak=True) + term = Term.create(termCode = (code + 3), termName = "Spring Break {}".format(termYear + 1), isBreak=True) elif i == 6: - Term.create(termCode = (code + 13), termName = "Summer {}".format(termYear + 1), isBreak=True, isSummer=True) + term = Term.create(termCode = (code + 13), termName = "Summer {}".format(termYear + 1), isBreak=True, isSummer=True) except IntegrityError as e: - pass + termCodeMap = { + 0: code, + 1: code + 11, + 2: code + 1, + 3: code + 2, + 4: code + 12, + 5: code + 3, + 6: code + 13, + 7: code + 4, + } + term = Term.get_or_none(Term.termCode == termCodeMap[i]) + + if term is not None: + createdTerms.append(term) + + return createdTerms @admin.route("/termManagement/setDate/", methods=['POST']) def ourDate(): diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index 48e3f5e68..ba0f1e0a6 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -57,20 +57,33 @@

    Manage Departments

    Download Allocation History - + +
    From bd5c4e6d8c30498c4f8547b55ed5a660cffd0dcb Mon Sep 17 00:00:00 2001 From: kurasova Date: Tue, 21 Jul 2026 15:56:25 -0400 Subject: [PATCH 39/45] Moved some of the code into logic + replaced eval() with get_json() in the complianceStatusCheck function for safety --- .../admin_routes/manage_departments.py | 63 ++++++------------- app/logic/manageDepartments.py | 40 ++++++++++-- 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/app/controllers/admin_routes/manage_departments.py b/app/controllers/admin_routes/manage_departments.py index 0f2dd2993..b59a5409c 100644 --- a/app/controllers/admin_routes/manage_departments.py +++ b/app/controllers/admin_routes/manage_departments.py @@ -31,30 +31,30 @@ def manage_departments(academic_year = None): print ("######################", g.openTerm.termName, "######################") try: currentUser = require_login() - if not currentUser: # Not logged in + if not currentUser: # If the current user is not logged in return render_template('errors/403.html') - if not currentUser.isLaborAdmin: # Not an admin - if currentUser.student: # logged in as a student + if not currentUser.isLaborAdmin: # If the currrent user is not an admin + if currentUser.student: # If the currrent user is logged in as a student return redirect('/laborHistory/' + currentUser.student.ID) elif currentUser.supervisor: return render_template('errors/403.html'), 403 - # Sets academic_year to the current open term if no academic year is provided in the URL. Current solution. WILL change in the future. - if not academic_year: - academic_year = g.openTerm.termCode - else: + + if academic_year: # If there is an academic year (term code) in the URL academic_year = int(academic_year) + else: + academic_year = g.openTerm.termCode + # Sets academic_year to the current open term if no academic year is provided in the URL. + # Current solution. WILL change in the future. currentAY = Term.get(Term.termCode == academic_year) print("Current Term:", currentAY.termName) - previousAcademicYear = (academic_year - 100) // 100 - createPreviousAY = createTerms(previousAcademicYear) + createPreviousAY = generateTerms(academic_year - 100) previousAY = createPreviousAY[0] print("Previous Term:", previousAY.termName) - nextAcademicYear = (academic_year + 100) // 100 - createNextAY = createTerms(nextAcademicYear) + createNextAY = generateTerms(academic_year + 100) nextAY = createNextAY[0] print("Next Term:", nextAY.termName) @@ -62,8 +62,8 @@ def manage_departments(academic_year = None): # We've also thought about having a drop down menu to select the term once the academic year is selected. This should also include the ability to view the entire academic year. # Given the new implementation of the term management page, we can now use the term management page to create terms for the academic year and then use this page to view the departments for that academic year. This will be a much more efficient way to manage the terms and departments. # A concept of Currently Selected Term does not exist, yet. Implementing it here will make it so that the user can select a term and then view the departments for that term. This will be a much more efficient way to manage the terms and departments. - plainAcademicYear = academic_year // 100 # Might be a good idea to create a function for // 100 since it appears in multiple places. This will make it easier to change the implementation in the future if needed. - createdTerms = createTerms(plainAcademicYear) #FIXME: Use the selected academic year to create the terms for that year. This will be a much more efficient way to manage the terms and departments. + + createdTerms = createTerms(academic_year) #FIXME: Use the selected academic year to create the terms for that year. This will be a much more efficient way to manage the terms and departments. fallTerm = createdTerms[1] springTerm = createdTerms[4] summerTerm = createdTerms[6] @@ -77,49 +77,22 @@ def manage_departments(academic_year = None): # print(row['department'],int(row['totalHours']),row['termCode']) # print(totalBreakSum) - breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(currentAY)} # I think Scott wanted this to say NULL not zero, unsure. + breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(currentAY)} + # I think Scott wanted this to say NULL not zero, unsure. - # print(breakHoursByDepartment) - # print("\n\nSomething") - - # This was left just incase anything went wrong. Delete this if everything works as expected. Not nessicary in current implementation. - # activeDepartments = Department.select().where(Department.isActive == True) - # allAllocations = Allocation.select().where(Allocation.termCode == currentAY) - - inactiveDepartments = Department.select().where(Department.isActive == False) - - activeDepartments = getActiveDepartmentsWithAllocation(currentAY) + inactiveDepartments = Department.select().where(Department.isActive == False) - # Move some of this to Logic. - for dept in activeDepartments: - dept.totalPrimaries = (dept.allocation.primary_10 + dept.allocation.primary_12 + dept.allocation.primary_15 + dept.allocation.primary_20) - dept.totalSecondaries = (dept.allocation.secondary_5 + dept.allocation.secondary_10) - - lsfCountPrimaries = getLSFCountPrimaries(currentAY, dept) - lsfCountSecondaries = getLSFCountSecondaries(currentAY, dept) - dept.lsfCountPrimaries = lsfCountPrimaries - dept.lsfCountSecondaries = lsfCountSecondaries - # print("######################") - # print(f"COUNTS: {lsfCountSecondaries} ") - # print([lsf.formID for lsf in lsfCountPrimaries]) - # print([lsf.formID for lsf in lsfCountSecondaries]) allocationStatus = { department.departmentID: getAllocationStatus(currentAY, department) for department in activeDepartments } - # print("Pizza\n\n\n\n") - # print ("Allocation Status:", allocationStatus) - # print("\n\n\n\nPotato") - - - allSupervisors= Supervisor.select().order_by(Supervisor.LAST_NAME) return render_template( 'admin/manageDepartments.html', - title = ("Manage Departments"), + #title = ("Manage Departments"), activeDepartments = activeDepartments, inactiveDepartments = inactiveDepartments, allSupervisors = allSupervisors, @@ -183,7 +156,7 @@ def complianceStatusCheck(): This function changes the compliance status in the database for labor status forms. It works in collaboration with the ajax call in manageDepartments.js """ try: - rsp = eval(request.data.decode("utf-8")) # This fixes byte indices must be intergers or slices error + rsp = request.get_json() # This fixes byte indices must be intergers or slices error if rsp: department = Department.get(int(rsp['deptName'])) department.departmentCompliance = not department.departmentCompliance diff --git a/app/logic/manageDepartments.py b/app/logic/manageDepartments.py index b16a7ab0b..17e49de2d 100644 --- a/app/logic/manageDepartments.py +++ b/app/logic/manageDepartments.py @@ -1,3 +1,4 @@ +from app.controllers.admin_routes.termManagement import createTerms from app.models.laborStatusForm import * from app.models.formHistory import * from app.models.allocation import * @@ -46,19 +47,37 @@ def getUsedBreakHours(term): return totalBreakSum -def getActiveDepartmentsWithAllocation(currentTerm): +def getActiveDepartmentsWithAllocation(term): """ - Returns a list of active departments that have an allocation for the given term. + Returns a list of active departments with allocations for the given term. """ - activeDep = (Department + + # This was left just incase anything went wrong. Delete this if everything works as expected. Not necessary in current implementation. + # activeDepartments = Department.select().where(Department.isActive == True) + # allAllocations = Allocation.select().where(Allocation.termCode == currentAY) + + activeDepartments = (Department .select(Department, Allocation) .join(Allocation) .where( Department.isActive == True, - Allocation.termCode == currentTerm.termCode + Allocation.termCode == term.termCode ) ) - return activeDep + + for dept in activeDepartments: + dept.totalPrimaries = (dept.allocation.primary_10 + dept.allocation.primary_12 + dept.allocation.primary_15 + dept.allocation.primary_20) + dept.totalSecondaries = (dept.allocation.secondary_5 + dept.allocation.secondary_10) + + dept.lsfCountPrimaries = getLSFCountPrimaries(term, dept) + dept.lsfCountSecondaries = getLSFCountSecondaries(term, dept) + + # # print("######################") + # print(f"COUNTS: {lsfCountSecondaries} ") + # print([lsf.formID for lsf in lsfCountPrimaries]) + # print([lsf.formID for lsf in lsfCountSecondaries]) + + return activeDepartments def getAllocationStatus(term, department): """ @@ -93,4 +112,13 @@ def getLSFCountSecondaries(currentTerm, department): #Returns the current term code based on a the selected term from a dropdown menu in the manage departments page. #Should only contain the current term, the next term, and the previous term. #''' - \ No newline at end of file + +def generateTerms(termCode): + """ + Generates all the terms in an academic year. + """ + + # Truncating term codes to hundreds. That's how we get the academic year. + academicYearCode = (termCode // 100) + + return createTerms(academicYearCode) \ No newline at end of file From f03cc59920b671f490d991ee88c5103f6edb26f3 Mon Sep 17 00:00:00 2001 From: kurasova Date: Tue, 21 Jul 2026 17:24:47 -0400 Subject: [PATCH 40/45] Users can now choose the previous and the following years --- .../admin_routes/manage_departments.py | 41 +++++++++++-------- app/templates/admin/manageDepartments.html | 8 ++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/app/controllers/admin_routes/manage_departments.py b/app/controllers/admin_routes/manage_departments.py index b59a5409c..535471aff 100644 --- a/app/controllers/admin_routes/manage_departments.py +++ b/app/controllers/admin_routes/manage_departments.py @@ -38,32 +38,39 @@ def manage_departments(academic_year = None): return redirect('/laborHistory/' + currentUser.student.ID) elif currentUser.supervisor: return render_template('errors/403.html'), 403 - - if academic_year: # If there is an academic year (term code) in the URL - academic_year = int(academic_year) - else: + if academic_year == None: academic_year = g.openTerm.termCode - # Sets academic_year to the current open term if no academic year is provided in the URL. - # Current solution. WILL change in the future. - currentAY = Term.get(Term.termCode == academic_year) + academic_year = int(academic_year) + + if (academic_year != g.openTerm.termCode - 100) and (academic_year != g.openTerm.termCode) and (academic_year != g.openTerm.termCode + 100): + return "", 400 + + createdTerms = generateTerms(g.openTerm.termCode) #FIXME: Use the selected academic year to create the terms for that year. This will be a much more efficient way to manage the terms and departments. + currentAY = Term.get(Term.termCode == g.openTerm.termCode) print("Current Term:", currentAY.termName) - createPreviousAY = generateTerms(academic_year - 100) + createPreviousAY = generateTerms(g.openTerm.termCode - 100) previousAY = createPreviousAY[0] print("Previous Term:", previousAY.termName) - createNextAY = generateTerms(academic_year + 100) + createNextAY = generateTerms(g.openTerm.termCode + 100) nextAY = createNextAY[0] print("Next Term:", nextAY.termName) + + if academic_year == g.openTerm.termCode - 100: + usedAY = previousAY + elif academic_year == g.openTerm.termCode: + usedAY = currentAY + else: + usedAY = nextAY # Works. Should work without production data now. # We've also thought about having a drop down menu to select the term once the academic year is selected. This should also include the ability to view the entire academic year. # Given the new implementation of the term management page, we can now use the term management page to create terms for the academic year and then use this page to view the departments for that academic year. This will be a much more efficient way to manage the terms and departments. # A concept of Currently Selected Term does not exist, yet. Implementing it here will make it so that the user can select a term and then view the departments for that term. This will be a much more efficient way to manage the terms and departments. - createdTerms = createTerms(academic_year) #FIXME: Use the selected academic year to create the terms for that year. This will be a much more efficient way to manage the terms and departments. fallTerm = createdTerms[1] springTerm = createdTerms[4] summerTerm = createdTerms[6] @@ -77,16 +84,16 @@ def manage_departments(academic_year = None): # print(row['department'],int(row['totalHours']),row['termCode']) # print(totalBreakSum) - breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(currentAY)} + breakHoursByDepartment = {row["department"]: str(row["totalHours"] if row["totalHours"] is not None else 0) for row in getUsedBreakHours(usedAY)} # I think Scott wanted this to say NULL not zero, unsure. - activeDepartments = getActiveDepartmentsWithAllocation(currentAY) + activeDepartments = getActiveDepartmentsWithAllocation(usedAY) inactiveDepartments = Department.select().where(Department.isActive == False) allocationStatus = { - department.departmentID: getAllocationStatus(currentAY, department) + department.departmentID: getAllocationStatus(usedAY, department) for department in activeDepartments } @@ -96,10 +103,10 @@ def manage_departments(academic_year = None): activeDepartments = activeDepartments, inactiveDepartments = inactiveDepartments, allSupervisors = allSupervisors, - currentAY = currentAY.termName, - previousAY = previousAY.termName, - nextAY = nextAY.termName, - academicYear = currentAY.termName, + currentAY = currentAY, + previousAY = previousAY, + nextAY = nextAY, + academicYear = usedAY.termName, # totalBreakSum = totalBreakSum breakHoursByDepartment = breakHoursByDepartment, allocationStatus = allocationStatus diff --git a/app/templates/admin/manageDepartments.html b/app/templates/admin/manageDepartments.html index ba0f1e0a6..4b9b8636e 100755 --- a/app/templates/admin/manageDepartments.html +++ b/app/templates/admin/manageDepartments.html @@ -64,22 +64,22 @@

    Manage Departments

    -

    - - -
    -
    - -
    - - +
    +
    + +
    - - -
    -
    + +
    -
    + +
    -
    + +
    + + + + + + + + +
    @@ -152,7 +180,8 @@

    Manage Departments

    Prim: {{department.lsfCountPrimaries}} of {{department.totalPrimaries}}

    -

    Sec: {{department.lsfCountSecondaries}} of {{department.totalSecondaries}} +

    Sec: {{department.lsfCountSecondaries}} of + {{department.totalSecondaries}}

    @@ -162,7 +191,7 @@

    Manage Departments

    style="pointer-events: none; cursor: default;"> {{ "Approved" if allocationStatus.get(department.departmentID) else "Pending" }} - +