diff --git a/app/controllers/main_routes/departmentPortal.py b/app/controllers/main_routes/departmentPortal.py index 5d69fdd7..65d27443 100644 --- a/app/controllers/main_routes/departmentPortal.py +++ b/app/controllers/main_routes/departmentPortal.py @@ -1,11 +1,11 @@ from datetime import datetime -from flask import g, render_template, request, send_file +from flask import flash, g, render_template, request, send_file from peewee import DoesNotExist from app.controllers.main_routes import main_bp from app.logic.download import makePositionDescriptionPDF -from app.logic.getPositions import getPosition, getPositions, getPositionDescriptionSections +from app.logic.getPositions import createPositionRevision, getPosition, getPositions, getPositionDescriptionSections from app.models.department import Department from app.models.positionHistory import PositionHistory from app.models.supervisorDepartment import SupervisorDepartment @@ -67,6 +67,39 @@ def downloadPositionDescription(org, account, positionCode): +@main_bp.route('/department///positions//revise', methods=['GET', 'POST']) +def revisePosition(org, account, positionCode): + try: + dept = Department.get(Department.ORG == org, Department.ACCOUNT == account) + except (NameError, DoesNotExist): + return render_template('errors/404.html'), 404 + + position = getPosition(dept, positionCode) + + if not position: + return render_template('errors/404.html'), 404 + + if request.method == 'POST': + position = createPositionRevision( + position, + g.currentUser.fullName, + request.form.get('positionTitle'), + request.form.get('wls'), + request.form.getlist('sectionTitle[]'), + request.form.getlist('sectionContent[]') + ) + flash('Position revision saved.', 'success') + + sections = getPositionDescriptionSections(position) + + return render_template( + 'main/revisepositionpage.html', + department=dept, + position=position, + sections=sections + ) + + @main_bp.route('/department///positions', methods=['GET']) def managePositions(org, account): try: @@ -87,4 +120,4 @@ def managePositions(org, account): department = dept, department_name = dept.DEPT_NAME, positions = positions - ) + ) \ No newline at end of file diff --git a/app/logic/getPositions.py b/app/logic/getPositions.py index 7410d7f7..3d3bcd67 100644 --- a/app/logic/getPositions.py +++ b/app/logic/getPositions.py @@ -1,5 +1,6 @@ from app.models.positionHistory import PositionHistory from app.models.positionDescriptionSection import PositionDescriptionSection +from datetime import date def getActivePositions(dept): """ @@ -52,7 +53,32 @@ def getPositionDescriptionSections(position): positionDescriptionSections = list(PositionDescriptionSection.select() .where(PositionDescriptionSection.position == position) .order_by(PositionDescriptionSection.order.asc())) - + return positionDescriptionSections +def createPositionRevision(position, revisedBy, positionTitle, wls, sectionTitles, sectionContents): + """ + Creates a new pending (Requested) revision of a position, copying forward its + department and position code, and replaces its description sections with the + given titles/contents. Returns the newly created PositionHistory row. + """ + newPosition = PositionHistory.create( + positionTitle=positionTitle, + positionCode=position.positionCode, + department=position.department, + status="Requested", + wls=wls, + revisionDate=date.today(), + revisedBy=revisedBy + ) + + for order, (sectionTitle, sectionContent) in enumerate(zip(sectionTitles, sectionContents)): + PositionDescriptionSection.create( + position=newPosition, + sectionTitle=sectionTitle, + sectionContent=sectionContent, + order=order + ) + + return newPosition diff --git a/app/static/css/revisepositionpage.css b/app/static/css/revisepositionpage.css new file mode 100644 index 00000000..1d642d2d --- /dev/null +++ b/app/static/css/revisepositionpage.css @@ -0,0 +1,12 @@ +/* Revise position form - styles not covered by Bootstrap */ +.description-section-row { + background: #fff; + border: 1px solid #e6e6e6; + padding: 1rem; + border-radius: 6px; + margin-bottom: 1rem; +} + +.revise-actions { + margin-top: 1.5rem; +} diff --git a/app/static/js/revisepositionpage.js b/app/static/js/revisepositionpage.js new file mode 100644 index 00000000..7ec65ffb --- /dev/null +++ b/app/static/js/revisepositionpage.js @@ -0,0 +1,14 @@ +$(document).ready(function () { + var sectionsContainer = document.getElementById('sectionsContainer'); + var sectionRowTemplate = document.getElementById('sectionRowTemplate'); + + document.getElementById('addSectionBtn').addEventListener('click', function () { + sectionsContainer.appendChild(sectionRowTemplate.content.cloneNode(true)); + }); + + sectionsContainer.addEventListener('click', function (event) { + if (event.target.classList.contains('remove-section-btn')) { + event.target.closest('.description-section-row').remove(); + } + }); +}); diff --git a/app/templates/main/managePositions.html b/app/templates/main/managePositions.html index 81b139d4..72f1738c 100644 --- a/app/templates/main/managePositions.html +++ b/app/templates/main/managePositions.html @@ -33,9 +33,8 @@

{{ department_name }} Positions

{{ position.wls }} {{ position.revisionDate }} - View - + View + Revise Position {% endfor %} diff --git a/app/templates/main/revisepositionpage.html b/app/templates/main/revisepositionpage.html new file mode 100644 index 00000000..fa1f2751 --- /dev/null +++ b/app/templates/main/revisepositionpage.html @@ -0,0 +1,105 @@ +{% extends "base.html" %} + +{% block scripts %} + {{ super() }} + + + +{% endblock %} + +{% block app_content %} +
+

Revise {{ position.positionTitle }}

+
+ +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+

{{ position.positionCode }}

+
+
+ +
+ +
+ +
+
+ +
+ +
+

{{ position.revisionDate }}

+
+
+ +
+ +
+

{{ position.revisedBy }}

+
+
+
+ +

Description

+
+ {%- for section in sections %} +
+
+ + +
+
+ + +
+ +
+ {%- endfor %} +
+ + + +
+
+ + Cancel + + +
+
+ +
+ +
+
+
+ + +{% endblock %}