Changeset 9420 for main/waeup.kofa/trunk/src/waeup/kofa/students
- Timestamp:
- 25 Oct 2012, 21:52:10 (12 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa/students
- Files:
-
- 2 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py
r9418 r9420 43 43 IStudent, IStudentStudyCourse, 44 44 IStudentUpdateByRegNo, IStudentUpdateByMatricNo, 45 IStudentStudyLevel, ICourseTicket ,45 IStudentStudyLevel, ICourseTicketImport, 46 46 IStudentOnlinePayment, IStudentVerdictUpdate) 47 47 from waeup.kofa.students.workflow import ( … … 305 305 grok.baseclass() 306 306 307 # additional available 307 # additional available fields 308 308 # beside 'student_id', 'reg_number' and 'matric_number' 309 309 additional_fields = [] … … 541 541 542 542 name = u'CourseTicket Processor' 543 iface = ICourseTicket 543 iface = ICourseTicketImport 544 544 factory_name = 'waeup.CourseTicket' 545 545 … … 547 547 additional_fields = ['level', 'code'] 548 548 additional_headers = ['level', 'code'] 549 550 @property 551 def available_fields(self): 552 fields = [ 553 'student_id','reg_number','matric_number', 554 'mandatory', 'score', 'carry_over', 'automatic', 555 'level_session' 556 ] + self.additional_fields 557 return sorted(fields) 549 558 550 559 def getParent(self, row, site): … … 579 588 obj.dcode = entries[0].__parent__.__parent__.code 580 589 obj.title = entries[0].title 581 if getattr(obj, 'credits', None) is None:582 583 if getattr(obj, 'passmark', None) is None:584 590 #if getattr(obj, 'credits', None) is None: 591 obj.credits = entries[0].credits 592 #if getattr(obj, 'passmark', None) is None: 593 obj.passmark = entries[0].passmark 585 594 obj.semester = entries[0].semester 586 595 parent[row['code']] = obj … … 602 611 errs, inv_errs, conv_dict = super( 603 612 CourseTicketProcessor, self).checkConversion(row, mode=mode) 604 605 # We have to check if course really exists. 613 if mode == 'remove': 614 return errs, inv_errs, conv_dict 615 # In update and create mode we have to check if course really exists. 606 616 # This is not done by the converter. 607 617 catalog = getUtility(ICatalog, name='courses_catalog') … … 610 620 errs.append(('code','non-existent')) 611 621 return errs, inv_errs, conv_dict 622 # If level_session is provided in row we have to check if 623 # the parent studylevel exists and if its level_session 624 # attribute corresponds with the expected value in row. 625 level_session = row.get('level_session', IGNORE_MARKER) 626 if level_session not in (IGNORE_MARKER, ''): 627 site = grok.getSite() 628 studylevel = self.getParent(row, site) 629 if studylevel is not None: 630 if studylevel.level_session != level_session: 631 errs.append(('level_session','does not match %s' 632 % studylevel.level_session)) 633 else: 634 errs.append(('level','does not exist')) 612 635 return errs, inv_errs, conv_dict 613 636 … … 793 816 notify(grok.ObjectModifiedEvent(obj.__parent__)) 794 817 return 795 796 class CourseResultProcessor(CourseTicketProcessor):797 """A special batch processor for course results objects.798 799 Import course results, compares session and creates study level.800 """801 grok.implements(IBatchProcessor)802 grok.provides(IBatchProcessor)803 grok.context(Interface)804 util_name = 'courseresultprocessor'805 grok.name(util_name)806 807 name = u'Course Result Processor (special processor)'808 iface = ICourseTicket809 factory_name = 'waeup.CourseTicket'810 811 location_fields = []812 additional_fields = ['level', 'code']813 additional_headers = ['level', 'code']814 815 def getParent(self, row, site):816 student = self._getStudent(row, site)817 if student is None:818 return None819 return student['studycourse'].get(row['level'])820 821 def getEntry(self, row, site):822 level = self.getParent(row, site)823 if level is None:824 return None825 return level.get(row['code'])826 827 def updateEntry(self, obj, row, site):828 """Update obj to the values given in row.829 """830 items_changed = super(CourseTicketProcessor, self).updateEntry(831 obj, row, site)832 parent = self.getParent(row, site)833 student = self.getParent(row, site).__parent__.__parent__834 student.__parent__.logger.info(835 '%s - Course ticket in %s updated: %s'836 % (student.student_id, parent.level, items_changed))837 return838 839 def addEntry(self, obj, row, site):840 parent = self.getParent(row, site)841 catalog = getUtility(ICatalog, name='courses_catalog')842 entries = list(catalog.searchResults(code=(row['code'],row['code'])))843 obj.fcode = entries[0].__parent__.__parent__.__parent__.code844 obj.dcode = entries[0].__parent__.__parent__.code845 obj.title = entries[0].title846 if getattr(obj, 'credits', None) is None:847 obj.credits = entries[0].credits848 if getattr(obj, 'passmark', None) is None:849 obj.passmark = entries[0].passmark850 obj.semester = entries[0].semester851 parent[row['code']] = obj852 return853 854 def delEntry(self, row, site):855 raise NotImplementedError('method not implemented')856 857 def checkConversion(self, row, mode='ignore'):858 """Validates all values in row.859 """860 errs, inv_errs, conv_dict = super(861 CourseTicketProcessor, self).checkConversion(row, mode=mode)862 863 # We have to check if course really exists.864 # This is not done by the converter.865 catalog = getUtility(ICatalog, name='courses_catalog')866 entries = catalog.searchResults(code=(row['code'],row['code']))867 if len(entries) == 0:868 errs.append(('code','non-existent'))869 return errs, inv_errs, conv_dict870 return errs, inv_errs, conv_dict -
main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
r9411 r9420 1184 1184 grok.require('waeup.manageStudent') 1185 1185 label = _('Add course ticket') 1186 form_fields = grok.AutoFields(ICourseTicketAdd).omit( 1187 'score', 'automatic', 'carry_over', 'credits', 'passmark') 1186 form_fields = grok.AutoFields(ICourseTicketAdd) 1188 1187 pnav = 4 1189 1188 … … 1222 1221 grok.require('waeup.viewStudent') 1223 1222 form_fields = grok.AutoFields(ICourseTicket) 1224 grok.template('courseticketpage')1225 1223 pnav = 4 1226 1224 … … 1237 1235 grok.name('manage') 1238 1236 grok.require('waeup.manageStudent') 1239 form_fields = grok.AutoFields(ICourseTicket).omit('credits', 'passmark') 1240 grok.template('courseticketmanagepage') 1237 form_fields = grok.AutoFields(ICourseTicket) 1238 form_fields['title'].for_display = True 1239 form_fields['fcode'].for_display = True 1240 form_fields['dcode'].for_display = True 1241 form_fields['semester'].for_display = True 1242 form_fields['passmark'].for_display = True 1243 form_fields['credits'].for_display = True 1244 form_fields['mandatory'].for_display = True 1245 form_fields['automatic'].for_display = True 1241 1246 pnav = 4 1242 1247 … … 2181 2186 grok.name('ctadd') 2182 2187 grok.require('waeup.handleStudent') 2183 form_fields = grok.AutoFields(ICourseTicketAdd).omit( 2184 'score', 'mandatory', 'automatic', 'carry_over', 'credits', 'passmark') 2188 form_fields = grok.AutoFields(ICourseTicketAdd) 2185 2189 2186 2190 def update(self): -
main/waeup.kofa/trunk/src/waeup/kofa/students/export.py
r9316 r9420 210 210 #: Fieldnames considered by this exporter 211 211 fields = tuple(sorted(iface_names(ICourseTicket) + 212 ['level', 'code', 'title', 213 'semester', 'fcode', 'dcode'])) + ('student_id', 'certcode') 212 ['level', 'code'])) + ('student_id', 'certcode') 214 213 215 214 #: The title under which this exporter will be displayed -
main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
r9334 r9420 28 28 from waeup.kofa.students.vocabularies import ( 29 29 StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source, 30 GenderSource, nats_vocab ,30 GenderSource, nats_vocab 31 31 ) 32 32 from waeup.kofa.payments.interfaces import ( 33 33 IPaymentsContainer, IOnlinePayment) 34 34 from waeup.kofa.university.vocabularies import ( 35 CourseSource, StudyModeSource, CertificateSource )35 CourseSource, StudyModeSource, CertificateSource, SemesterSource) 36 36 37 37 # VerdictSource can't be placed into the vocabularies module because it … … 488 488 489 489 class ICourseTicket(IKofaObject): 490 """A course ticket.490 """An interface for course tickets. 491 491 492 492 """ 493 493 code = Attribute('code of the original course') 494 title = Attribute('title of the original course')495 credits = Attribute('credits of the original course')496 passmark = Attribute('passmark of the original course')497 semester = Attribute('semester of the original course')498 fcode = Attribute('faculty code of the original course')499 dcode = Attribute('department code of the original course')500 494 certcode = Attribute('certificate code of the study course') 495 496 title = schema.TextLine( 497 title = _(u'Title'), 498 required = False, 499 ) 500 501 fcode = schema.TextLine( 502 title = _(u'Faculty Code'), 503 required = False, 504 ) 505 506 dcode = schema.TextLine( 507 title = _(u'Department Code'), 508 required = False, 509 ) 510 511 semester = schema.Choice( 512 title = _(u'Semester/Term'), 513 source = SemesterSource(), 514 required = False, 515 ) 516 517 passmark = schema.Int( 518 title = _(u'Passmark'), 519 required = False, 520 ) 521 522 credits = schema.Int( 523 title = _(u'Credits'), 524 required = False, 525 ) 501 526 502 527 mandatory = schema.Bool( … … 504 529 default = False, 505 530 required = False, 506 readonly = False,507 531 ) 508 532 … … 511 535 default = 0, 512 536 required = False, 513 readonly = False, 537 ) 538 539 carry_over = schema.Bool( 540 title = _(u'Carry-over Course'), 541 default = False, 542 required = False, 514 543 ) 515 544 … … 518 547 default = False, 519 548 required = False, 520 readonly = True, 521 ) 522 523 carry_over = schema.Bool( 524 title = _(u'Carry-over Course'), 525 default = False, 526 required = False, 527 readonly = False, 528 ) 529 530 credits = schema.Int( 531 title = _(u'Credits'), 532 required = False, 533 ) 534 535 passmark = schema.Int( 536 title = _(u'Passmark'), 537 required = False, 538 ) 549 ) 550 539 551 540 552 def getLevel(): … … 546 558 """ 547 559 548 class ICourseTicketAdd(I CourseTicket):560 class ICourseTicketAdd(IKofaObject): 549 561 """An interface for adding course tickets. 550 562 … … 556 568 ) 557 569 570 class ICourseTicketImport(ICourseTicket): 571 """An interface for importing course results and nothing more. 572 573 """ 574 score = schema.Int( 575 title = _(u'Score'), 576 required = False, 577 readonly = False, 578 ) 579 580 level_session = schema.Choice( 581 title = _(u'Level Session'), 582 source = academic_sessions_vocab, 583 required = False, 584 readonly = False, 585 ) 586 558 587 class IStudentAccommodation(IKofaObject): 559 588 """A container for student accommodation objects. -
main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py
r9316 r9420 121 121 super(CourseTicket, self).__init__() 122 122 self.code = None 123 self.title = None124 self.fcode = None125 self.dcode = None126 self.semester = None127 123 return 128 124 -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/sample_courseticket_data.csv
r7665 r9420 1 reg_number,matric_number,level,code,score,mandatory 2 1,,100,COURSE1,1,True 3 2,,100,COURSE1,2,False 4 ,100002,100,COURSE1,3,False 5 1,,nonsense,COURSE1,5, 6 1,,100,NONSENSE,5, 1 reg_number,matric_number,level,code,score,mandatory,level_session 2 1,,100,COURSE1,1,True, 3 2,,100,COURSE1,2,False, 4 ,100002,100,COURSE1,3,False, 5 1,,nonsense,COURSE1,5,, 6 1,,100,NONSENSE,5,, 7 1,,200,COURSE1,6,,2004 8 1,,300,COURSE1,6,,2008 9 1,,300,COURSE1,6,,200888 -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_batching.py
r9302 r9420 733 733 734 734 def test_import(self): 735 736 735 num, num_warns, fin_file, fail_file = self.processor.doImport( 737 736 self.csv_file, COURSETICKET_HEADER_FIELDS,'create') 738 739 self.assertEqual(num_warns,2) 737 fail_file = open(fail_file).read() 738 self.assertEqual(num_warns,5) 739 self.assertEqual(fail_file, 740 'reg_number,code,mandatory,level,level_session,score,matric_number,--ERRORS--\r\n' 741 '1,COURSE1,,nonsense,,5,,Not all parents do exist yet. Skipping\r\n' 742 '1,NONSENSE,,100,,5,,code: non-existent\r\n' 743 '1,COURSE1,,200,2004,6,,level_session: does not match 2008\r\n' 744 '1,COURSE1,,300,2008,6,,level: does not exist\r\n' 745 '1,COURSE1,,300,200888,6,,level_session: Invalid value; level: does not exist\r\n') 740 746 assert self.processor.entryExists( 741 747 dict(reg_number='1', level='100', code='COURSE1'), … … 772 778 num, num_warns, fin_file, fail_file = self.processor.doImport( 773 779 self.csv_file, COURSETICKET_HEADER_FIELDS,'update') 774 self.assertEqual(num_warns,2) 780 fail_file = open(fail_file).read() 781 self.assertEqual(num_warns,5) 782 self.assertEqual(fail_file, 783 'reg_number,code,mandatory,level,level_session,score,matric_number,--ERRORS--\r\n' 784 '1,COURSE1,<IGNORE>,nonsense,<IGNORE>,5,<IGNORE>,Cannot update: no such entry\r\n' 785 '1,NONSENSE,<IGNORE>,100,<IGNORE>,5,<IGNORE>,code: non-existent\r\n' 786 '1,COURSE1,<IGNORE>,200,2004,6,<IGNORE>,level_session: does not match 2008\r\n' 787 '1,COURSE1,<IGNORE>,300,2008,6,<IGNORE>,level: does not exist\r\n' 788 '1,COURSE1,<IGNORE>,300,200888,6,<IGNORE>,level_session: Invalid value; level: does not exist\r\n') 775 789 shutil.rmtree(os.path.dirname(fin_file)) 776 790 … … 786 800 num, num_warns, fin_file, fail_file = self.processor.doImport( 787 801 self.csv_file, COURSETICKET_HEADER_FIELDS,'remove') 788 self.assertEqual(num_warns, 2)802 self.assertEqual(num_warns,5) 789 803 assert self.processor.entryExists( 790 804 dict(reg_number='1', level='100', code='COURSE1'), self.app) is False -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
r9412 r9420 161 161 self.certificate.school_fee_1 = 40000.0 162 162 self.certificate.school_fee_2 = 20000.0 163 self.app['faculties']['fac1'] = Faculty(code= 'fac1')164 self.app['faculties']['fac1']['dep1'] = Department(code= 'dep1')163 self.app['faculties']['fac1'] = Faculty(code=u'fac1') 164 self.app['faculties']['fac1']['dep1'] = Department(code=u'dep1') 165 165 self.app['faculties']['fac1']['dep1'].certificates.addCertificate( 166 166 self.certificate)
Note: See TracChangeset for help on using the changeset viewer.