-
Notifications
You must be signed in to change notification settings - Fork 0
Add over-allocation warning on labor status form (#615) #646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DanielRukwasha
wants to merge
22
commits into
department-portal-base
Choose a base branch
from
615-over-allocation-warning-lsf-creation
base: department-portal-base
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
b4d408f
Wire Current Allocation card to real Allocation/LaborStatusForm data …
DanielRukwasha 0d1dad4
Remove Request Allocation button and relabel AY as Term on allocation…
DanielRukwasha 747a75e
Add Primary/Secondary titles above the hour-band breakdown lists
DanielRukwasha 391728a
Merge remote-tracking branch 'origin/allocation_card' into allocation…
DanielRukwasha 0d64daf
Add allocation warning to pending LSF approval modal (#622)
DanielRukwasha ac0ace0
Highlight positions and break hours independently in allocation warning
DanielRukwasha ca34008
Flash a warning after approving forms if the department is now over-a…
DanielRukwasha 035cda0
Fix over-allocation check to look at each hour-band, not just the total
DanielRukwasha f71b525
Merge remote-tracking branch 'origin/department-portal-base' into 622…
DanielRukwasha 3ff622a
Add over-allocation warning on labor status form (#615)
DanielRukwasha b148007
Merge remote-tracking branch 'origin/development' into 615-over-alloc…
DanielRukwasha a6fde6c
Merge branch 'department-portal-base' into 615-over-allocation-warnin…
DanielRukwasha b9565b8
Merge branch 'department-portal-base' into 615-over-allocation-warnin…
DanielRukwasha e33755a
Address remaining PR review comments on the over-allocation warning f…
DanielRukwasha 9069a1b
Always show individual approve checkbox regardless of student/supervi…
DanielRukwasha 40b11be
removing x/y allocatioin to X remaining on the forms to make pending
DanielRukwasha 3c7b838
real time small table display the current allocation sitution
DanielRukwasha 56396ac
new real table update allocation situation on the labor status form
DanielRukwasha c10060e
Merge remote-tracking branch 'origin/department-portal-base' into 615…
DanielRukwasha a63e0e8
warn when staged students overallocate a department before submission
DanielRukwasha 0b72402
Show live over-allocation warnings on the pending-forms list page
DanielRukwasha 8e95894
Merge branch 'department-portal-base' into 615-over-allocation-warnin…
MImran2002 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| from peewee import fn | ||
|
|
||
| from app.models.allocation import Allocation | ||
| from app.models.laborStatusForm import LaborStatusForm | ||
| from app.models.formHistory import FormHistory | ||
| from app.models.term import Term | ||
|
|
||
| # (Allocation field name, LaborStatusForm.jobType, LaborStatusForm.weeklyHours) | ||
| ALLOCATION_BAND_FIELDS = [ | ||
| ('primary_10', 'Primary', 10), | ||
| ('primary_12', 'Primary', 12), | ||
| ('primary_15', 'Primary', 15), | ||
| ('primary_20', 'Primary', 20), | ||
| ('secondary_5', 'Secondary', 5), | ||
| ('secondary_10', 'Secondary', 10), | ||
| ] | ||
|
|
||
| BAND_LABELS = {fieldName: f"{hours} Hour {jobType}" for fieldName, jobType, hours in ALLOCATION_BAND_FIELDS} | ||
|
|
||
|
|
||
| def getTotalAllocations(term, dept): | ||
| """Return the department's allocated totals per band for a term.""" | ||
| if not term or not dept: | ||
| return None | ||
|
|
||
| allocation = Allocation.get_or_none(Allocation.department == dept, Allocation.termCode == term) | ||
| if not allocation: | ||
| return None | ||
|
|
||
| bandTotals = {fieldName: getattr(allocation, fieldName) for fieldName, _, _ in ALLOCATION_BAND_FIELDS} | ||
| return { | ||
| "allocation": allocation, | ||
| "bandTotals": bandTotals, | ||
| "totalAllocations": sum(bandTotals.values()), | ||
| } | ||
|
|
||
|
|
||
| def getContractedAllocations(term, dept): | ||
| """Return the department's used positions per band and approved break hours for a term.""" | ||
| if not term or not dept: | ||
| return None | ||
|
|
||
| usedPositions = {} | ||
| for fieldName, jobType, hours in ALLOCATION_BAND_FIELDS: | ||
| usedPositions[fieldName] = ( | ||
| LaborStatusForm.select() | ||
| .join(FormHistory, on=(FormHistory.formID == LaborStatusForm.laborStatusFormID)) | ||
| .where( | ||
| LaborStatusForm.department == dept, | ||
| LaborStatusForm.termCode == term, | ||
| LaborStatusForm.jobType == jobType, | ||
| LaborStatusForm.weeklyHours == hours, | ||
| FormHistory.historyType == "Labor Status Form", | ||
| ~(FormHistory.status % "Denied%"), | ||
| ) | ||
| .distinct() | ||
| .count() | ||
| ) | ||
|
|
||
| # Break hours are tracked on separate break-term rows (e.g. Thanksgiving Break) | ||
| # that share the same academic year prefix as the given AY term. | ||
| yearPrefix = str(term.termCode)[:-2] | ||
| breakTermCodes = [ | ||
| t.termCode for t in Term.select().where(Term.isBreak == True) | ||
| if str(t.termCode).startswith(yearPrefix) | ||
| ] | ||
| breakHours = ( | ||
| LaborStatusForm.select(fn.SUM(LaborStatusForm.contractHours)) | ||
| .join(FormHistory, on=(FormHistory.formID == LaborStatusForm.laborStatusFormID)) | ||
| .where( | ||
| LaborStatusForm.department == dept, | ||
| LaborStatusForm.termCode.in_(breakTermCodes), | ||
| FormHistory.historyType == "Labor Status Form", | ||
| ~(FormHistory.status % "Denied%"), | ||
| ) | ||
| .scalar() | ||
| ) or 0 | ||
|
|
||
| return { | ||
| "usedPositions": usedPositions, | ||
| "usedTotal": sum(usedPositions.values()), | ||
| "breakHours": breakHours, | ||
| } | ||
|
|
||
|
|
||
| def getBandAllocationStatus(dept, term, jobType, hours): | ||
| fieldName = next((f for f, j, h in ALLOCATION_BAND_FIELDS if j == jobType and h == hours), None) | ||
| if not fieldName: | ||
| return None | ||
|
|
||
| totals = getTotalAllocations(term, dept) | ||
| if not totals: | ||
| return None | ||
| contracted = getContractedAllocations(term, dept) | ||
|
|
||
| allocated = totals["bandTotals"][fieldName] | ||
| used = contracted["usedPositions"][fieldName] | ||
| return { | ||
| 'label': BAND_LABELS[fieldName], | ||
| 'used': used, | ||
| 'allocated': allocated, | ||
| 'remaining': allocated - used, | ||
| 'isOverAllocated': used > allocated, | ||
| } | ||
|
|
||
|
|
||
| def getAllocationWarning(dept, term): | ||
| totals = getTotalAllocations(term, dept) | ||
| if not totals: | ||
| return None | ||
| contracted = getContractedAllocations(term, dept) | ||
|
|
||
| positionsRemaining = totals["totalAllocations"] - contracted["usedTotal"] | ||
| breakHoursRemaining = totals["allocation"].breakHours - contracted["breakHours"] | ||
|
|
||
| # A department can be within its total position count while still exceeding | ||
| # one specific hour-band (e.g. over on 10-hour Primary but under on others), | ||
| # so each band needs to be checked individually, not just the aggregate total. | ||
| overAllocatedBands = [ | ||
| {'label': BAND_LABELS[fieldName], 'used': contracted["usedPositions"][fieldName], 'allocated': totals["bandTotals"][fieldName]} | ||
| for fieldName, _, _ in ALLOCATION_BAND_FIELDS | ||
| if contracted["usedPositions"][fieldName] > totals["bandTotals"][fieldName] | ||
| ] | ||
| isPositionsOverAllocated = positionsRemaining < 0 or bool(overAllocatedBands) | ||
| isBreakHoursOverAllocated = breakHoursRemaining < 0 | ||
|
|
||
| return { | ||
| 'departmentName': dept.DEPT_NAME, | ||
| 'totalPositionsAllocated': totals["totalAllocations"], | ||
| 'totalPositionsUsed': contracted["usedTotal"], | ||
| 'positionsRemaining': positionsRemaining, | ||
| 'isPositionsOverAllocated': isPositionsOverAllocated, | ||
| 'overAllocatedBands': overAllocatedBands, | ||
| 'breakHoursAllocated': totals["allocation"].breakHours, | ||
| 'breakHoursUsed': contracted["breakHours"], | ||
| 'breakHoursRemaining': breakHoursRemaining, | ||
| 'isBreakHoursOverAllocated': isBreakHoursOverAllocated, | ||
| 'isOverAllocated': isPositionsOverAllocated or isBreakHoursOverAllocated, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,4 +12,3 @@ class PositionHistory(baseModel): | |
|
|
||
| class Meta: | ||
| indexes = ( (('positionCode', 'revisionDate', 'status'), True), ) | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.