def singleGrades2db(schoolyear, pid, klass, term, date, rtype, grades): """Add or update GRADES table entry for a single pupil and date. <term> is the date of the entry, which may already exist: the TERM field. <date> is the new date, which may be the same as <term>, but can also indicate a change, in which case also the TERM field will be changed. <rtype> is the report type. <grades> is a mapping {sid -> grade}. """ db = DB(schoolyear) gstring = map2grades(grades) db.updateOrAdd('GRADES', { 'KLASS': klass.klass, 'STREAM': klass.stream, 'PID': pid, 'TERM': term if term.isdigit() else date, 'REPORT_TYPE': rtype, 'DATE_D': date, 'GRADES': gstring }, TERM=term, PID=pid )
def updateGradeReport(schoolyear, pid, term, date, rtype): """Update grade database when building reports. <pid> (pupil-id) and <term> (term or extra date) are used to key the entry in the GRADES table. For term reports, update only DATE_D and REPORT_TYPE fields. This is not used for "extra" reports. """ db = DB(schoolyear) termn = int(term) # check that term (not date) is given try: # Update term. This only works if there is already an entry. db.updateOrAdd ('GRADES', {'DATE_D': date, 'REPORT_TYPE': rtype}, update_only=True, PID=pid, TERM=term ) except UpdateError: REPORT.Bug("No entry in db, table GRADES for: PID={pid}, TERM={term}", pid=pid, term=term)
def grades2db(schoolyear, gtable, term=None): """Enter the grades from the given table into the database. <schoolyear> is checked against the value in the info part of the table (gtable.info['SCHOOLYEAR']). <term>, if given, is only used as a check against the value in the info part of the table (gtable.info['TERM']). """ # Check school-year try: y = gtable.info.get('SCHOOLYEAR', '–––') yn = int(y) except ValueError: REPORT.Fail(_INVALID_YEAR, val=y) if yn != schoolyear: REPORT.Fail(_WRONG_YEAR, year=y) # Check term rtag = gtable.info.get('TERM', '–––') if term: if term != rtag: REPORT.Fail(_WRONG_TERM, term=term, termf=rtag) # Check klass klass = Klass(gtable.info.get('CLASS', '–––')) # Check validity pupils = Pupils(schoolyear) try: plist = pupils.classPupils(klass) if not plist: raise ValueError except: REPORT.Fail(_INVALID_KLASS, klass=klass) # Filter the relevant pids p2grades = {} p2stream = {} for pdata in plist: pid = pdata['PID'] try: p2grades[pid] = gtable.pop(pid) except KeyError: # The table may include just a subset of the pupils continue p2stream[pid] = pdata['STREAM'] # Anything left unhandled in <gtable>? for pid in gtable: REPORT.Error(_UNKNOWN_PUPIL, pid=pid) #TODO: Sanitize input ... only valid grades? # Now enter to database if p2grades: db = DB(schoolyear) for pid, grades in p2grades.items(): gstring = map2grades(grades) db.updateOrAdd('GRADES', { 'KLASS': klass.klass, 'STREAM': p2stream[pid], 'PID': pid, 'TERM': rtag, 'REPORT_TYPE': None, 'DATE_D': None, 'GRADES': gstring }, TERM=rtag, PID=pid ) REPORT.Info(_NEWGRADES, n=len(p2grades), klass=klass, year=schoolyear, term=rtag) else: REPORT.Warn(_NOPUPILS)