Changeset 13003


Ignore:
Timestamp:
27 May 2015, 07:20:57 (9 years ago)
Author:
Henrik Bettermann
Message:

More docs and necessary adjustment of code.

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

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/docs/source/userdocs/datacenter/import_processors.rst

    r12968 r13003  
    136136  verdicts have to be set or workflow transitions have to be triggered.
    137137
     138.. _course_ticket_processor:
     139
    138140Course Ticket Processor
    139141-----------------------
  • main/waeup.kofa/trunk/docs/source/userdocs/students.rst

    r13002 r13003  
    44**********************************
    55
    6 'Student' is a multi-purpose term in Kofa which may lead to some misconceptions. First of all 'Student' is a Python/Grok container class and student objects are the instances of this class. Sometimes we are sluggish when talking about 'creating students' and actually mean: 'creating student container objects and storing the objects (persistently) in the ``students`` container'. The latter is the parent container for all students in the portal.
     6'Student' is a multi-purpose term in Kofa which may lead to some misconceptions. First of all, 'Student' is a Python/Grok container class and student objects are the instances of this class. Sometimes we are sluggish when talking about 'creating students' and actually mean: 'creating student container objects and storing the objects (persistently) in the ``students`` container'. The latter is the parent container for all students in the portal.
    77
    88The :ref:`treelike storage of objects <object_database>` in the student section can be figured as follows::
     
    5757   :pyobject: IStudentBase
    5858
    59 The **first part** of the interface lists attributes. Except for the first two (`password` and `temp_password`) they are all read-only property attributes, i.e. attributes with a getter method only. These properties are computed dynamically and can't be set. Most of them return data derived from the ``studycourse`` subobject.
     59The **first part** of the interface lists attributes. Except for the last two attributes (`password` and `temp_password`) they are all read-only property attributes, i.e. attributes with a getter method only. These properties are computed dynamically and can't be set. Most of them return data derived from the ``studycourse`` subobject.
    6060
    6161The **second part** of the interface specifies the schema fields
     
    7171  **Vocabularies and sources** are very similar. The latter is a newer concept of producing choices and considered to replace vocabularies. In Kofa we are using both. Common to both is that a set of values is accompanied by a user-friendly title, which is displayed on pages (e.g. in select boxes) instead of a less informative value token or even a cryptic representation of a persistent value object. In most cases we have a token-title pair which perfectly describes the values of a source or a vocabulary. The tokens are being sent in forms or imported by batch processors.
    7272
    73   **Token-title pairs** of most (non-database-dependent) sources and vocabularies of the Kofa base package can be viewed `here <http://kofa-demo.waeup.org/sources>`_.
     73  See `token-title pairs <http://kofa-demo.waeup.org/sources>`_ of most (non-database-dependent) sources and vocabularies in the Kofa base package.
    7474
    7575The **third part** of the interface lists the methods which can be applied to student objects.
     
    107107Kofa provides a mechanism which ensures that personal data are being kept up to date. Students are regularly requested to update the personal data directly after login. The personal data expire 180 days after saving the data for the last time which is stored in the `personal_updated` attribute. Then the `personal_data_expired` property returns ``True`` and the student is redirected to the personal data edit page when logging in.
    108108
     109`IStudentNavigation`
     110--------------------
     111
     112See docstring.
     113
     114.. literalinclude:: ../../../src/waeup/kofa/students/interfaces.py
     115   :pyobject: IStudentNavigation
     116
    109117Student Study Courses
    110118=====================
    111119
    112 All data related to an individual course of study are stored with the ``studycourse`` object. This container object is an instance of the `StudentStudyCourse` class which implements `waeup.kofa.students.interfaces.IStudentStudyCourse`.
     120All data related to an individual course of study are stored with the ``studycourse`` object. This container object is an instance of the `StudentStudyCourse` class which implements `waeup.kofa.students.interfaces.IStudentStudyCourse`, `waeup.kofa.students.interfaces.IStudentNavigation` and `waeup.kofa.students.interfaces.IStudentStudyCourseTranscript`. The latter does not add further behaviour to our classes but is needed for transcript pages only. It is not described in the user handbook.
    113121
    114122`IStudentStudyCourse`
     
    128136What is a verdict? A verdict is the individual judgement of a jury (senate in Nigeria) at the end of each academic session. The jury's verdict tells the portal, if the student has successfully completed an academic session or not. Depending on the verdict, the student will be either allowed to proceed to the next study level or forced to repeat the current level. Without a verdict, the student gets stuck and cannot even pay school fees for the next academic year. This will be further exlplained in the workflow section below.
    129137
    130 `StudentStudyCourse` is a container class. Study courses contain `StudentStudyLevel` instances which implement `waeup.kofa.students.interfaces.IStudentStudyLevel`.
     138`StudentStudyCourse` is a container class. Study courses contain `StudentStudyLevel` instances which implement `waeup.kofa.students.interfaces.IStudentStudyLevel` and also `waeup.kofa.students.interfaces.IStudentNavigation`, see above.
    131139
    132140`IStudentStudyLevel`
    133141--------------------
    134142
    135 `StudentStudyLevel` instances contain information about the study progress achieved at that level. In Kofa study levels range from 100 to 900. There are two additional levels: a pre-studies level (10) and a special postgraduate level (999). There are also two probation levels per regular study level. Level 120, for instance, means level 100 on second probation. The complete numbering of study levels can be viewed `here <https://kofa-demo.waeup.org/sources#collapseStudyLevels>`_.
     143`StudentStudyLevel` instances contain information about the study progress achieved at that level. In Kofa study levels range from 100 to 900. There are two additional levels: a pre-studies level (10) and a special postgraduate level (999). There are also two probation levels per regular study level. Level 120, for instance, means level 100 on second probation. See `complete numbering of study levels <https://kofa-demo.waeup.org/sources#collapseStudyLevels>`_ in the base package.
    136144
    137145`StudentStudyLevel` instances are container objects which contain course tickets. We therefore sometimes speak of a level course list instead of a study level. The study level stores and provides the information when (`validation_date`) and by whom (`validated_by`) the course list was validated, in which session the level was taken (`level_session`) and which verdict the student finally obtained.
     
    140148   :pyobject: IStudentStudyLevel
    141149
    142 `StudentStudyLevel` instances also compute some statistical values on the fly to give an overview of the courses taken. These read-only property attributes are: `number_of_tickets`, `passed_params`, `gpa_params`, `gpa_params_rectified`, `cumulative_params`, `total_credits` and `gpa`. The attentive reader may wonder why the latter two are not listed in the attributes section of the interface, but as read-only schema fields further below. This is a trick which we used to properly display these fields on some form pages and pdf slips. However, the `attrs_to_fields` function explicitly excludes them when starting the portal, so that these fields are not used for persistent storage of same-named attributes in the database.
     150`StudentStudyLevel` instances also compute some statistics on the fly to give an overview of the courses taken. These read-only property attributes are: `number_of_tickets`, `passed_params`, `gpa_params`, `gpa_params_rectified`, `cumulative_params`, `total_credits` and `gpa`. The attentive reader may wonder why the latter two are not listed in the attributes section of the interface, but as read-only schema fields further below. This is a trick which we used to properly display these fields on some display pages and pdf slips. However, the `attrs_to_fields` function explicitly excludes them when starting the portal, so that these fields are not used for persistent storage of same-named attributes in the database.
    143151
    144152`ICourseTicket`
    145153---------------
    146154
     155Course tickets allow students to attend a course. Lecturers can enter scores at the end of the term. A `CourseTicket` instance contains a copy of the original `Course` and `CertificateCourse` data. If the courses and/or the referring certificate courses are removed, the corresponding tickets remain unchanged. So we do not need any event triggered actions on course tickets.
     156
     157The `CourseTicket`  implements `waeup.kofa.students.interfaces.ICourseTicket` and also `waeup.kofa.students.interfaces.IStudentNavigation`, see above.
     158
    147159.. literalinclude:: ../../../src/waeup/kofa/students/interfaces.py
    148160   :pyobject: ICourseTicket
     161
     162The quite long list of schema fields pretends that form pages may provide these fields for editing. This is not the case. Except for `score`, all these fields are 'for display' only. They can neither be changed through the UI nor by batch processing (import). They are solely meant for backing up the orginal course data. See also :ref:`course_ticket_processor`.
     163
     164.. note::
     165
     166  It may happen that a course has been accidentally misconfigured, for example the number of credits was set too high. The course object can be corrected, but, course tickets, which refer to this course, can not. They are neither adjusted automatically nor changeable by the batch processor. The only solution to 'adjust' course tickets is to replace them by new tickets.
    149167
    150168Student Payments
  • main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py

    r13002 r13003  
    178178
    179179class IStudentNavigation(IStudentNavigationBase):
    180     """Interface needed for student navigation, logging, etc.
    181     """
    182     student = Attribute('Student object of context.')
     180    """Interface needed for navigation and logging. This interface is
     181    implemented by all content classes in the student section.
     182    """
     183    student = Attribute('Student object of context')
    183184
    184185    def writeLogMessage(view, message):
    185186        """Write a view specific log message into students.log.
    186 
    187187        """
    188188
     
    190190    """Representation of student base data.
    191191    """
    192     password = Attribute('Encrypted password')
    193     temp_password = Attribute('Dictionary with user name, timestamp and encrypted password')
    194192    history = Attribute('Object history, a list of messages')
    195193    state = Attribute('Registration state')
     
    211209    transcript_enabled = Attribute('True if transcript processing is enabled')
    212210
     211    password = Attribute('Encrypted password')
     212    temp_password = Attribute('Dictionary with user name, timestamp and encrypted password')
     213
    213214    suspended = schema.Bool(
    214215        title = _(u'Account suspended'),
     
    281282        required = False,
    282283        )
    283 
    284     def writeLogMessage(view, message):
    285         """Write formatted log message into students.log.
    286         """
    287284
    288285    def setTempPassword(user, password):
     
    427424    """Representation of student study course data.
    428425    """
    429     student = Attribute('Student object')
    430426    next_session_allowed = Attribute('True if the student can proceed to next session')
    431427    is_postgrad = Attribute('True if student is postgraduate student')
     
    482478        )
    483479
    484     def writeLogMessage(view, message):
    485         """Write formatted log message into students.log.
    486         """
    487 
    488480    def addStudentStudyLevel(cert, studylevel):
    489481        """Add a study level object.
     
    577569    """A representation of student study level data.
    578570    """
    579     student = Attribute('Student object')
    580 
    581571    certcode = Attribute('The certificate code of the study course')
    582572    is_current_level = Attribute('True if level is current level of the student')
     
    633623        )
    634624
    635     def writeLogMessage(view, message):
    636         """Write formatted log message into students.log.
    637         """
    638 
    639625    def addCourseTicket(ticket, course):
    640626        """Add a course ticket object.
     
    649635    """A representation of course ticket data.
    650636    """
    651     code = Attribute('code of the original course')
    652     certcode = Attribute('certificate code of the study course')
    653     grade = Attribute('grade calculated from score')
    654     weight = Attribute('weight calculated from score')
    655     removable_by_student = Attribute('Is student allowed to remove the ticket?')
    656     level_session = Attribute('session of the level the ticket has been added to')
    657     level = Attribute('id of the level the ticket has been added to')
     637    certcode = Attribute('Certificate code of the study course')
     638    level_session = Attribute('Session of the study level the ticket has been added to')
     639    level = Attribute('Level value of the study level the ticket has been added to')
     640    grade = Attribute('Grade calculated from score')
     641    weight = Attribute('Weight calculated from score')
     642    removable_by_student = Attribute('True if student is allowed to remove the ticket')
     643    editable_by_lecturer = Attribute('True if lecturer is allowed to edit the ticket')
     644
     645    code = Attribute('Code of the original course')
    658646
    659647    title = schema.TextLine(
     
    712700        required = False,
    713701        )
    714 
    715702
    716703class ICourseTicketAdd(IKofaObject):
  • main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py

    r13002 r13003  
    143143    def passed_params(self):
    144144        """Determine the number and credits of passed and failed courses.
    145 
    146145        This method is used for level reports.
    147146        """
     
    274273        try:
    275274            return self.__parent__.__parent__.__parent__
    276         except AttributeError:
     275        except AttributeError: # in unit tests
    277276            return None
    278277
     
    281280        try:
    282281            return self.__parent__.__parent__.certificate.code
    283         except AttributeError:
     282        except AttributeError: # in unit tests
    284283            return None
    285284
     
    290289    @property
    291290    def editable_by_lecturer(self):
    292         cas = grok.getSite()['configuration'].current_academic_session
    293         if self.student.state == VALIDATED and self.student.current_session == cas:
    294             return True
     291        try:
     292            cas = grok.getSite()['configuration'].current_academic_session
     293            if self.student.state == VALIDATED and self.student.current_session == cas:
     294                return True
     295        except TypeError: # in unit tests
     296            pass
    295297        return False
    296298
     
    304306        try:
    305307            return self.__parent__.level
    306         except AttributeError:
     308        except AttributeError: # in unit tests
    307309            return None
    308310
     
    313315        try:
    314316            return self.__parent__.level_session
    315         except AttributeError:
     317        except AttributeError: # in unit tests
    316318            return None
    317319
     
    327329        """
    328330        return getGradeWeightFromScore(self.score)[1]
    329 
    330     @property
    331     def course(self):
    332         """Returns the course the ticket is referring to. Returns
    333         None if the course has been removed.
    334 
    335         This method is not used in Kofa anymore.
    336         """
    337         cat = queryUtility(ICatalog, name='courses_catalog')
    338         result = cat.searchResults(code=(self.code, self.code))
    339         if len(result) != 1:
    340             return None
    341         return list(result)[0]
    342331
    343332CourseTicket = attrs_to_fields(CourseTicket)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r12889 r13003  
    18031803        self.browser.getControl("Show").click()
    18041804        self.assertTrue(self.student_id in self.browser.contents)
    1805         # The course ticket can be linked with the course.
    1806         self.assertEqual(
    1807             self.student['studycourse']['100']['COURSE1'].course,
    1808             self.course)
    18091805        # Lecturer can neither access the student ...
    18101806        self.assertRaises(
Note: See TracChangeset for help on using the changeset viewer.