Source code for uw.local.teaching.webui.ta.entitlement

"""TA entitlement-related user interface implementation.

This module implements the Web user interface for managing TA entitlements.
"""

from operator import attrgetter
from itertools import groupby, islice

from ll.xist.ns import html

from uw.web.html.form import render_select, render_hidden, render_radio
from uw.web.html.format import make_table_format, format_return, format_datetime

from uw.web.wsgi.delegate import delegate_get_post
from uw.web.wsgi.form import use_form_param, parse_form_value
from uw.web.wsgi.function import return_html
from uw.web.wsgi.status import HTTPFound

from uw.local.util.format import format_person
from uw.local.termtools import fromCode, render_term_select

from ....util.identity import use_remote_identity

from .ui import format_units

[docs]def format_entitlement_cancellation (e, h): if e.entitled_cancelled is not None: h = html.span (h, style="text-decoration: line-through") return h
[docs]def format_entitlement_description (e): return format_entitlement_cancellation (e, e.entitlement_description)
[docs]def format_entitlement_units (e): return format_entitlement_cancellation (e, format_units (e.entitled_units))
[docs]def format_entitlement_time (cursor, e): if e.entitled_cancelled is None: action = 'Created ' when = e.entitled_created who = e.created_by_person_id else: action = 'Cancelled ' when = e.entitled_cancelled who = e.cancelled_by_person_id result = [ action, format_datetime (when), ] if who is not None: result.extend ([ ' by ', format_person (cursor, who), ]) return result
[docs]def render_entitlements (cursor, unit, term, person, roles, url_prefix=""): '''Renders the TA Entitlement section :param term: Object respresenting a uw term. :param person: A database row representing a particular student. :param url_prefix: :return: a list of HTML elements for the TA entitlement section. The section provides forms for TA scholarship or override entitlements as well as TA assignment history. ''' result = [ html.h3 ('Entitlements'), ] entitlements = cursor.execute_tuples ("select *, ta_student_entitlement_description (tse) as entitlement_description from ta_student_entitlement tse where (unit_code, person_id) = (%(unit_code)s, %(person_id)s) order by entitlement_seq", unit_code=unit.unit_code, person_id=person.person_id) table_columns = [ ('#', attrgetter ('entitlement_seq')), ('Description', format_entitlement_description), ('Units', format_entitlement_units), ('Comment', attrgetter ('entitled_comment')), ('History', lambda r: format_entitlement_time (cursor, r)), ] if 'TAMAN' in roles: table_columns.append (('Actions', lambda r: html.a ('Cancel…', href="entitle?entitlement-seq=%d" % r.entitlement_seq) if r.entitled_cancelled is None else None)) table = make_table_format (*table_columns) (entitlements) total_entitlement = sum (r.entitled_units for r in entitlements if r.entitled_cancelled is None) table.append (html.tr ( html.th ('Total Entitlement:', colspan=2), html.td (format_units (total_entitlement)), html.td (colspan=3), )) result.append (table) if 'TAMAN' in roles: result.append (html.form ( html.p ( 'New entitlement:' ), html.p ( html.label ( render_radio ("type", value="scholarship"), ' Scholarship (starting ', ), render_term_select ("start-term", islice ((term - 3).countFrom (), 9)), ' for ', render_select ("term-count", ((i, i) for i in range (2, 10))), ' terms)', ), html.p ( html.label ( render_radio ("type", value="override"), ' Override', ) ), html.p ( 'Units: ', html.input (type="text", name="units"), ), html.p ( ' Comment: ', html.input (type="text", name="comment"), ' ', ), html.p ( html.input (type="submit", name="!create", value="Create!"), ), method="post", action=url_prefix )) assignments = groupby (cursor.execute_tuples ("select * from ta_position_assignment_plus left join ta_eval using (unit_code, term_id, admin_id, job_code, person_id) left join (select * from ta_rating_eval where rating_code = 'OVERALL') as tre using (eval_id) where (unit_code, person_id) = (%(unit_code)s, %(person_id)s) order by term_id, admin_description, job_description", unit_code=unit.unit_code, term_id=term.code (), person_id=person.person_id), key=attrgetter ('term_id')) table = html.table ( html.tr ( html.th ('Term'), html.th ('Course'), html.th ('Job'), html.th ('Overall Rating'), html.th ('Evaluation'), html.th ('Job Units'), html.th ('Term Units'), ) ) total_units = 0 for term_id, rows in assignments: rows = list (rows) for i, r in enumerate (rows): tr = html.tr () if not i: tr.append (html.td (fromCode (r.term_id).description (), rowspan=len (rows))) tr.append (html.td (r.admin_description)) tr.append (html.td (r.job_description)) tr.append (html.td (r.rating if r.rating else None, style="text-align: center;")) tr.append (html.td (html.a ('View…', href="./eval/%s" % r.eval_id) if r.eval_id else None)) tr.append (html.td (format_units (r.assigned_units))) if not i: term_units = sum (rr.assigned_units for rr in rows) total_units += term_units tr.append (html.td (format_units (term_units), rowspan=len (rows))) table.append (tr) table.append (html.tr ( html.th ('Total Units Assigned:', style="text-align: right;", colspan=5), html.td (format_units (total_units), colspan=2), )) result.extend ([ html.h3 ('Assignment History'), table ]) result.append (html.p ( 'Remaining entitlement: ', format_units (total_entitlement - total_units), )) return result
@use_form_param @use_remote_identity @return_html def entitlement_get_handler (cursor, unit, term, person, form, remote_identity, roles): if "entitlement-seq" in form: result = html.form (html.p ( render_hidden ("entitlement-seq", form.required_field_value ("entitlement-seq")), html.input (type="submit", name="!cancel", value="Cancel!"), ), method="post", action="?" ) return 'Confirm Cancel', result else: result = [format_return ('Term', 'Student List', dot='Student')] result.append (render_entitlements (cursor, unit, term, person, roles)) return 'Student Entitlements for %s, %s (%s)' % (person.surname, person.givennames, person.userid), result @use_form_param @use_remote_identity @return_html def entitlement_post_handler (cursor, unit, term, person, form, remote_identity, roles): if not 'TAMAN' in roles: raise HTTPForbidden () if "!create" in form: # Create an entitlement etype = form.required_field_value ("type") if etype == "scholarship": plan_code = None start_term = parse_form_value (form.optional_field_value ("start-term"), fromCode) if start_term is None: return 'Error: No start term selected', html.p ('Please choose a start term and try again.') term_count = parse_form_value (form.optional_field_value ("term-count"), int) if term_count is None: return 'Error: No term count selected', html.p ('Please choose a term count and try again.') scholarship_dates = '[%s,%s)' % (start_term.startDate (), (start_term + term_count).startDate ()) elif etype == "override": plan_code = None scholarship_dates = None else: return 'Error: No entitlement type selected', html.p ('Please choose an entitlement type and try again.') units = form.optional_field_value ("units") try: units = parse_form_value (units, float) except ValueError as x: return 'Error: Cannot understand number of units', html.p ( '“%s” does not look like a number of units.' % units ) if units is None: return 'Error: No number of units specified', html.p ('Please fill in a number of units and try again.') comment = form.optional_field_value ("comment") cursor.callproc_none ("ta_student_entitlement_create", unit.unit_code, person.person_id, plan_code, scholarship_dates, units, comment, remote_identity.person_id) elif "!cancel" in form: # Cancel an entitlement entitlement_seq = form.required_field_value ("entitlement-seq") cursor.callproc_none ("ta_student_entitlement_cancel", unit.unit_code, person.person_id, entitlement_seq, remote_identity.person_id) raise HTTPFound (".") entitlement_handler = delegate_get_post (entitlement_get_handler, entitlement_post_handler)
[docs]def render_entitlement_schedule (cursor, unit_code): entitlements = cursor.execute_tuples ("select * from ta_plan_entitlement natural join pps_plan where unit_code = %(unit_code)s order by plan_code", unit_code=unit_code) return make_table_format ( ('Plan Code', attrgetter ('plan_code')), ('Plan Transcript Description', attrgetter ('plan_transcript_description')), ('Units', lambda r: format_units (r.entitled_units)), ) (entitlements)