Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9bd90f6
added changes from previous branch to avoid all files being commited
conwelld Jul 21, 2026
56d5a29
fixed some pr comments
conwelld Jul 21, 2026
faf1957
fixed some pr comments for css styling
conwelld Jul 21, 2026
1204269
fixed useless code
conwelld Jul 21, 2026
0f166c2
fixed department code
conwelld Jul 21, 2026
6f5850a
We have change the hard coded part with variable able to be flexible …
Jul 22, 2026
813f398
Temporary allocation logic will be replaced by the official shared se…
Jul 22, 2026
7584ffa
fix the review comment from Minran, all of them
DanielRukwasha Jul 27, 2026
e9a4415
Merge branch 'department-portal-base' into new-allocation-card, resol…
DanielRukwasha Jul 28, 2026
20b424c
Fix import after allocationUtilization rename to getAllocation, add i…
DanielRukwasha Jul 29, 2026
ee0e066
Address PR review comments: consolidate getAllocation return dict, ex…
DanielRukwasha Jul 30, 2026
6abd704
Merge branch 'department-portal-base' into new-allocation-card, resol…
DanielRukwasha Jul 30, 2026
8618b68
Adopt approval-status filtering from UsedAllocFunction branch in getA…
DanielRukwasha Jul 30, 2026
a0ba238
Polish the allocation card: dynamic Fall/Spring term label, "X of Y" …
munsakad Aug 3, 2026
86bee45
Merge branch 'department-portal-base' into new-allocation-card
munsakad Aug 3, 2026
45b13e0
Fix duplicate main.managePositions endpoint left over from the depart…
munsakad Aug 3, 2026
74bdd3a
Rework allocation rows to the "N hr: X contracts (out of Y allocation…
munsakad Aug 3, 2026
a7ca474
Address allocation card review: camelCase naming, stacked layout, con…
munsakad Aug 4, 2026
c7ef1ec
Merge branch 'department-portal-base' of https://github.com/BCStudent…
munsakad Aug 5, 2026
25d9a9b
Reuse allocationManager.py in getAllocation.py
munsakad Aug 5, 2026
f5640b3
Fix missing LaborReleaseForm import in demo_data.py
munsakad Aug 5, 2026
4c17019
Fix allocation card showing zeros for departments with only a draft a…
munsakad Aug 5, 2026
f3b43c6
removed unneccesary comments
munsakad Aug 5, 2026
6ae3931
removed department information in main routes
munsakad Aug 5, 2026
6f9486f
Merge branch 'department-portal-base' of https://github.com/BCStudent…
fritzj2 Aug 27, 2026
6d6997c
removed merge conflict fragment
fritzj2 Aug 27, 2026
ded0a5e
fixed broken icons in css
fritzj2 Aug 27, 2026
ba90482
added smaller logic for the allocation card
fritzj2 Aug 28, 2026
300b7b0
HTML now uses new variables
fritzj2 Aug 28, 2026
10fdda4
added the current semester
fritzj2 Aug 28, 2026
02a100d
fixed syntax when no value it given
fritzj2 Aug 28, 2026
9bb3197
removed out of scope change
fritzj2 Aug 28, 2026
fd86d2a
removed out of scope database issue
fritzj2 Aug 28, 2026
0b0324a
removed unused dateTime import
fritzj2 Aug 28, 2026
db6f90a
removed unused logic file
fritzj2 Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions app/controllers/main_routes/main_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from app.models.laborStatusForm import LaborStatusForm
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.models.positionHistory import PositionHistory

from app.controllers.admin_routes.allPendingForms import checkAdjustment
from app.controllers.main_routes import main_bp
Expand All @@ -24,7 +24,7 @@
from app.logic.getSupervisors import getSupervisors
from app.logic.getPositions import getActivePositions
from app.logic.allocationManager import getBreakContracts, getContractedAllocations, getTotalAllocations
from app.logic.getTerms import getTerms
from app.logic.getTerms import getTerms, getCurrentSemester


@main_bp.route('/logout', methods=['GET'])
Expand Down Expand Up @@ -74,11 +74,21 @@ def departmentPortal(org=None,account=None):

