Changeset 7133
- Timestamp:
- 18 Nov 2011, 08:48:22 (13 years ago)
- Location:
- main/waeup.sirp/trunk/src/waeup/sirp/students
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/students/browser.py
r7127 r7133 22 22 from zope.event import notify 23 23 from zope.catalog.interfaces import ICatalog 24 from zope.component import queryUtility 24 from zope.component import queryUtility, getUtility 25 25 from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState 26 26 from zope.component import createObject … … 34 34 from waeup.sirp.browser.viewlets import ( 35 35 ManageActionButton, PrimaryNavTab, AddActionButton) 36 from waeup.sirp.interfaces import IWAeUPObject, IUserAccount 36 from waeup.sirp.interfaces import IWAeUPObject, IUserAccount, IExtFileStore 37 37 from waeup.sirp.widgets.datewidget import ( 38 38 FriendlyDateWidget, FriendlyDateDisplayWidget, … … 62 62 return 63 63 64 # Save function used for save methods in managerpages64 # Save function used for save methods in pages 65 65 def msave(view, **data): 66 66 form = view.request.form … … 74 74 if fields_string: 75 75 write_log_message(view, 'saved: %s' % fields_string) 76 return 77 78 def emitLockMessage(view): 79 view.flash('The requested form is locked (read-only).') 80 view.redirect(view.url(view.context)) 76 81 return 77 82 … … 364 369 grok.require('waeup.manageStudents') 365 370 text = 'Manage' 366 target = ' edit_base'371 target = 'manage_base' 367 372 368 373 class StudentBaseManageFormPage(WAeUPEditFormPage): 369 """ View to editstudent base data370 """ 371 grok.context(IStudent) 372 grok.name(' edit_base')374 """ View to manage student base data 375 """ 376 grok.context(IStudent) 377 grok.name('manage_base') 373 378 grok.require('waeup.manageStudents') 374 379 form_fields = grok.AutoFields(IStudentBase).omit('student_id') … … 409 414 write_log_message(self, 'password changed') 410 415 416 # The following is now done by contextual_reg_num_source validation 411 417 #self.reg_number = form.get('form.reg_number', None) 412 418 #if self.reg_number: … … 1448 1454 # Pages for students only 1449 1455 1456 class StudentBaseActionButton(ManageActionButton): 1457 grok.order(1) 1458 grok.context(IStudent) 1459 grok.view(StudentBaseDisplayFormPage) 1460 grok.require('waeup.handleStudent') 1461 text = 'Edit base data' 1462 target = 'edit_base' 1463 1450 1464 class StudentPasswordActionButton(ManageActionButton): 1451 grok.order( 1)1465 grok.order(2) 1452 1466 grok.context(IStudent) 1453 1467 grok.view(StudentBaseDisplayFormPage) … … 1458 1472 1459 1473 class StudentPassportActionButton(ManageActionButton): 1460 grok.order( 1)1474 grok.order(3) 1461 1475 grok.context(IStudent) 1462 1476 grok.view(StudentBaseDisplayFormPage) … … 1465 1479 text = 'Change portrait' 1466 1480 target = 'change_portrait' 1481 1482 @property 1483 def target_url(self): 1484 if self.context.state != 'admitted': 1485 return '' 1486 return self.view.url(self.view.context, self.target) 1487 1488 class StudentBaseEditFormPage(WAeUPEditFormPage): 1489 """ View to edit student base data 1490 """ 1491 grok.context(IStudent) 1492 grok.name('edit_base') 1493 grok.require('waeup.handleStudent') 1494 form_fields = grok.AutoFields(IStudentBase).select( 1495 'email', 'phone') 1496 #grok.template('basemanagepage') 1497 label = 'Edit base data' 1498 title = 'Base Data' 1499 pnav = 4 1500 1501 @grok.action('Save') 1502 def save(self, **data): 1503 msave(self, **data) 1504 return 1467 1505 1468 1506 class StudentPasswordSetting(grok.Adapter): … … 1543 1581 pnav = 4 1544 1582 1583 def update(self): 1584 if self.context.getStudent().state != 'admitted': 1585 emitLockMessage(self) 1586 return 1587 super(StudentFilesUploadPage, self).update() 1588 return 1589 1545 1590 class StudentClearanceStartActionButton(ManageActionButton): 1546 1591 grok.order(1) … … 1570 1615 buttonname = 'Start clearance now' 1571 1616 1617 @property 1618 def all_required_fields_filled(self): 1619 if self.context.email and self.context.phone: 1620 return True 1621 return False 1622 1623 @property 1624 def portrait_uploaded(self): 1625 store = getUtility(IExtFileStore) 1626 if store.getFileByContext(self.context, attr=u'passport.jpg'): 1627 return True 1628 return False 1629 1572 1630 def update(self, SUBMIT=None): 1573 1631 if not self.context.state == 'admitted': 1574 1632 self.flash("Wrong state.") 1575 1633 self.redirect(self.url(self.context)) 1634 return 1635 if not self.portrait_uploaded: 1636 self.flash("No portrait uploaded.") 1637 self.redirect(self.url(self.context, 'change_portrait')) 1638 return 1639 if not self.all_required_fields_filled: 1640 self.flash("Not all required fields filled.") 1641 self.redirect(self.url(self.context, 'edit_base')) 1576 1642 return 1577 1643 self.ac_series = self.request.form.get('ac_series', None) … … 1630 1696 form_fields['date_of_birth'].custom_widget = FriendlyDateWidget('le-year') 1631 1697 1632 def emitLockMessage(self):1633 self.flash('The requested form is locked (read-only).')1634 self.redirect(self.url(self.context))1635 return1636 1637 1698 def update(self): 1638 1699 if self.context.clearance_locked: 1639 self.emitLockMessage() 1640 return 1641 datepicker.need() 1700 emitLockMessage(self) 1701 return 1642 1702 return super(StudentClearanceEditFormPage, self).update() 1643 1703 … … 1793 1853 return 'Add current level %s' % title 1794 1854 1795 def emitLockMessage(self):1796 self.flash('The requested form is locked (read-only).')1797 self.redirect(self.url(self.context))1798 return1799 1800 1855 def update(self): 1801 1856 if self.context.getStudent().state != 'school fee paid': 1802 self.emitLockMessage()1857 emitLockMessage(self) 1803 1858 return 1804 1859 super(AddStudyLevelFormPage, self).update() -
main/waeup.sirp/trunk/src/waeup/sirp/students/interfaces.py
r7124 r7133 1 1 ## 2 2 ## interfaces.py 3 import re 3 4 from datetime import datetime 4 5 from zope.interface import Attribute, invariant … … 14 15 from waeup.sirp.payments.interfaces import IPaymentsContainer, IOnlinePayment 15 16 17 # Define a valiation method for email addresses 18 class NotAnEmailAddress(schema.ValidationError): 19 __doc__ = u"Invalid email address" 20 21 check_email = re.compile( 22 r"[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+.)*[a-zA-Z]{2,4}").match 23 def validate_email(value): 24 if not check_email(value): 25 raise NotAnEmailAddress(value) 26 return True 27 16 28 class IStudentsContainer(IWAeUPObject): 17 29 """A students container contains university students. … … 139 151 required = False, 140 152 readonly = True, 153 ) 154 155 email = schema.ASCIILine( 156 title = u'Email', 157 required = False, 158 constraint=validate_email, 159 ) 160 phone = schema.Int( 161 title = u'Phone', 162 description = u'Enter phone number with country code and without spaces.', 163 required = False, 141 164 ) 142 165 -
main/waeup.sirp/trunk/src/waeup/sirp/students/tests/sample_student_data.csv
r6844 r7133 1 firstname,lastname,fullname,reg_number,date_of_birth,matric_number 2 Aaren,Pieri,Aaren Pieri,1,1990-01-02,100000 3 Aaren,Finau,Aaren Finau,2,1990-01-03,100001 4 Aaren,Berson,Aaren Berson,3,1990-01-04,100002 1 firstname,lastname,fullname,reg_number,date_of_birth,matric_number,email,phone 2 Aaren,Pieri,Aaren Pieri,1,1990-01-02,100000,aa@aa.ng,1234 3 Aaren,Finau,Aaren Finau,2,1990-01-03,100001,aa@aa.ng,1234 4 Aaren,Berson,Aaren Berson,3,1990-01-04,100002,aa@aa.ng,1234 -
main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_browser.py
r7127 r7133 91 91 student.matric_number = u'234' 92 92 student.sex = u'm' 93 student.email = 'aa@aa.ng' 94 student.phone = 1234 93 95 self.app['students'].addStudent(student) 94 96 self.student_id = student.student_id … … 104 106 self.add_student_path = self.container_path + '/addstudent' 105 107 self.student_path = self.container_path + '/' + self.student_id 106 self.manage_student_path = self.student_path + '/ edit_base'108 self.manage_student_path = self.student_path + '/manage_base' 107 109 self.clearance_student_path = self.student_path + '/view_clearance' 108 110 self.personal_student_path = self.student_path + '/view_personal' … … 584 586 # Prepare a csv file for students 585 587 open('students.csv', 'wb').write( 586 """firstname,lastname,fullname,reg_number,date_of_birth,matric_number 587 Aaren,Pieri,Aaren Pieri,1,1990-01-02,100000 588 Claus,Finau,Claus Finau,2,1990-01-03,100001 589 Brit,Berson,Brit Berson,3,1990-01-04,100001 588 """firstname,lastname,fullname,reg_number,date_of_birth,matric_number,email,phone 589 Aaren,Pieri,Aaren Pieri,1,1990-01-02,100000,aa@aa.ng,1234 590 Claus,Finau,Claus Finau,2,1990-01-03,100001,aa@aa.ng,1234 591 Brit,Berson,Brit Berson,3,1990-01-04,100001,aa@aa.ng,1234 590 592 """) 591 593 self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') … … 757 759 self.browser.getLink("Clearance Data").click() 758 760 self.browser.getLink("Start clearance").click() 761 self.student.email = None 762 # Uups, we forgot to fill the email fields 763 self.browser.getControl("Start clearance").click() 764 self.assertMatches('...Not all required fields filled...', 765 self.browser.contents) 766 self.student.email = 'aa@aa.ng' 767 self.browser.open(self.student_path + '/start_clearance') 759 768 self.browser.getControl(name="ac_series").value = '3' 760 769 self.browser.getControl(name="ac_number").value = '4444444' … … 923 932 ac = self.app['accesscodes']['CLR-0'][pin] 924 933 ac.owner = self.student_id 925 # The new CLR-0 pin can be used for starting clearance926 IWorkflowInfo(self.student).fireTransition('admit')927 self.browser.open(self.student_path + '/start_clearance')928 parts = pin.split('-')[1:]929 clrseries, clrnumber = parts930 self.browser.getControl(name="ac_series").value = clrseries931 self.browser.getControl(name="ac_number").value = clrnumber932 self.browser.getControl("Start clearance now").click()933 self.assertMatches('...Clearance process has been started...',934 self.browser.contents)935 934 return 936 935 … … 975 974 976 975 # The new CLR-0 pin can be used for starting clearance 976 # but they have to upload a passport picture first 977 # which is only possible in state admitted 978 self.browser.open(self.student_path + '/change_portrait') 979 self.assertMatches('...form is locked...', 980 self.browser.contents) 977 981 IWorkflowInfo(self.student).fireTransition('admit') 982 self.browser.open(self.student_path + '/change_portrait') 983 pseudo_image = StringIO('I pretend to be a graphics file') 984 ctrl = self.browser.getControl(name='passportuploadedit') 985 file_ctrl = ctrl.mech_control 986 file_ctrl.add_file(pseudo_image, filename='my_photo.jpg') 987 self.browser.getControl( 988 name='upload_passportuploadedit').click() 978 989 self.browser.open(self.student_path + '/start_clearance') 979 990 parts = pin.split('-')[1:] -
main/waeup.sirp/trunk/src/waeup/sirp/students/workflow.py
r6990 r7133 176 176 def handle_student_transition_event(obj, event): 177 177 """Append message to student history and log file when transition happened. 178 179 Lock and unlock clearance form. 178 180 """ 179 181 msg = '%s' % event.transition.user_data['msg']
Note: See TracChangeset for help on using the changeset viewer.