Changeset 16827 for main/waeup.kofa


Ignore:
Timestamp:
22 Feb 2022, 12:48:36 (3 years ago)
Author:
Henrik Bettermann
Message:

Add exporters for previous study course data.

Location:
main/waeup.kofa/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/CHANGES.txt

    r16819 r16827  
    441.7.2.dev0 (unreleased)
    55=======================
     6
     7* Add exporters for previous study course data.
    68
    79* Enable import of student history.
  • main/waeup.kofa/trunk/src/waeup/kofa/students/export.py

    r16812 r16827  
    4141    return stud_filter.query()
    4242
    43 def get_studycourses(students):
     43def get_studycourses(students, previous=0):
    4444    """Get studycourses of `students`.
    4545    """
    46     return [x.get('studycourse', None) for x in students
    47             if x is not None]
    48 
    49 def get_levels(students, **kw):
     46    studycourse = 'studycourse'
     47    if previous == 1:
     48        studycourse = 'studycourse_1'
     49    elif previous == 2:
     50        studycourse = 'studycourse_2'
     51    for x in students:
     52        if x.get(studycourse, None) is None:
     53            continue
     54        yield x.get(studycourse, None)
     55
     56def get_levels(students, previous=0, **kw):
    5057    """Get all studylevels of `students`.
    5158    """
    5259    levels = []
    5360    level_session = kw.get('level_session', None)
    54     for course in get_studycourses(students):
     61    for course in get_studycourses(students, previous):
    5562        for level in course.values():
    5663            if level_session not in ('all', None) and \
     
    6067    return levels
    6168
    62 def get_tickets(students, **kw):
     69def get_tickets(students, previous=0, **kw):
    6370    """Get course tickets of `students`.
    6471    If code is passed through, filter course tickets
     
    7885    ct_semester = kw.get('ct_semester', None)
    7986    if code is None:
    80         for level_obj in get_levels(students, **kw):
     87        for level_obj in get_levels(students, previous, **kw):
    8188            for ticket in level_obj.values():
    8289                if ct_level not in ('all', None):
     
    95102                tickets.append(ticket)
    96103    else:
    97         for level_obj in get_levels(students, **kw):
     104        for level_obj in get_levels(students, previous, **kw):
    98105            for ticket in level_obj.values():
    99106                if ticket.code != code:
     
    112119    return tickets
    113120
    114 def get_tickets_for_lecturer(students, **kw):
     121def get_tickets_for_lecturer(students, previous=0, **kw):
    115122    """Get course tickets of `students`.
    116123    Filter course tickets which belong to this course code and
     
    122129    level_session = kw.get('session', None)
    123130    level = kw.get('level', None)
    124     for level_obj in get_levels(students, **kw):
     131    for level_obj in get_levels(students, previous, **kw):
    125132        for ticket in level_obj.values():
    126133            if ticket.code != code:
     
    428435            value, name, context=context)
    429436
     437class FirstStudentStudyCourseExporter(StudentStudyCourseExporter):
     438    """The First Student Study Course Exporter exports the first
     439    study course if student was transferred.
     440    """
     441    grok.name('studentstudycourses_1')
     442
     443    title = _(u'First Student Study Courses (Data Backup)')
     444
     445    def filter_func(self, x, **kw):
     446        return get_studycourses(x, 1)
     447
     448class SecondStudentStudyCourseExporter(StudentStudyCourseExporter):
     449    """The Second Student Study Course Exporter exports the second
     450    study course if student was transferred twice.
     451    """
     452    grok.name('studentstudycourses_2')
     453
     454    title = _(u'Second Student Study Courses (Data Backup)')
     455
     456    def filter_func(self, x, **kw):
     457        return get_studycourses(x, 2)
    430458
    431459class StudentStudyLevelExporter(grok.GlobalUtility, StudentExporterBase):
     
    456484            value, name, context=context)
    457485
     486class FirstStudentStudyLevelExporter(StudentStudyLevelExporter):
     487    """The First Student Study Level Exporter exports study levels of the
     488    first study course if the student was transferred.
     489    """
     490    grok.name('studentstudylevels_1')
     491
     492    title = _(u'First Course Student Study Levels (Data Backup)')
     493
     494    def filter_func(self, x, **kw):
     495        return get_levels(x, 1, **kw)
     496
     497class SecondStudentStudyLevelExporter(StudentStudyLevelExporter):
     498    """The Second Student Study Level Exporter exports study levels of the
     499    second tudy course if the student was transferred twice.
     500    """
     501    grok.name('studentstudylevels_2')
     502
     503    title = _(u'Second Course Student Study Levels (Data Backup)')
     504
     505    def filter_func(self, x, **kw):
     506        return get_levels(x, 2, **kw)
     507
    458508class CourseTicketExporter(grok.GlobalUtility, StudentExporterBase):
    459509    """The Course Ticket Exporter exports course tickets. Usually,
     
    490540            CourseTicketExporter, self).mangle_value(
    491541            value, name, context=context)
     542
     543class FirstCourseTicketExporter(CourseTicketExporter):
     544    """The First Course Ticket Exporter exports course tickets of
     545    first study courses if the student was transferred.
     546    """
     547    grok.name('coursetickets_1')
     548
     549    title = _(u'First Course Course Tickets (Data Backup)')
     550
     551    def filter_func(self, x, **kw):
     552        return get_tickets(x, 1, **kw)
     553
     554class SecondCourseTicketExporter(CourseTicketExporter):
     555    """The Second Course Ticket Exporter exports course tickets of
     556    second study courses if the student was transferred twice.
     557    """
     558    grok.name('coursetickets_2')
     559
     560    title = _(u'Second Course Course Tickets (Data Backup)')
     561
     562    def filter_func(self, x, **kw):
     563        return get_tickets(x, 2, **kw)
    492564
    493565class StudentPaymentExporter(grok.GlobalUtility, StudentExporterBase):
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py

    r16812 r16827  
    2121import datetime
    2222from cStringIO import StringIO
    23 from zope.component import queryUtility, getUtility
     23from zope.component import queryUtility, getUtility, createObject
    2424from zope.event import notify
    2525from zope.interface.verify import verifyObject, verifyClass
     
    3030from waeup.kofa.university.certificate import CertificateCourse
    3131from waeup.kofa.students.export import (
    32     StudentExporter, StudentStudyCourseExporter, StudentStudyLevelExporter,
    33     CourseTicketExporter, StudentPaymentExporter, BedTicketExporter,
     32    StudentExporter,
     33    StudentStudyCourseExporter,
     34    FirstStudentStudyCourseExporter,
     35    SecondStudentStudyCourseExporter,
     36    StudentStudyLevelExporter,
     37    FirstStudentStudyLevelExporter,
     38    SecondStudentStudyLevelExporter,
     39    CourseTicketExporter,
     40    FirstCourseTicketExporter,
     41    SecondCourseTicketExporter,
     42    StudentPaymentExporter, BedTicketExporter,
    3443    SchoolFeePaymentsOverviewExporter, StudyLevelsOverviewExporter,
    3544    ComboCardDataExporter, DataForBursaryExporter,
     
    516525        return
    517526
     527class PreviousStudyCourseExporterTests(StudentImportExportSetup):
     528
     529    layer = FunctionalLayer
     530
     531    def setUp(self):
     532        super(PreviousStudyCourseExporterTests, self).setUp()
     533        self.setup_for_export()
     534        self.certificate2 = createObject('waeup.Certificate')
     535        self.certificate2.code = 'CERT2'
     536        self.certificate2.application_category = 'basic'
     537        self.certificate2.start_level = 200
     538        self.certificate2.end_level = 500
     539        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
     540            self.certificate2)
     541        return
     542
     543    def test_export_studycourses(self):
     544        self.setup_student(self.student)
     545        exporter = FirstStudentStudyCourseExporter()
     546        exporter.export_all(self.app, self.outfile)
     547        result = open(self.outfile, 'rb').read()
     548        self.assertEqual(
     549            result,
     550            'certificate,current_level,current_session,current_verdict,'
     551            'entry_mode,entry_session,previous_verdict,student_id\r\n'
     552            )
     553        error = self.student.transfer(self.certificate2, current_session=2013)
     554        self.assertTrue(error == None)
     555        exporter.export_all(self.app, self.outfile)
     556        result = open(self.outfile, 'rb').read()
     557        self.assertEqual(
     558            result,
     559            'certificate,current_level,current_session,current_verdict,'
     560            'entry_mode,entry_session,previous_verdict,student_id\r\n'
     561            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n')
     562        error = self.student.transfer(self.certificate,
     563                                      current_session=2014,
     564                                      current_level=300)
     565        self.assertTrue(error == None)
     566        exporter = SecondStudentStudyCourseExporter()
     567        exporter.export_all(self.app, self.outfile)
     568        result = open(self.outfile, 'rb').read()
     569        self.assertEqual(
     570            result,
     571            'certificate,current_level,current_session,current_verdict,'
     572            'entry_mode,entry_session,previous_verdict,student_id\r\n'
     573            'CERT2,,2013,,transfer,2010,,A111111\r\n')
     574        exporter = StudentStudyCourseExporter()
     575        exporter.export_all(self.app, self.outfile)
     576        result = open(self.outfile, 'rb').read()
     577        self.assertEqual(
     578            result,
     579            'certificate,current_level,current_session,current_verdict,'
     580            'entry_mode,entry_session,previous_verdict,student_id\r\n'
     581            'CERT1,300,2014,,transfer,2010,,A111111\r\n')
     582        return
     583
     584    def test_export_studylevels(self):
     585        self.setup_student(self.student)
     586        exporter = FirstStudentStudyLevelExporter()
     587        exporter.export_all(self.app, self.outfile)
     588        result = open(self.outfile, 'rb').read()
     589        self.assertEqual(
     590            result,
     591            'gpa,level,level_session,level_verdict,total_credits,'
     592            'transcript_remark,validated_by,validation_date,student_id,'
     593            'number_of_tickets,certcode\r\n'
     594            )
     595        error = self.student.transfer(self.certificate2, current_session=2013)
     596        self.assertTrue(error == None)
     597        exporter.export_all(self.app, self.outfile)
     598        result = open(self.outfile, 'rb').read()
     599        self.assertEqual(
     600            result,
     601            'gpa,level,level_session,level_verdict,total_credits,'
     602            'transcript_remark,validated_by,validation_date,student_id,'
     603            'number_of_tickets,certcode\r\n'
     604            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n' )
     605        study_level = StudentStudyLevel()
     606        study_level.level_session = 2015
     607        study_level.level_verdict = "C"
     608        study_level.level = 400
     609        self.student['studycourse'].addStudentStudyLevel(
     610            self.certificate2, study_level)
     611        error = self.student.transfer(self.certificate,
     612                                      current_session=2014,
     613                                      current_level=300)
     614        self.assertTrue(error == None)
     615        exporter = SecondStudentStudyLevelExporter()
     616        exporter.export_all(self.app, self.outfile)
     617        result = open(self.outfile, 'rb').read()
     618        self.assertEqual(
     619            result,
     620            'gpa,level,level_session,level_verdict,total_credits,'
     621            'transcript_remark,validated_by,validation_date,student_id,'
     622            'number_of_tickets,certcode\r\n'
     623            '0.00,400,2015,C,0,,,,A111111,0,CERT2\r\n')
     624        exporter = StudentStudyLevelExporter()
     625        exporter.export_all(self.app, self.outfile)
     626        result = open(self.outfile, 'rb').read()
     627        self.assertEqual(
     628            result,
     629            'gpa,level,level_session,level_verdict,total_credits,'
     630            'transcript_remark,validated_by,validation_date,student_id,'
     631            'number_of_tickets,certcode\r\n')
     632        return
     633
     634    def test_export_coursetickets(self):
     635        self.setup_student(self.student)
     636        exporter = FirstCourseTicketExporter()
     637        exporter.export_all(self.app, self.outfile)
     638        result = open(self.outfile, 'rb').read()
     639        self.assertEqual(
     640            result,
     641            'automatic,carry_over,code,course_category,credits,dcode,'
     642            'fcode,level,level_session,mandatory,outstanding,passmark,'
     643            'score,semester,ticket_session,title,student_id,certcode,'
     644            'display_fullname\r\n'
     645            )
     646        error = self.student.transfer(self.certificate2, current_session=2013)
     647        self.assertTrue(error == None)
     648        exporter.export_all(self.app, self.outfile)
     649        result = open(self.outfile, 'rb').read()
     650        self.assertEqual(
     651            result,
     652            'automatic,carry_over,code,course_category,credits,dcode,'
     653            'fcode,level,level_session,mandatory,outstanding,passmark,'
     654            'score,semester,ticket_session,title,student_id,certcode,'
     655            'display_fullname\r\n'
     656            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,'
     657            'A111111,CERT1,Anna M. Tester\r\n')
     658        study_level = StudentStudyLevel()
     659        study_level.level_session = 2015
     660        study_level.level_verdict = "C"
     661        study_level.level = 400
     662        self.student['studycourse'].addStudentStudyLevel(
     663            self.certificate2, study_level)
     664        ticket = CourseTicket()
     665        ticket.automatic = True
     666        ticket.carry_over = True
     667        ticket.code = u'CRS9'
     668        ticket.title = u'Course 9'
     669        ticket.fcode = u'FAC9'
     670        ticket.dcode = u'DEP9'
     671        ticket.credits = 150
     672        ticket.passmark = 100
     673        ticket.semester = 2
     674        study_level[ticket.code] = ticket
     675        error = self.student.transfer(self.certificate,
     676                                      current_session=2014,
     677                                      current_level=300)
     678        self.assertTrue(error == None)
     679        exporter = SecondCourseTicketExporter()
     680        exporter.export_all(self.app, self.outfile)
     681        result = open(self.outfile, 'rb').read()
     682        self.assertEqual(
     683            result,
     684            'automatic,carry_over,code,course_category,credits,dcode,'
     685            'fcode,level,level_session,mandatory,outstanding,passmark,'
     686            'score,semester,ticket_session,title,student_id,certcode,'
     687            'display_fullname\r\n1,1,CRS9,,150,DEP9,FAC9,400,2015,0,0,'
     688            '100,,2,,Course 9,A111111,CERT2,Anna M. Tester\r\n')
     689        exporter = CourseTicketExporter()
     690        exporter.export_all(self.app, self.outfile)
     691        result = open(self.outfile, 'rb').read()
     692        self.assertEqual(
     693            result,
     694            'automatic,carry_over,code,course_category,credits,dcode,'
     695            'fcode,level,level_session,mandatory,outstanding,passmark,'
     696            'score,semester,ticket_session,title,student_id,certcode,'
     697            'display_fullname\r\n'
     698            )
     699        return
    518700
    519701class StudentStudyLevelExporterTest(StudentImportExportSetup):
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_student.py

    r15416 r16827  
    160160        super(StudentRemovalTests, self).setUp()
    161161        self.setup_for_export()
     162        self.certificate2 = createObject('waeup.Certificate')
     163        self.certificate2.code = 'CERT2'
     164        self.certificate2.application_category = 'basic'
     165        self.certificate2.start_level = 200
     166        self.certificate2.end_level = 500
     167        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
     168            self.certificate2)
    162169        return
    163170
     
    190197            IStudentsUtils).STUDENT_BACKUP_EXPORTER_NAMES
    191198        for name in STUDENT_BACKUP_EXPORTER_NAMES:
     199            if name[-2:-1] == '_':
     200                continue
    192201            csv_path = os.path.join(del_dir, '%s.csv' % name)
    193202            self.assertTrue(os.path.isfile(csv_path))
     
    218227            IStudentsUtils).STUDENT_BACKUP_EXPORTER_NAMES
    219228        for name in STUDENT_BACKUP_EXPORTER_NAMES:
     229            if name[-2:-1] == '_':
     230                continue
    220231            csv_path = os.path.join(del_dir, '%s.csv' % name)
    221232            self.assertTrue(os.path.isfile(csv_path))
     
    223234            # We expect 3 lines output including a linebreak at end of file.
    224235            self.assertEqual(len(contents), 3)
     236        return
     237
     238    def test_backup_single_graduated_transferred_data(self):
     239        del_dir = self.app['datacenter'].graduated_path
     240        # when a single graduated student is removed, the data is backed up
     241        # somewhere else including previous study courses
     242        self.setup_student(self.student)
     243        error = self.student.transfer(self.certificate2, current_session=2013)
     244        self.assertTrue(error == None)
     245        IWorkflowState(self.student).setState('graduated')
     246        handle_student_removed(self.student, None)
     247        # The previous study course data were put into CSV files
     248        name = 'studentstudycourses_1'
     249        csv_path = os.path.join(del_dir, '%s.csv' % name)
     250        self.assertTrue(os.path.isfile(csv_path))
     251        contents = open(csv_path, 'rb').read().split('\r\n')
     252        # We expect 3 lines output including a linebreak at end of file.
     253        self.assertEqual(len(contents), 3)
     254        name = 'studentstudycourses_2'
     255        csv_path = os.path.join(del_dir, '%s.csv' % name)
     256        self.assertTrue(os.path.isfile(csv_path))
     257        contents = open(csv_path, 'rb').read().split('\r\n')
     258        # We expect only 2 lines output including a linebreak at end of file.
     259        self.assertEqual(len(contents), 2)
     260        name = 'studentstudylevels_1'
     261        csv_path = os.path.join(del_dir, '%s.csv' % name)
     262        self.assertTrue(os.path.isfile(csv_path))
     263        contents = open(csv_path, 'rb').read().split('\r\n')
     264        # We expect 3 lines output including a linebreak at end of file.
     265        self.assertEqual(len(contents), 3)
     266        name = 'coursetickets_1'
     267        csv_path = os.path.join(del_dir, '%s.csv' % name)
     268        self.assertTrue(os.path.isfile(csv_path))
     269        contents = open(csv_path, 'rb').read().split('\r\n')
     270        # We expect 3 lines output including a linebreak at end of file.
     271        self.assertEqual(len(contents), 3)
    225272        return
    226273
  • main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py

    r16777 r16827  
    12581258            'students',
    12591259            'studentstudycourses',
     1260            #'studentstudycourses_1',
     1261            #'studentstudycourses_2',
    12601262            'studentstudylevels',
     1263            #'studentstudylevels_1',
     1264            #'studentstudylevels_2',
    12611265            'coursetickets',
     1266            #'coursetickets_1',
     1267            #'coursetickets_2',
    12621268            'studentpayments',
    12631269            'bedtickets',
     
    12771283    #: A tuple containing all exporter names needed for backing
    12781284    #: up student data
    1279     STUDENT_BACKUP_EXPORTER_NAMES = ('students', 'studentstudycourses',
    1280             'studentstudylevels', 'coursetickets',
    1281             'studentpayments', 'bedtickets')
     1285    STUDENT_BACKUP_EXPORTER_NAMES = (
     1286            'students',
     1287            'studentstudycourses',
     1288            'studentstudycourses_1',
     1289            'studentstudycourses_2',
     1290            'studentstudylevels',
     1291            'studentstudylevels_1',
     1292            'studentstudylevels_2',
     1293            'coursetickets',
     1294            'coursetickets_1',
     1295            'coursetickets_2',
     1296            'studentpayments',
     1297            'bedtickets')
    12821298
    12831299    # Maximum size of upload files in kB
Note: See TracChangeset for help on using the changeset viewer.