supervisors, laborCoordinators = getSupervisors(dept)


currentAY, fallTerm, springTerm = getTerms()
allocationDict = getTotalAllocations(currentAY, dept)
currentSemester = getCurrentSemester()
contracts = getContractedAllocations(currentSemester, dept)


positionsList, posURL = getActivePositions(dept)

return render_template('main/departmentPortal.html',
departments = departments,
department = dept,
contracts = contracts,
allocation = allocationDict,
currentSemester = currentSemester.termName,
supervisors = supervisors,
laborCoordinators=laborCoordinators,
currentUser=currentUser,
Expand Down
42 changes: 14 additions & 28 deletions app/logic/allocationManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,36 +98,22 @@ def countContracts(jobType: str, weeklyContractHours: int, termCode: int, dept:

def getContractedAllocations(termCode: int, dept: int):
'''
This function returns a dictionary with a breakdown of all types of contracts
This function returns a dictionary with a breakdown of all types of contracts
for the given department and term in the form of a dictionary.
'''
academicYearCode = int(str(termCode)[:4] + "00")
allocationObject = getAllocation(termCode, dept)
breakAllocation = 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 breakAllocation:
if row["department"] == dept:
breakSum = row
break

breakHoursTotal = (
FormHistory.select(fn.SUM(LaborStatusForm.contractHours))
.join(LaborStatusForm, on=(FormHistory.formID == LaborStatusForm.laborStatusFormID))
.where(
FormHistory.historyType == "Labor Status Form",
FormHistory.status == "Approved",
LaborStatusForm.termCode.in_([termCode, academicYearCode]),
LaborStatusForm.department == dept,
)
.scalar()
) or 0

# dictionary definition:
usedPositions = {
"used_10": countContracts("Primary", "10", termCode, dept),
Expand All @@ -139,7 +125,7 @@ def getContractedAllocations(termCode: int, dept: int):
"used_primaries": 0,
"used_secondaries": 0,
"used_total": 0, # all contracts with weekly hours, i.e. primaries + secondaries (not break contracts)
"break_hours": breakSum["total_hours"] # all break hours contracted (but not necessarily worked)
"break_hours": breakHoursTotal # all break hours contracted (but not necessarily worked)
}
usedPositions["used_primaries"] = sum(list(usedPositions.values())[:4])
usedPositions["used_secondaries"] = sum(list(usedPositions.values())[4:6])
Expand Down
12 changes: 12 additions & 0 deletions app/logic/getTerms.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,15 @@ def getTerms(academicYear: str = None):
springTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 12).get()
return currentAY, fallTerm, springTerm

def getCurrentSemester():
'''
The difference between this function and the one above is that it gets just the current term
It does not get both Fall and Spring, it just gets one depending on the month.
'''
currentDate = date.today()
if currentDate.month <= 6:
springTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 12 - 100).get()
return springTerm
else:
fallTerm = Term.select().where(Term.termCode == currentDate.year * 100 + 11).get()
return fallTerm
76 changes: 67 additions & 9 deletions app/static/css/departmentPortal.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,71 @@
padding: 1rem;
min-width: 100%;
}

