From 662b15deca2fc8ba77dab5810862a58e5313556f Mon Sep 17 00:00:00 2001 From: zawn Date: Wed, 22 Jul 2026 14:14:13 -0400 Subject: [PATCH 1/6] removed the laborhisotry dict not being changed multiple times because of the same key, considered edge cases if there are multiple position hold by a person and if the switch to a different position during spring which means we cannot display it as AY but as seperate spring and fall. --- app/logic/celtsLabor.py | 39 +++++++++++++++++++++++------ app/templates/main/userProfile.html | 4 +-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/app/logic/celtsLabor.py b/app/logic/celtsLabor.py index c32bc2eae..dcac59841 100644 --- a/app/logic/celtsLabor.py +++ b/app/logic/celtsLabor.py @@ -15,8 +15,10 @@ def getCeltsLaborFromLsf(): """ try: - lsfUrl = f"{app.config['lsf_url'].strip('/')}/api/org/2084" + # lsfUrl = f"{app.config['lsf_url'].strip('/')}/api/org/2084" + lsfUrl = "http://127.0.0.1:8989/api/org/2084" response = requests.get(lsfUrl) + print("jinja", response.json()) return response.json() except json.decoder.JSONDecodeError: print(f'Response from {lsfUrl} was not JSON.\n' + response.text) @@ -117,14 +119,37 @@ def refreshCeltsLaborRecords(laborDict): def getCeltsLaborHistory(volunteer): laborHistoryList = list(CeltsLabor.select(CeltsLabor.positionTitle, + CeltsLabor.id, Term.description, Term.academicYear, Term.isSummer) .join(Term, on=(CeltsLabor.term == Term.id)) - .where(CeltsLabor.user == volunteer)) - + .where(CeltsLabor.user == volunteer) + .order_by(Term.id.asc())) + termsByAcademicYear = {} + for position in laborHistoryList: + if position.term.isSummer: + continue + academicYear = position.term.academicYear + description = position.term.description + if academicYear not in termsByAcademicYear: + termsByAcademicYear[academicYear] = {"Fall": False,"Spring": False} + if "Fall" in description: + termsByAcademicYear[academicYear]["Fall"] = True + elif "Spring" in description: + termsByAcademicYear[academicYear]["Spring"] = True laborHistoryDict= {} - for position in laborHistoryList: - laborHistoryDict[position.positionTitle] = position.term.description if position.term.isSummer else position.term.academicYear - - return laborHistoryDict + for position in laborHistoryList: + description = position.term.description + academicYear = position.term.academicYear + if position.term.isSummer: + positionTerm = description + else: + hasFall = termsByAcademicYear[academicYear]["Fall"] + hasSpring = termsByAcademicYear[academicYear]["Spring"] + if hasFall and hasSpring: + positionTerm = description + else: + positionTerm = f"AY {academicYear}" + laborHistoryDict[position.id] = (position.positionTitle,positionTerm) + return laborHistoryDict \ No newline at end of file diff --git a/app/templates/main/userProfile.html b/app/templates/main/userProfile.html index b4cafbccf..597044883 100644 --- a/app/templates/main/userProfile.html +++ b/app/templates/main/userProfile.html @@ -282,8 +282,8 @@

{% if participatedInLabor %}
CELTS Labor History:
- {% for program, term in participatedInLabor.items() %} -

{{term}}: {{program}}

+ {% for positionTitle, term in participatedInLabor.values() %} +

{{term}}: {{positionTitle}}

{% endfor %}
{% endif %} From 1ac554a3433c410df5b5cc57e23065a234fe9fb7 Mon Sep 17 00:00:00 2001 From: zawn Date: Mon, 27 Jul 2026 09:40:33 -0400 Subject: [PATCH 2/6] any wild card and any prefix and ambiguity problem in search is fix --- app/logic/searchUsers.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/logic/searchUsers.py b/app/logic/searchUsers.py index 92ee2c76a..b2cf66c13 100644 --- a/app/logic/searchUsers.py +++ b/app/logic/searchUsers.py @@ -8,14 +8,13 @@ def searchUsers(query, category=None): ''' # add wildcards to each piece of the query splitSearch = query.strip().split() - firstName = splitSearch[0] + "%" - lastName = " ".join(splitSearch[1:]) +"%" - - if len(splitSearch) == 1: # search for query in first OR last name - searchWhere = (User.firstName ** firstName | User.lastName ** firstName | User.username ** splitSearch) - else: # search for first AND last name - searchWhere = (User.firstName ** firstName & User.lastName ** lastName) - + fullSearch = " ".join(splitSearch) + "%" + searchWhere = (User.firstName ** fullSearch | User.lastName ** fullSearch | User.username ** fullSearch) + for splitIndex in range(1, len(splitSearch)): + firstName = " ".join(splitSearch[:splitIndex]) + "%" + lastName = " ".join(splitSearch[splitIndex:]) + "%" + searchWhere |= (User.firstName ** firstName & User.lastName ** lastName) + if category == "instructor": userWhere = (User.isFaculty | User.isStaff) elif category == "admin": From b75ca4e02bd1faf24ad2dbeab02ee9d12bb90fdb Mon Sep 17 00:00:00 2001 From: zawn Date: Mon, 27 Jul 2026 10:10:41 -0400 Subject: [PATCH 3/6] access controlled added and as neillz is not longer listed as isceltsstudentstaff I have editted the side bar to allow someone who is studentstaff --- app/controllers/minor/routes.py | 3 +++ app/templates/sidebar.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/minor/routes.py b/app/controllers/minor/routes.py index 64575ba4f..099ee6b64 100644 --- a/app/controllers/minor/routes.py +++ b/app/controllers/minor/routes.py @@ -29,6 +29,9 @@ def viewCceMinor(username): """ Load minor management page with community engagements and summer experience """ + if not (g.current_user.isAdmin or g.current_user.username == username or g.current_user.isCeltsStudentStaff): + return abort(403) + sustainedEngagementByTerm = getCommunityEngagementByTerm(username) activeTab = request.args.get("tab", "sustainedCommunityEngagements") diff --git a/app/templates/sidebar.html b/app/templates/sidebar.html index e1dd71e24..6ed24234a 100644 --- a/app/templates/sidebar.html +++ b/app/templates/sidebar.html @@ -105,7 +105,7 @@
Current User: {{g.current_user.username}}
From dfd1031fc71f77151924894989d06f7c54e78c95 Mon Sep 17 00:00:00 2001 From: zawn Date: Mon, 27 Jul 2026 11:07:37 -0400 Subject: [PATCH 4/6] test case added ascending order fixed --- app/logic/celtsLabor.py | 2 +- tests/code/test_celtsLabor.py | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/logic/celtsLabor.py b/app/logic/celtsLabor.py index dcac59841..612e87d16 100644 --- a/app/logic/celtsLabor.py +++ b/app/logic/celtsLabor.py @@ -125,7 +125,7 @@ def getCeltsLaborHistory(volunteer): Term.isSummer) .join(Term, on=(CeltsLabor.term == Term.id)) .where(CeltsLabor.user == volunteer) - .order_by(Term.id.asc())) + .order_by(Term.termOrder.asc())) termsByAcademicYear = {} for position in laborHistoryList: if position.term.isSummer: diff --git a/tests/code/test_celtsLabor.py b/tests/code/test_celtsLabor.py index 0beb24cfb..01d2d329f 100644 --- a/tests/code/test_celtsLabor.py +++ b/tests/code/test_celtsLabor.py @@ -244,13 +244,24 @@ def test_getCeltsLaborHistory(): isAcademicYear = True) - testDataAyisieHistory = {"Bonner Manager": "Summer 2021"} + testDataAyisieHistory = [('Bonner Manager', 'Summer 2021')] getAyisieHistory = getCeltsLaborHistory(ayisie) - testDataMupotsalHistory = {"Habitat For Humanity Cord.": "2020-2021"} + testDataMupotsalHistory = [('Habitat For Humanity Cord.', 'AY 2020-2021')] getMupotsalHistory = getCeltsLaborHistory(mupotsal) - assert getAyisieHistory == testDataAyisieHistory - assert getMupotsalHistory == testDataMupotsalHistory + assert list(getAyisieHistory.values()) == testDataAyisieHistory + assert list(getMupotsalHistory.values()) == testDataMupotsalHistory + + CeltsLabor.create(user = mupotsal, + positionTitle = "Bonner Manager", + term = Term.get_by_id(1), + isAcademicYear = True) + + #this is to test if there are two different celts labor in a academic year it no longers show AY 2020-2021 instead shows Fall and Spring in ascending order + testDataMupotsalHistoryFallSpring = [('Bonner Manager', 'Fall 2020'), ('Habitat For Humanity Cord.', 'Spring 2021')] + getMupotsalHistory = getCeltsLaborHistory(mupotsal) + + assert list(getMupotsalHistory.values()) == testDataMupotsalHistoryFallSpring transaction.rollback() \ No newline at end of file From b06444046d29a9f3bc5a9688ef9999a9378aae38 Mon Sep 17 00:00:00 2001 From: zawn Date: Mon, 27 Jul 2026 11:22:35 -0400 Subject: [PATCH 5/6] remove print statment --- app/logic/celtsLabor.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/logic/celtsLabor.py b/app/logic/celtsLabor.py index 612e87d16..db8c78450 100644 --- a/app/logic/celtsLabor.py +++ b/app/logic/celtsLabor.py @@ -15,10 +15,8 @@ def getCeltsLaborFromLsf(): """ try: - # lsfUrl = f"{app.config['lsf_url'].strip('/')}/api/org/2084" - lsfUrl = "http://127.0.0.1:8989/api/org/2084" + lsfUrl = f"{app.config['lsf_url'].strip('/')}/api/org/2084" response = requests.get(lsfUrl) - print("jinja", response.json()) return response.json() except json.decoder.JSONDecodeError: print(f'Response from {lsfUrl} was not JSON.\n' + response.text) From bbddd858397431e15596574252e7f5e8510e7b45 Mon Sep 17 00:00:00 2001 From: zawn Date: Thu, 13 Aug 2026 14:56:15 -0400 Subject: [PATCH 6/6] search query click fix, search query prefix, suffix fixed, report download fix, sidebar enhanced, new config line added --- app/config/default.yml | 2 ++ app/logic/searchUsers.py | 30 ++++++++++++++++++++++++++++-- app/logic/volunteerSpreadsheet.py | 2 +- app/static/js/searchStudent.js | 2 +- app/templates/sidebar.html | 4 +++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/app/config/default.yml b/app/config/default.yml index b480cc7d2..bbc3f9ba6 100644 --- a/app/config/default.yml +++ b/app/config/default.yml @@ -7,6 +7,8 @@ support_email_contact: "support@bereacollege.onmicrosoft.com" show_queries: True test_entry: "Default" +lsf_url: "REPLACE" + db: name: "celts" host: "db" diff --git a/app/logic/searchUsers.py b/app/logic/searchUsers.py index 1c635f293..a18f1fece 100644 --- a/app/logic/searchUsers.py +++ b/app/logic/searchUsers.py @@ -1,3 +1,4 @@ +from peewee import fn from playhouse.shortcuts import model_to_dict from app.models.user import User def searchUsers(query, category=None): @@ -8,12 +9,28 @@ def searchUsers(query, category=None): ''' # add wildcards to each piece of the query splitSearch = query.strip().split() + if not splitSearch: + return User.select().where(False) fullSearch = " ".join(splitSearch) + "%" searchWhere = (User.firstName ** fullSearch | User.lastName ** fullSearch | User.username ** fullSearch) for splitIndex in range(1, len(splitSearch)): firstName = " ".join(splitSearch[:splitIndex]) + "%" lastName = " ".join(splitSearch[splitIndex:]) + "%" - searchWhere |= (User.firstName ** firstName & User.lastName ** lastName) + + searchWhere |= ( + (User.firstName ** firstName) & + (User.lastName ** lastName) + ) + + # Also allow individual pieces of the name to match + for namePart in splitSearch: + nameSearch = namePart + "%" + + searchWhere |= ( + (User.firstName ** nameSearch) | + (User.lastName ** nameSearch) | + (User.username ** nameSearch) + ) if category == "instructor": userWhere = (User.isFaculty | User.isStaff) @@ -30,7 +47,16 @@ def searchUsers(query, category=None): else: userWhere = (User.isStudent) + fullSearchText = " ".join(splitSearch) # Combine into query - searchResults = User.select().where(searchWhere, userWhere) + searchResults = User.select().where(searchWhere, userWhere).order_by( + fn.CONCAT(User.firstName, " ", User.lastName) + .contains(fullSearchText) + .desc(), + User.firstName.startswith(fullSearchText).desc(), + User.lastName.startswith(fullSearchText).desc(), + User.lastName, + User.firstName + ) return { user.username : model_to_dict(user) for user in searchResults } diff --git a/app/logic/volunteerSpreadsheet.py b/app/logic/volunteerSpreadsheet.py index 411bab07a..86dd59cac 100644 --- a/app/logic/volunteerSpreadsheet.py +++ b/app/logic/volunteerSpreadsheet.py @@ -319,7 +319,7 @@ def makeDataXls(sheetName, sheetData, workbook, sheetDesc=None): if type(dataRows) == list: for row, rowData in enumerate(dataRows): col_idx = 0 - for column, value in rowData.items(): + for value in rowData: # dates and times should use their text representation if isinstance(value, (datetime, date, time)): value = str(value) diff --git a/app/static/js/searchStudent.js b/app/static/js/searchStudent.js index bdfcc9e1f..3d6f8a087 100644 --- a/app/static/js/searchStudent.js +++ b/app/static/js/searchStudent.js @@ -1,7 +1,7 @@ import searchUser from './searchUser.js' function callback(selected) { - $("#searchStudentsInput").submit(); + $("#searchStudentsInput").closest("form").submit(); } $(document).ready(function() { diff --git a/app/templates/sidebar.html b/app/templates/sidebar.html index b4fb6246a..1098e6385 100644 --- a/app/templates/sidebar.html +++ b/app/templates/sidebar.html @@ -105,7 +105,9 @@
Current User: {{g.current_user.username}}