Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 9 additions & 2 deletions app/controllers/admin_routes/allPendingForms.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def allPendingForms(formType):
adjustedFormCounter = FormHistory.select().where((FormHistory.status == 'Pending') & (FormHistory.historyType == 'Labor Adjustment Form')).count()
releaseFormCounter = FormHistory.select().where((FormHistory.status == 'Pending') & (FormHistory.historyType == 'Labor Release Form')).count()
preStudentApprovalCounter = FormHistory.select().where(FormHistory.status == 'Pre-Student Approval',FormHistory.historyType == 'Labor Status Form',FormHistory.overloadForm.is_null()).count()

preStudentApprovalAdjustmentCounter = FormHistory.select().where(FormHistory.status == 'Pre-Student Approval', FormHistory.historyType == 'Labor Adjustment Form',FormHistory.overloadForm.is_null()).count()

if currentUser.isLaborAdmin or currentUser.isLaborDepartmentStudent:
overloadFormCounter = FormHistory.select().where(FormHistory.status.in_(('Pending','Pre-Student Approval')) & (FormHistory.historyType == 'Labor Overload Form')).count()
elif currentUser.isFinancialAidAdmin:
Expand Down Expand Up @@ -98,6 +99,11 @@ def allPendingForms(formType):
historyType = "Labor Status Form"
approvalTarget = ""
pageTitle = "Pre-Student Approval"

elif formType == "preStudentAdjustmentApproval":
historyType = "Labor Adjustment Form"
approvalTarget = ""
pageTitle = "Pre-Student Adjustment Approval"



Expand Down Expand Up @@ -140,6 +146,8 @@ def allPendingForms(formType):
baseQuery = baseQuery.where(FormHistory.status.in_(('Pending','Pre-Student Approval')),FormHistory.historyType == "Labor Overload Form")
elif formType == "preStudentApproval":
baseQuery = baseQuery.where(FormHistory.status == "Pre-Student Approval", FormHistory.historyType == historyType, FormHistory.overloadForm.is_null())
elif formType == "preStudentAdjustmentApproval":
baseQuery = baseQuery.where(FormHistory.status == "Pre-Student Approval", FormHistory.historyType == historyType, FormHistory.overloadForm.is_null())
elif formType in ("pendingLabor","pendingAdjustment","pendingRelease"):
baseQuery = baseQuery.where(FormHistory.status == "Pending", FormHistory.historyType == historyType)

Expand Down Expand Up @@ -187,7 +195,6 @@ def allPendingForms(formType):
print("Error Loading all Pending Forms:", e)
return render_template('errors/500.html'), 500


@admin.route('/admin/pendingForms/download', methods=['POST'])
def downloadAllPendingForms():
searchResult = retrieveFormSearchResult(request.form.get('downloadId'))
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/main_routes/alterLSF.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ def submitAlteredLSF(laborStatusKey):
if formStatus =="Pending" or formStatus == "Pre-Student Approval":
modifyLSF(fieldsChanged, fieldName, lsf, currentUser, host=request.host)
elif formStatus =="Approved":
changedForm = adjustLSF(fieldsChanged, fieldName, lsf, currentUser, host=request.host)
# set studentConfirmation to None so that the student can re-approve the form after changes are made
lsf.studentConfirmation = None
lsf.save()
changedForm = adjustLSF(fieldsChanged, fieldName, lsf, currentUser, host=request.host)
if changedForm:
formHistoryIDs.append(changedForm)
if formStatus == "Approved":
Expand All @@ -172,5 +175,3 @@ def submitAlteredLSF(laborStatusKey):
flash(message, "danger")
print("An error occured during form submission:", e)
return jsonify({"Success": False}), 500


17 changes: 13 additions & 4 deletions app/controllers/main_routes/laborHistory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import datetime
# Source - https://stackoverflow.com/a
# Posted by Joe
# Retrieved 2025-12-04, License - CC BY-SA 3.0

from datetime import date
import re
import types
from fpdf import FPDF
Expand Down Expand Up @@ -62,7 +66,7 @@ def laborhistory(id):