.members-icon {
display: inline-block;
.bi-suitcase-lg-fill { /* Bootstrap Icon */
border: 1px solid #c0c0c0;
border-radius: 8px;
padding: 3px 3.5px 1.5px;
font-size: 36px;
color: #6e6e6e;
padding: 3px 3.5px 1.5px 3.5px;
font-size: 3rem;
color:#6e6e6e;
}
margin-bottom: 20px;
min-height: 200px;
.bi-clock {
Comment thread
munsakad marked this conversation as resolved.
border: 1px solid #c0c0c0;
border-radius: 8px;
padding: 3px 3.5px 1.5px 3.5px;
font-size: 3rem;
color:#6e6e6e;
}
.bi-suitcase-lg-fill { /* Bootstrap Icon */
.bi-info-circle {
padding: 3px 3.5px 1.5px 3.5px;
font-size: 1.5rem;
vertical-align: middle;
color:#6e6e6e;
}
.allocation-table-wrapper {
overflow-x: auto;
margin: 10px 0;
}
.allocation-summary {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
gap: 0 1rem;
}
.allocation-summary h4 {
margin: 10px 0;
}
.allocation-columns {
display: flex;
Comment thread
munsakad marked this conversation as resolved.
flex-wrap: wrap;
gap: 0 2rem;
}
.allocation-table {
/* wraps onto its own line when the card is too narrow, instead of shrinking */
flex: 1 1 180px;
border-collapse: collapse;
font-size: 1.2em;
}
.allocation-table th,
.allocation-table td {
text-align: left;
white-space: nowrap;
padding: 4px 10px 4px 0;
line-height: 1.3;
}
.allocation-table th {
font-weight: 700;
padding-top: 10px;
}

.bi-people-fill { /* Bootstrap Icon for Members Card */
border: 1px solid #c0c0c0;
border-radius: 8px;
padding: 3px 3.5px 1.5px 3.5px;
font-size: 3rem;
color:#6e6e6e;
}

.card-group {
gap: 1rem;
}
Expand All @@ -52,3 +98,15 @@
flex-direction: column;
}
}

/* Narrow card: stack Secondary below Primary, and the position count below the
term, rather than shrinking the text to keep them side by side. */
@media (min-width: 1200px) and (max-width: 1450px), (max-width: 480px) {
.allocation-summary {
flex-direction: column;
gap: 0;
}
.allocation-columns .allocation-table {
flex-basis: 100%;
}
}
4 changes: 4 additions & 0 deletions app/static/js/departmentPortal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ $(document).ready(function() {
window.location = `/department/${deptData.org}/${deptData.account}`;
});
});

$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
46 changes: 44 additions & 2 deletions app/templates/main/departmentPortal.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,50 @@ <h2 class="text-center">{% if department %} {{department.DEPT_NAME}} Portal {% e
{% if department %}
<div class="card-row g-3">
<div class="col-12 col-lg-4 ">
<section class="card" aria-labelledby="current_allocation-title">
<p> Insert Allocations Card Here </p>
<section class="card" aria-labelledby="allocationTitle">
<div class="card-body">
<div class="media">
<div class="media-left media-middle">
<span aria-hidden="true" style="color: #424242; font-size: 24px;">
<i class="bi bi-clock"></i>
</span>
</div>
<div class="media-body media-middle">
<h3 id="allocationTitle">Current Allocations</h3>
</div>
{% macro allocationRow(hours, used, allocated) -%}
<tr><td>{{ hours }} hr: {{ used }} contract{{ 's' if used != 1 else '' }} out of {{ allocated if allocated is integer else 0 }} allocation{{ 's' if allocated != 1 else '' }}</td></tr>
{%- endmacro %}
<div class="allocation-table-wrapper">
<div class="allocation-summary">
<h4><b>{{ currentSemester if currentSemester else "No term data" }}</b></h4>
<h4>{{contracts["used_total"]}} contracted of {{allocation["totalAllocations"] if allocation["totalAllocations"] is integer else 0}} allocations</h4>
</div>
<div class="allocation-columns">
<table class="allocation-table">
<thead>
<th>Primary</th>
</thead>
<tbody>
{{ allocationRow(10, contracts["used_10"], allocation["primary_10"]) }}
{{ allocationRow(12, contracts["used_12"], allocation["primary_12"]) }}
{{ allocationRow(15, contracts["used_15"], allocation["primary_15"]) }}
{{ allocationRow(20, contracts["used_20"], allocation["primary_20"]) }}
</tbody>
</table>
<table class="allocation-table">
<thead>
<th>Secondary</th>
</thead>
<tbody>
{{ allocationRow(5,contracts["used_5_sec"], allocation["secondary_5"]) }}
{{ allocationRow(10, contracts["used_10_sec"], allocation["secondary_10"]) }}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card-footer text-center">
<a href="/department/{{ department.ORG }}/{{ department.ACCOUNT }}/allocations" class="btn btn-primary">View Allocations<span class="glyphicon glyphicon-chevron-right"></span></a>
</div>
Expand Down
Loading