Changeset 7951
- Timestamp:
- 22 Mar 2012, 07:21:20 (13 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa/students
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/students/batching.py
r7933 r7951 31 31 from zope.event import notify 32 32 from zope.catalog.interfaces import ICatalog 33 from hurry.workflow.interfaces import IWorkflowState 33 from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo 34 34 from waeup.kofa.interfaces import ( 35 35 IBatchProcessor, FatalCSVError, IObjectConverter, IUserAccount, 36 IObjectHistory )36 IObjectHistory, VALIDATED) 37 37 from waeup.kofa.students.interfaces import ( 38 38 IStudent, IStudentStudyCourse, 39 39 IStudentUpdateByRegNo, IStudentUpdateByMatricNo, 40 40 IStudentStudyLevel, ICourseTicket, 41 IStudentOnlinePayment )41 IStudentOnlinePayment, IStudentVerdictUpdate) 42 42 from waeup.kofa.students.workflow import IMPORTABLE_STATES 43 43 from waeup.kofa.utils.batching import BatchProcessor … … 639 639 return errs, inv_errs, conv_dict 640 640 return errs, inv_errs, conv_dict 641 642 class StudentVerdictProcessor(StudentStudyCourseProcessor): 643 """A batch processor for verdicts. 644 645 Import verdicts and perform workflow transitions. 646 """ 647 648 util_name = 'verdictupdater' 649 grok.name(util_name) 650 651 name = u'Verdict Processor (update only)' 652 iface = IStudentVerdictUpdate 653 factory_name = 'waeup.StudentStudyCourse' 654 655 @property 656 def available_fields(self): 657 return sorted(list(set( 658 ['student_id','reg_number','matric_number', 659 'current_session', 'current_level'] + getFields( 660 self.iface).keys()))) 661 662 def checkUpdateRequirements(self, obj, row, site): 663 """Checks requirements the studycourse and the student must fulfill 664 before being updated. 665 """ 666 # Check if current_levels correspond 667 if obj.current_level != row['current_level']: 668 return 'Current level does not correspond.' 669 # Check if current_sessions correspond 670 if obj.current_session != row['current_session']: 671 return 'Current session does not correspond.' 672 # Check if student is in state REGISTERED 673 if obj.getStudent().state != VALIDATED: 674 return 'Student in wrong state.' 675 return None 676 677 def updateEntry(self, obj, row, site): 678 """Update obj to the values given in row. 679 """ 680 items_changed = '' 681 for key, value in row.items(): 682 # Skip fields not declared in interface plus 683 # current_verdict and current_level 684 if hasattr(obj, key) and not key in [ 685 'current_verdict','current_level']: 686 setattr(obj, key, value) 687 items_changed += '%s=%s, ' % (key,value) 688 parent = self.getParent(row, site) 689 parent.__parent__.logger.info( 690 '%s - Verdict updated: %s' 691 % (parent.student_id, items_changed)) 692 # Fire transition 693 IWorkflowInfo(obj.__parent__).fireTransition('return') 694 # Update the students_catalog 695 notify(grok.ObjectModifiedEvent(obj.__parent__)) 696 return 697 698 def checkConversion(self, row, mode='ignore'): 699 """Validates all values in row. 700 """ 701 converter = IObjectConverter(self.iface) 702 errs, inv_errs, conv_dict = converter.fromStringDict( 703 row, self.factory_name) 704 return errs, inv_errs, conv_dict -
main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
r7915 r7951 334 334 ) 335 335 336 class IStudentVerdictUpdate(IKofaObject): 337 """A interface for verdict imports. 338 339 """ 340 341 current_verdict = schema.Choice( 342 title = _(u'Current Verdict'), 343 source = VerdictSource(), 344 required = True, 345 ) 346 347 current_session = schema.Choice( 348 title = _(u'Current Session'), 349 source = academic_sessions_vocab, 350 default = None, 351 required = True, 352 ) 353 354 current_level = schema.Choice( 355 title = _(u'Current Level'), 356 source = StudyLevelSource(), 357 default = None, 358 required = True, 359 ) 360 336 361 class IStudentStudyLevel(IKofaObject): 337 362 """A container for course tickets. -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/sample_student_data.csv
r7643 r7951 1 student_id,firstname,lastname,reg_number,date_of_birth,matric_number,email,phone 2 X666666,Aaren,Pieri,1,1990-01-02,100000,aa@aa.ng,1234 3 ,Aaren,Finau,2,1990-01-03,100001,aa@aa.ng,1234 4 ,Aaren,Berson,3,1990-01-04,100002,aa@aa.ng,1234 1 student_id,firstname,lastname,reg_number,date_of_birth,matric_number,email,phone,reg_state 2 X666666,Aaren,Pieri,1,1990-01-02,100000,aa@aa.ng,1234,courses validated 3 ,Aaren,Finau,2,1990-01-03,100001,aa@aa.ng,1234,courses validated 4 ,Aaren,Berson,3,1990-01-04,100002,aa@aa.ng,1234,courses validated -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_batching.py
r7947 r7951 34 34 StudentProcessor, StudentStudyCourseProcessor, 35 35 StudentStudyLevelProcessor, CourseTicketProcessor, 36 StudentOnlinePaymentProcessor )36 StudentOnlinePaymentProcessor, StudentVerdictProcessor) 37 37 from waeup.kofa.students.student import Student 38 38 from waeup.kofa.testing import FunctionalLayer, FunctionalTestCase … … 65 65 66 66 STUDYCOURSE_HEADER_FIELDS = STUDYCOURSE_SAMPLE_DATA.split( 67 '\n')[0].split(',') 68 69 VERDICT_SAMPLE_DATA = open( 70 os.path.join(os.path.dirname(__file__), 'sample_verdict_data.csv'), 71 'rb').read() 72 73 VERDICT_HEADER_FIELDS = VERDICT_SAMPLE_DATA.split( 67 74 '\n')[0].split(',') 68 75 … … 108 115 self.app = self.getRootFolder()['app'] 109 116 setSite(app) 110 111 # Import students with subobjects112 #student_file = os.path.join(self.workdir, 'sample_student_data.csv')113 #open(student_file, 'wb').write(STUDENT_SAMPLE_DATA)114 #num, num_warns, fin_file, fail_file = StudentProcessor().doImport(115 # student_file, STUDENT_HEADER_FIELDS)116 #shutil.rmtree(os.path.dirname(fin_file))117 117 118 118 # Populate university … … 126 126 self.app['faculties']['fac1']['dep1'].certificates.addCertificate( 127 127 self.certificate) 128 129 self.importer = StudentStudyCourseProcessor()130 self.csv_file = os.path.join(131 self.workdir, 'sample_studycourse_data.csv')132 open(self.csv_file, 'wb').write(STUDYCOURSE_SAMPLE_DATA)133 128 return 134 129 … … 297 292 298 293 299 class StudentStudyCourseProcessorTest(FunctionalTestCase): 300 301 layer = FunctionalLayer 294 class StudentStudyCourseProcessorTest(StudentImportExportSetup): 302 295 303 296 def setUp(self): 304 297 super(StudentStudyCourseProcessorTest, self).setUp() 305 self.dc_root = tempfile.mkdtemp()306 self.workdir = tempfile.mkdtemp()307 app = University()308 app['datacenter'].setStoragePath(self.dc_root)309 self.getRootFolder()['app'] = app310 self.app = self.getRootFolder()['app']311 setSite(app)312 298 313 299 # Import students with subobjects … … 318 304 shutil.rmtree(os.path.dirname(fin_file)) 319 305 320 # Populate university321 self.certificate = createObject('waeup.Certificate')322 self.certificate.code = 'CERT1'323 self.certificate.application_category = 'basic'324 self.certificate.start_level = 200325 self.certificate.end_level = 500326 self.app['faculties']['fac1'] = Faculty()327 self.app['faculties']['fac1']['dep1'] = Department()328 self.app['faculties']['fac1']['dep1'].certificates.addCertificate(329 self.certificate)330 331 306 self.processor = StudentStudyCourseProcessor() 332 307 self.csv_file = os.path.join( … … 335 310 return 336 311 337 def tearDown(self):338 super(StudentStudyCourseProcessorTest, self).tearDown()339 shutil.rmtree(self.workdir)340 shutil.rmtree(self.dc_root)341 clearSite()342 return343 344 312 def test_interface(self): 345 313 # Make sure we fulfill the interface contracts. … … 384 352 shutil.rmtree(os.path.dirname(fin_file)) 385 353 386 class StudentStudyLevelProcessorTest(FunctionalTestCase): 387 388 layer = FunctionalLayer 354 class StudentVerdictProcessorTest(StudentImportExportSetup): 355 389 356 390 357 def setUp(self): 391 super(StudentStudyLevelProcessorTest, self).setUp() 392 self.dc_root = tempfile.mkdtemp() 393 self.workdir = tempfile.mkdtemp() 394 app = University() 395 app['datacenter'].setStoragePath(self.dc_root) 396 self.getRootFolder()['app'] = app 397 self.app = self.getRootFolder()['app'] 398 setSite(app) 358 super(StudentVerdictProcessorTest, self).setUp() 399 359 400 360 # Import students with subobjects … … 404 364 student_file, STUDENT_HEADER_FIELDS) 405 365 shutil.rmtree(os.path.dirname(fin_file)) 406 407 # Populate university408 self.certificate = createObject('waeup.Certificate')409 self.certificate.code = 'CERT1'410 self.certificate.application_category = 'basic'411 self.certificate.start_level = 200412 self.certificate.end_level = 500413 self.app['faculties']['fac1'] = Faculty()414 self.app['faculties']['fac1']['dep1'] = Department()415 self.app['faculties']['fac1']['dep1'].certificates.addCertificate(416 self.certificate)417 366 418 367 # Update study courses … … 425 374 shutil.rmtree(os.path.dirname(fin_file)) 426 375 376 self.processor = StudentVerdictProcessor() 377 self.csv_file = os.path.join( 378 self.workdir, 'sample_verdict_data.csv') 379 open(self.csv_file, 'wb').write(VERDICT_SAMPLE_DATA) 380 return 381 382 def test_import(self): 383 num, num_warns, fin_file, fail_file = self.processor.doImport( 384 self.csv_file, VERDICT_HEADER_FIELDS,'update') 385 self.assertEqual(num_warns,0) 386 studycourse = self.processor.getEntry(dict(reg_number='1'), self.app) 387 self.assertEqual(studycourse.certificate.code, u'CERT1') 388 shutil.rmtree(os.path.dirname(fin_file)) 389 390 391 class StudentStudyLevelProcessorTest(StudentImportExportSetup): 392 393 def setUp(self): 394 super(StudentStudyLevelProcessorTest, self).setUp() 395 396 # Import students with subobjects 397 student_file = os.path.join(self.workdir, 'sample_student_data.csv') 398 open(student_file, 'wb').write(STUDENT_SAMPLE_DATA) 399 num, num_warns, fin_file, fail_file = StudentProcessor().doImport( 400 student_file, STUDENT_HEADER_FIELDS) 401 shutil.rmtree(os.path.dirname(fin_file)) 402 403 # Update study courses 404 studycourse_file = os.path.join( 405 self.workdir, 'sample_studycourse_data.csv') 406 open(studycourse_file, 'wb').write(STUDYCOURSE_SAMPLE_DATA) 407 processor = StudentStudyCourseProcessor() 408 num, num_warns, fin_file, fail_file = processor.doImport( 409 studycourse_file, STUDYCOURSE_HEADER_FIELDS,'update') 410 shutil.rmtree(os.path.dirname(fin_file)) 411 427 412 self.processor = StudentStudyLevelProcessor() 428 413 self.csv_file = os.path.join( 429 414 self.workdir, 'sample_studylevel_data.csv') 430 415 open(self.csv_file, 'wb').write(STUDYLEVEL_SAMPLE_DATA) 431 432 def tearDown(self):433 super(StudentStudyLevelProcessorTest, self).tearDown()434 shutil.rmtree(self.workdir)435 shutil.rmtree(self.dc_root)436 clearSite()437 return438 416 439 417 def test_interface(self): … … 471 449 472 450 473 class CourseTicketProcessorTest(FunctionalTestCase): 474 475 layer = FunctionalLayer 451 class CourseTicketProcessorTest(StudentImportExportSetup): 476 452 477 453 def setUp(self): 478 454 super(CourseTicketProcessorTest, self).setUp() 479 self.dc_root = tempfile.mkdtemp()480 self.workdir = tempfile.mkdtemp()481 app = University()482 app['datacenter'].setStoragePath(self.dc_root)483 self.getRootFolder()['app'] = app484 self.app = self.getRootFolder()['app']485 setSite(app)486 455 487 456 # Import students with subobjects … … 492 461 shutil.rmtree(os.path.dirname(fin_file)) 493 462 494 # Populate university 495 self.certificate = createObject('waeup.Certificate') 496 self.certificate.code = 'CERT1' 497 self.certificate.application_category = 'basic' 498 self.certificate.start_level = 200 499 self.certificate.end_level = 500 500 self.app['faculties']['fac1'] = Faculty() 501 self.app['faculties']['fac1']['dep1'] = Department() 502 self.app['faculties']['fac1']['dep1'].certificates.addCertificate( 503 self.certificate) 463 # Add course and course referrer 504 464 self.course = createObject('waeup.Course') 505 465 self.course.code = 'COURSE1' … … 534 494 self.workdir, 'sample_courseticket_data.csv') 535 495 open(self.csv_file, 'wb').write(COURSETICKET_SAMPLE_DATA) 536 537 def tearDown(self):538 super(CourseTicketProcessorTest, self).tearDown()539 shutil.rmtree(self.workdir)540 shutil.rmtree(self.dc_root)541 clearSite()542 return543 496 544 497 def test_interface(self): … … 579 532 shutil.rmtree(os.path.dirname(fin_file)) 580 533 581 class PaymentProcessorTest(FunctionalTestCase): 582 583 layer = FunctionalLayer 534 class PaymentProcessorTest(StudentImportExportSetup): 584 535 585 536 def setUp(self): 586 537 super(PaymentProcessorTest, self).setUp() 587 self.dc_root = tempfile.mkdtemp()588 self.workdir = tempfile.mkdtemp()589 app = University()590 app['datacenter'].setStoragePath(self.dc_root)591 self.getRootFolder()['app'] = app592 self.app = self.getRootFolder()['app']593 setSite(app)594 538 595 539 # Add student with payment … … 616 560 self.workdir, 'sample_payment_data.csv') 617 561 open(self.csv_file, 'wb').write(PAYMENT_SAMPLE_DATA) 618 619 def tearDown(self):620 super(PaymentProcessorTest, self).tearDown()621 shutil.rmtree(self.workdir)622 shutil.rmtree(self.dc_root)623 clearSite()624 return625 562 626 563 def test_interface(self): … … 690 627 StudentProcessorTest,StudentStudyCourseProcessorTest, 691 628 StudentStudyLevelProcessorTest,CourseTicketProcessorTest, 692 PaymentProcessorTest, ]:629 PaymentProcessorTest,StudentVerdictProcessorTest]: 693 630 suite.addTest(unittest.TestLoader().loadTestsFromTestCase( 694 631 testcase
Note: See TracChangeset for help on using the changeset viewer.