laborStatusFormList = ','.join([str(form.formID.laborStatusFormID) for form in studentForms])
# modify status display for overload and release forms
formIds = [form.formID for form in authorizedForms]
formIds = [form.formID.laborStatusFormID for form in authorizedForms]

relatedForms = (FormHistory.select().where(
(FormHistory.formID.in_(formIds)) &
Expand Down Expand Up @@ -135,7 +139,7 @@ def populateModal(statusKey):
.where(FormHistory.formID == statusKey).order_by(FormHistory.createdDate.desc(), FormHistory.formHistoryID.desc()))
statusForm = LaborStatusForm.get(LaborStatusForm.laborStatusFormID == statusKey)
student = Student.get(Student.ID == statusForm.studentSupervisee)
currentDate = datetime.date.today()
currentDate = date.today()
pendingformType = None
first = True # temp variable to determine if this is the newest form
for form in forms:
Expand Down Expand Up @@ -175,12 +179,16 @@ def populateModal(statusKey):
# Convert the field adjusted value out of camelcase into a more readable format
form.adjustedForm.fieldAdjusted = re.sub(r"(\w)([A-Z])", r"\1 \2", form.adjustedForm.fieldAdjusted).title()

# if form.adjustedForm.fieldAdjusted == "weeklyhours":
# newWeeklyHours = newValue
# oldWeeklyHours = oldValue

# Pending release or adjustment forms need the historyType known
if (form.releaseForm != None or form.adjustedForm != None) and form.status.statusName == "Pending":
pendingformType = form.historyType.historyTypeName

approveLink = f"{request.host_url}studentResponse/confirm?token={statusForm.confirmationToken}"

resp = make_response(render_template('snips/studentHistoryModal.html',
forms = forms,
currentUser = currentUser,
Expand All @@ -189,6 +197,7 @@ def populateModal(statusKey):
pendingformType = pendingformType,
buttonState = buttonState,
approveLink = approveLink,
student = student
))
return (resp)
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/main_routes/laborStatusForm.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,4 @@ def releaseAndRehire():
return jsonify({"Success":True})
except Exception as e:
print("Error on release and rehire: ", e)
return jsonify({"Success": False})
return jsonify({"Success": False})
34 changes: 31 additions & 3 deletions app/controllers/main_routes/studentResponse.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from app.models.laborStatusForm import LaborStatusForm
from app.models.formHistory import FormHistory
from app.models.adjustedForm import AdjustedForm

from app.controllers.main_routes import main_bp

Expand All @@ -21,13 +22,40 @@ def confirm():
form = forms.get()
except DoesNotExist as e:
flash("This contract is invalid or has expired.", "danger")
abort(404)

abort(404)
if form.studentConfirmation is not None: # 3 possible values, True, False, None
verb = "accepted" if form.studentConfirmation else "denied"
flash("This contract has already been " + verb + ".", "danger")
abort(403)

# query adjustedform to get old/new values
lsfId = form.laborStatusFormID
adjustedForms = AdjustedForm.select().where(AdjustedForm.lsfId == lsfId)
adjustedPositionCode = None
if adjustedForms:
for adjustedForm in adjustedForms:
if adjustedForm.fieldAdjusted == "position":
adjustedPositionCode = adjustedForm.newValue


adjustedPositionTitle = None
adjustWLS = None
if adjustedForms and adjustedPositionCode:
adjustedPosition = LaborStatusForm.get(LaborStatusForm.POSN_CODE == adjustedPositionCode)
adjustedPositionTitle = adjustedPosition.POSN_TITLE
adjustWLS = adjustedPosition.WLS

# adjustedWls = None
# if adjustedForms and adjustedPositionCode:
# for adjustedForm in adjustedForms:
# if adjustedForm.fieldAdjusted == "wls":
# adjustedWls = adjustedForm.newValue

# print("###adjustedWls: ", adjustedWls.get())
# if adjustedPositionTitle:
# adjustef_row = adjustedPositionTitle.get_or_none(LaborStatusForm.POSN_CODE == adjustedPositionCode)
# adjustedPositionTitle = adjustef_row.POSN_TITLE if adjustef_row else None

laborDescription = {
"student_name": form.studentSupervisee.FIRST_NAME + " " + form.studentSupervisee.LAST_NAME,
"expiration_date": form.studentExpirationDate,
Expand All @@ -43,7 +71,7 @@ def confirm():
"end_date": form.endDate.strftime('%m/%d/%Y'),
}

return render_template('main/studentEmailConfirmation.html', form=form, laborDescription=laborDescription)
return render_template('main/studentEmailConfirmation.html', form=form, laborDescription=laborDescription, adjustedForms=adjustedForms, adjustedPositionTitle=adjustedPositionTitle, adjustWLS=adjustWLS)

@main_bp.route('/studentResponse/submit', methods=['POST'])
def confirmSubmit():
Expand Down
3 changes: 2 additions & 1 deletion app/logic/alterLSF.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def adjustLSF(fieldsChanged, fieldName, lsf, currentUser, host=None):
adjustedforms = AdjustedForm.create(fieldAdjusted = fieldName,
oldValue = fieldsChanged[fieldName]["oldValue"],
newValue = fieldsChanged[fieldName]["newValue"],
effectiveDate = datetime.strptime(fieldsChanged[fieldName]["date"], "%m/%d/%Y").strftime("%Y-%m-%d"))
effectiveDate = datetime.strptime(fieldsChanged[fieldName]["date"], "%m/%d/%Y").strftime("%Y-%m-%d"),
lsfId = lsf.laborStatusFormID)
historyType = HistoryType.get(HistoryType.historyTypeName == "Labor Adjustment Form")
status = Status.get(Status.statusName == "Pending")
adjustedFormHistory = FormHistory.create(formID = lsf.laborStatusFormID,
Expand Down
2 changes: 2 additions & 0 deletions app/models/adjustedForm.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from app.models import *
from app.models.laborStatusForm import LaborStatusForm

# For each adjustment made to an existing approved LSF, a new entry appears in this table
# Adjustments to pending LSFs do not go on this table! The changes go directly to the LaborStatusForm table
class AdjustedForm(baseModel):
adjustedFormID = PrimaryKeyField()
lsfId = ForeignKeyField(LaborStatusForm, backref='adjusted_forms', column_name='lsfId')
fieldAdjusted = CharField()
oldValue = CharField()
newValue = CharField()
Expand Down
132 changes: 131 additions & 1 deletion app/templates/main/studentEmailConfirmation.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
{% block app_content %}

<h2>Confirm Your Work Contract</h2>

<div style="width:50%; min-width:400px; padding-left: 10px;">
<p class="alert alert-danger">
<b>ACTION REQUIRED</b>
Expand All @@ -27,6 +28,133 @@ <h2>Confirm Your Work Contract</h2>

<p> Please take a moment to read carefully and review the information before submitting your decision.</p>
<h3>Labor Contract Details: </h3>

{% if adjustedForms %}
{% set adjustments = {} %}
{% for a in adjustedForms %}
{% set _ = adjustments.update({ a.fieldAdjusted: (a.oldValue, a.newValue) }) %}
{% endfor %}

<table class="table table-bordered" style="width: 60%; font-size: 1.1em;">
<thead>
<tr>
<th>Field</th>
<th>Old Contract Details</th>
<th>New Contract Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>Student Name</td>
<td>{{ laborDescription.student_name }} ({{ laborDescription.student_id }})</td>
<td>
{% if adjustments.get('studentName') %}
<b>{{ adjustments.get('studentName')[1] }}</b>
{% else %}
{{ laborDescription.student_name }} ({{ laborDescription.student_id }})
{% endif %}
</td>
</tr>

<tr>
<td>Supervisor</td>
<td>{{ laborDescription.supervisor }}</td>
<td>
{% if adjustments.get('supervisor') %}
<b>{{ adjustments.get('supervisor')[1] }}</b>
{% else %}
{{ laborDescription.supervisor }}
{% endif %}
</td>
</tr>

<tr>
<td>Position Code/Title</td>
<td>{{ laborDescription.position_code_title }}</td>
<td>
{% if adjustments.get('position') %}
<b>{{ adjustments.get('position')[1] }}</b>, <b>{{ adjustedPositionTitle }}</b>
{% else %}
{{ laborDescription.position_code_title }}
{% endif %}
</td>
</tr>

<tr>
<td>WLS Level</td>
<td>{{ laborDescription.wls }}</td>
<td>
<b>{{ adjustWLS }}</b>
</td>
</tr>

<tr>
<td>Department Name</td>
<td>{{ laborDescription.department }}</td>
<td>
{% if adjustments.get('department') %}
<b>{{ adjustments.get('department')[1] }}</b>
{% else %}
{{ laborDescription.department }}
{% endif %}
</td>
</tr>

<tr>
<td>Position Type</td>
<td>{{ laborDescription.jobType }}</td>
<td>
{% if adjustments.get('jobType') %}
<b>{{ adjustments.get('jobType')[1] }}</b>
{% else %}
{{ laborDescription.jobType }}
{% endif %}
</td>
</tr>

<tr>
<td>{{ "Total Contracted Hours" if laborDescription.term.isBreak else "Hours per Week" }}</td>
<td>{{ laborDescription.hours_per_week }}</td>
<td>
{% if adjustments.get('weeklyHours') %}
<b>{{ adjustments.get('weeklyHours')[1] }}</b>
{% else %}
{{ laborDescription.hours_per_week }}
{% endif %}
</td>
</tr>

<tr>
<td>Start Date</td>
<td>{{ laborDescription.start_date }}</td>
<td>
{% if adjustments.get('startDate') %}
<b>{{ adjustments.get('startDate')[1] }}</b>
{% else %}
{{ laborDescription.start_date }}
{% endif %}
</td>
</tr>

<tr>
<td>End Date</td>
<td>{{ laborDescription.end_date }}</td>
<td>
{% if adjustments.get('endDate') %}
<b>{{ adjustments.get('endDate')[1] }}</b>
{% else %}
{{ laborDescription.end_date }}
{% endif %}
</td>
</tr>
</tbody>
</table>




{% else %}
{# --- Your current view stays EXACTLY the same here --- #}
<div style="margin:10px;font-size:1.2em">
<div class="labor-status-info">
<p><strong>Student Name:</strong> {{ laborDescription.student_name }} ({{ laborDescription.student_id }})</p>
Expand All @@ -36,11 +164,13 @@ <h3>Labor Contract Details: </h3>
<p><strong>Department Name:</strong> {{ laborDescription.department }}</p>
<p><strong>Position Type:</strong> {{ laborDescription.jobType }}</p>
{% set hoursDescription = "Total Contracted Hours" if laborDescription.term.isBreak else "Hours per Week" %}
<p><strong>{{ hoursDescription}}:</strong> {{ laborDescription.hours_per_week }}</p>
<p><strong>{{ hoursDescription }}:</strong> {{ laborDescription.hours_per_week }}</p>
<p><strong>Start Date:</strong> {{ laborDescription.start_date }}</p>
<p><strong>End Date:</strong> {{ laborDescription.end_date }}</p>
</div>
</div>
{% endif %}


<div class="form-group">
{% if laborDescription.jobType == "Primary" %}
Expand Down
1 change: 1 addition & 0 deletions app/templates/snips/studentHistoryModal.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<dt class="col-sm-3">Job Type (Hours)</dt>
<dd class="col-sm-9" id="laborJobType">{{statusForm.jobType}}
({% if statusForm.weeklyHours == None %}{{statusForm.contractHours}}{% else %}{{statusForm.weeklyHours}}{% endif %})
| New Weekly Hours: {{newWeeklyHours}}
</dd>

<dt class="col-sm-3">Position (WLS)</dt>
Expand Down
18 changes: 17 additions & 1 deletion database/prod-backup.sql

Large diffs are not rendered by default.