Ignore:
Timestamp:
15 Jun 2015, 08:57:24 (10 years ago)
Author:
Henrik Bettermann
Message:

More docs.

Location:
main/waeup.kofa/trunk
Files:
1 added
6 edited

Legend:

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

    r12908 r13047  
    11.. _configuration:
    22
    3 Portal Configuration :sup:`in progress`
    4 ***************************************
     3Portal Configuration and Customization :sup:`in progress`
     4*********************************************************
  • main/waeup.kofa/trunk/docs/source/userdocs/index.rst

    r12912 r13047  
    1717   reports
    1818   configuration
     19   mandates
    1920   testing
    2021   buildingdocs
  • main/waeup.kofa/trunk/docs/source/userdocs/students/browser.rst

    r13046 r13047  
    126126
    127127
    128 Ticket Redemption
    129 -----------------
     128Payment Ticket Redemption
     129-------------------------
    130130
    131131Directly after a student payment ticket has been paid - either by approval by an officer or by receiving a positive response from a payment gateway - the
     
    1571572. The portal can be configured (`IConfigurationContainer.carry_over`) such that failed courses are automatically carried over from one session to the next. Failed course tickets from the previous level, i.e. tickets with a score below the passmark, are collected and 'copied' into the current study level container. The attributes `automatic` and `carry_over` are set to ``True``.
    158158
    159 In most cases such an automatically created course list is not perfect or even ready for submission to the course adviser. The list must be edited according to the student's needs. Students can select further courses, which they desire to attend, and can create additional course tickets, as long as total credits do not exceed 50 (value customizable). Course tickets can also be removed. Whereas officers can remove any ticket from the list, students can remove only optional (non-mandatory) course tickets (condition customizable).
     159In most cases such an automatically created course list is not perfect or even ready for submission to the course adviser. The list must be edited according to the student's needs. Students can select further courses, which they desire to attend, and can create additional course tickets, as long as the total number of credits do not exceed 50 (value customizable). Course tickets can also be removed. Whereas officers can remove any ticket from the list, students can remove only optional (non-mandatory) course tickets (condition customizable).
    160160
    161161The edit form page provides a 'Register course list' button which submits the course list to the course adviser for validation. Course advisers can't edit the registered/submitted course list, but they can validate or reject it by pressing the same-named link buttons. After pressing the 'Reject courses' button, Kofa redirects to the ContactStudentForm which can be used to inform the student about the reason of rejection. In contrast to clearance rejection, the message, which is being sent to the student by email, is neither stored in the database nor in the logfiles.
     
    171171=================================
    172172
    173 Lecturer cannot access student data directly. They don't have access to the student section. Instead, lecturers go to their course in the academic section and view or export lists of students who attended the course, either in a previous or in the current session. They do also see an 'Update scores' link button which opens the `EditScoresPage` if score editing is enabled for that department (`IDepartment.score_editing_disabled`) and `IConfigurationContainer.current_academic_session` has been set on the portal's configuration page. The page lists all students, who are attending the course in the current academic session. If score editing is allowed, the score can be entered at the end of the student line. Score editing is allowed if the student's current session corresponds with the current academic session and the student is in state 'courses validated', see method :py:meth:`CourseTicket.editable_by_lecturer<waeup.kofa.students.studylevel.CourseTicket.editable_by_lecturer>`
     173Lecturers cannot access student records directly. They don't have access to the student section. Instead, lecturers go to their course in the academic section and view or export lists of students who attended the course, either in a previous or in the current session. They do also see an 'Update scores' link button which opens the `EditScoresPage` if score editing is enabled for that department (`IDepartment.score_editing_disabled`) and `IConfigurationContainer.current_academic_session` has been set on the portal's configuration page. The `EditScoresPage` lists all students, who are attending the course in the current academic session. Score editing is allowed if the student's current session corresponds with the current academic session and the student is in state 'courses validated', see method :py:meth:`CourseTicket.editable_by_lecturer<waeup.kofa.students.studylevel.CourseTicket.editable_by_lecturer>`.
    174174
    175175.. seealso::
     
    178178
    179179
    180 .. _requesting_new_password:
    181 
    182 Requesting New Password
    183 =======================
    184 
    185 
    186 .. bed_tickets:
     180.. _bed_tickets:
    187181
    188182Bed Tickets
    189183===========
    190184
     185Students can obtain a bed ticket if a series of conditions is met:
     186
     187- The current date must be inside the booking period (between `IHostelsContainer.startdate` and `IHostelsContainer.enddate`).
     188
     189- The student's current session must match the accommodation session (`IHostelsContainer.accommodation_session`).
     190
     191- A bed ticket for the same accommodation session does not exist.
     192
     193- The student must be in the correct workflow state (`IHostelsContainer.accommodation_states`).
     194
     195- A bed type, which fits to the student, can be determined.
     196
     197- A bed of that type is available.
     198
     199- The HOS activation code is not yet used.
     200
     201- The student is the owner of the activation code.
     202
     203The customizable utility method  :py:meth:`getAccommodationDetails<waeup.kofa.students.utils.StudentsUtils.getAccommodationDetails>` composes a bed type string. Three criteria are checked: Is the student a new, a returning or a final year student? Is the student female or male? Has the student to be accommodated in a special hostel (`IHostel.special_handling`)? The resulting bed type string contains these information. Example: ``regular_female_fr`` means that a bed for a new female student in a regular hostel is wanted. If the student record allows to determine such a bed string, Kofa starts searching a proper bed space.
     204
     205Before Kofa searches for a free bed space, which meets the bed type criteria above, it checks if a bed space has already been allocated manually to the student. If so, then this bed is used, no matter whether the bed meets the criteria or not. (Theoretically, a male student can be accommodated in a hostel which is reserved for female students.) If no manually allocated bed space is found, Kofa searches for the right space. If bed booking is subject to a charge, Kofa also checks, if the student has entered a valid activation code, before delivering the bed coordinates to the student.
     206
     207
    191208Bed Relocation
    192209--------------
    193210
     211Officers with  `ManageHostels` permission do see a 'Relocate student' link button which calls the `BedTicketRelocationPage`. This view relocates the student if student parameters or the bed type of the bed have changed. The `update` method of this view checks first if the student has a 'reserved' bed space. Students in reserved beds are never subject to relocation. It checks secondly if booking has been cancelled in the accommodation section but other bed space has been manually allocated after cancellation. Then this bed is used, no matter whether the bed meets the bed type criteria or not. If both checks are negative, Kofa searches for a free bed space, which meets the student's bed type criteria. Only if it finds a new and free bed space, it starts the relocation process by releasing the old bed, booking the new bed and designating the new bed in the bed ticket.
     212
     213.. seealso::
     214
     215  :ref:`Bed Space Booking Doctests <test_handle_accommodation>`
    194216
    195217
  • main/waeup.kofa/trunk/docs/source/userdocs/testing.rst

    r13046 r13047  
    178178
    179179The first test can be found in
    180 `waeup.kofa.browser.tests.test_browser.SupplementaryBrowserTests`:
    181 
    182 .. literalinclude:: ../../../src/waeup/kofa/browser/tests/test_browser.py
    183    :pyobject: test_suspended_officer
    184 
    185 This test makes sure that a suspended officers can't login but see a
     180`waeup.kofa.browser.tests.test_browser.SupplementaryBrowserTests`. The test makes sure that suspended officers can't login but see a
    186181proper warning message when trying to login. Furthermore, suspended
    187182officer accounts are clearly marked and a warning message shows up
     
    189184<officers>`.
    190185
     186.. literalinclude:: ../../../src/waeup/kofa/browser/tests/test_browser.py
     187   :pyobject: test_suspended_officer
     188
    191189
    192190.. _test_handle_clearance:
    193191
    194 Handle Clearance by Clearance Officer
    195 -------------------------------------
    196 
    197 This test can be found in
    198 `waeup.kofa.students.tests.test_browser.OfficerUITests`:
     192Handling Clearance by Clearance Officer
     193---------------------------------------
     194
     195This test can be found in
     196`waeup.kofa.students.tests.test_browser.OfficerUITests`. The corresponding use
     197case is partly described :ref:`elsewhere <rejecting_clearance>`.
    199198
    200199.. literalinclude:: ../../../src/waeup/kofa/students/tests/test_browser.py
     
    204203.. _test_handle_courses:
    205204
    206 Handle Course List Validation by Course Adviser
    207 -----------------------------------------------
    208 
    209 This test can be found in
    210 `waeup.kofa.students.tests.test_browser.OfficerUITests`:
     205Handling Course List Validation by Course Adviser
     206-------------------------------------------------
     207
     208This test can be found in
     209`waeup.kofa.students.tests.test_browser.OfficerUITests`. The corresponding use
     210case is described :ref:`elsewhere <course_registration>`.
    211211
    212212.. literalinclude:: ../../../src/waeup/kofa/students/tests/test_browser.py
     
    220220
    221221This test can be found in
    222 `waeup.kofa.students.tests.test_browser.OfficerUITests`:
     222`waeup.kofa.students.tests.test_browser.OfficerUITests`. The corresponding use
     223case is described :ref:`elsewhere <batch_editing_scores>`.
    223224
    224225.. literalinclude:: ../../../src/waeup/kofa/students/tests/test_browser.py
    225226   :pyobject: test_handle_courses_by_lecturer
     227
     228
     229.. _test_handle_accommodation:
     230
     231Bed Space Booking
     232-----------------
     233
     234This test can be found in
     235`waeup.kofa.students.tests.test_browser.OfficerUITests`. The corresponding use
     236case is described :ref:`elsewhere <bed_tickets>`.
     237
     238.. literalinclude:: ../../../src/waeup/kofa/students/tests/test_browser.py
     239   :pyobject: test_student_accommodation
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r13040 r13047  
    20522052                self.flash(_('System error: Please contact the adminsitrator.'),
    20532053                           type="danger")
    2054                 self.context.writeLogMessage(self, 'fatal error: %s' % bed.bed_id)
     2054                self.context.writeLogMessage(
     2055                    self, 'fatal error: %s' % bed.bed_id)
    20552056                return
    20562057        else:
     
    20632064                students_utils = getUtility(IStudentsUtils)
    20642065                bed = students_utils.selectBed(available_beds)
    2065                 # Safety belt for paranoids: Does this bed really exist in portal?
     2066                # Safety belt for paranoids: Does this bed really exist
     2067                # in portal?
    20662068                # XXX: Can be remove if nobody complains.
    20672069                if bed.__parent__.__parent__ is None:
    2068                     self.flash(_('System error: Please contact the adminsitrator.'),
    2069                                type="warning")
    2070                     self.context.writeLogMessage(self, 'fatal error: %s' % bed.bed_id)
     2070                    self.flash(_(
     2071                        'System error: Please contact the adminsitrator.'),
     2072                        type="warning")
     2073                    self.context.writeLogMessage(
     2074                        self, 'fatal error: %s' % bed.bed_id)
    20712075                    return
    20722076                bed.bookBed(student.student_id)
     
    22192223            self.context.bed.owner = NOT_OCCUPIED
    22202224            notify(grok.ObjectModifiedEvent(self.context.bed))
    2221         # Alocate new bed
     2225        # Designate new bed in ticket
    22222226        self.context.bed_type = acc_details['bt']
    22232227        self.context.bed = new_bed
     
    27882792
    27892793class StudentRequestPasswordPage(KofaAddFormPage):
    2790     """Captcha'd registration page for applicants.
     2794    """Captcha'd request password page for students.
    27912795    """
    27922796    grok.name('requestpw')
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r13046 r13047  
    14761476            '...<div>Academics Officer (view only)</div>...',
    14771477            self.browser.contents)
    1478         #self.assertMatches(
    1479         #    '...<div>Students Officer (view only)</div>...',
    1480         #    self.browser.contents)
    14811478        # But not his local role ...
    14821479        self.assertFalse('Clearance Officer' in self.browser.contents)
     
    14841481        # has changed
    14851482        notify(LocalRoleSetEvent(
    1486             self.department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
     1483            self.department, 'waeup.local.ClearanceOfficer', 'mrclear',
     1484            granted=True))
    14871485        self.browser.open('http://localhost/app/users/mrclear/my_roles')
    14881486        self.assertTrue('Clearance Officer' in self.browser.contents)
     
    15251523            self.browser.url, self.student_path + '/reject_clearance')
    15261524        # Type comment why
    1527         self.browser.getControl(name="form.officer_comment").value = """Dear Student,
    1528 You did not fill properly.
    1529 """
     1525        self.browser.getControl(name="form.officer_comment").value = (
     1526            'Dear Student,\n'
     1527            'You did not fill properly.')
    15301528        self.browser.getControl("Save comment").click()
    15311529        self.assertTrue('Clearance has been annulled' in self.browser.contents)
    15321530        url = ('http://localhost/app/students/K1000000/'
    15331531              'contactstudent?body=Dear+Student%2C%0AYou+did+not+fill+properly.'
    1534               '%0A&subject=Clearance+has+been+annulled.')
     1532              '&subject=Clearance+has+been+annulled.')
    15351533        # CO does now see the prefilled contact form and can send a message
    15361534        self.assertEqual(self.browser.url, url)
     
    15451543        # The comment has been stored ...
    15461544        self.assertEqual(self.student.officer_comment,
    1547             u'Dear Student,\nYou did not fill properly.\n')
     1545            u'Dear Student,\nYou did not fill properly.')
    15481546        # ... and logged
    15491547        logfile = os.path.join(
     
    15531551            'INFO - mrclear - students.browser.StudentRejectClearancePage - '
    15541552            'K1000000 - comment: Dear Student,<br>You did not fill '
    1555             'properly.<br>\n' in logcontent)
     1553            'properly.\n' in logcontent)
    15561554        self.browser.open(self.history_path)
    15571555        self.assertTrue("Reset to 'clearance started' by My Public Name" in
     
    16011599        # Additional setups according to test above
    16021600        notify(LocalRoleSetEvent(
    1603             self.department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
     1601            self.department, 'waeup.local.ClearanceOfficer', 'mrclear',
     1602            granted=True))
    16041603        self.app['configuration']['2004'].clearance_enabled = True
    16051604        IWorkflowState(self.student).setState('clearance requested')
     
    29712970
    29722971    def test_student_accommodation(self):
    2973         # Login
    29742972        self.browser.open(self.login_path)
    29752973        self.browser.getControl(name="form.login").value = self.student_id
    29762974        self.browser.getControl(name="form.password").value = 'spwd'
    29772975        self.browser.getControl("Login").click()
    2978 
    29792976        # Students can add online booking fee payment tickets and open the
    29802977        # callback view (see test_manage_payments)
     
    29932990        parts = pin.split('-')[1:]
    29942991        sfeseries, sfenumber = parts
    2995 
    29962992        # Students can use HOS code and book a bed space with it ...
    29972993        self.browser.open(self.acco_path)
     
    30293025        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
    30303026                           self.browser.contents)
    3031 
    30323027        # Bed has been allocated
    30333028        bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
    30343029        self.assertTrue(bed.owner == self.student_id)
    3035 
    30363030        # BedTicketAddPage is now blocked
    30373031        self.browser.getLink("Book accommodation").click()
    30383032        self.assertMatches('...You already booked a bed space...',
    30393033            self.browser.contents)
    3040 
    30413034        # The bed ticket displays the data correctly
    30423035        self.browser.open(self.acco_path + '/2004')
     
    30463039        self.assertMatches('...regular_male_fr...', self.browser.contents)
    30473040        self.assertMatches('...%s...' % pin, self.browser.contents)
    3048 
    30493041        # Students can open the pdf slip
    30503042        self.browser.open(self.browser.url + '/bed_allocation_slip.pdf')
    30513043        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    30523044        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
    3053 
    30543045        # Students can't relocate themselves
    30553046        self.assertFalse('Relocate' in self.browser.contents)
     
    30573048        self.assertRaises(
    30583049            Unauthorized, self.browser.open, relocate_path)
    3059 
    30603050        # Students can't the Remove button and check boxes
    30613051        self.browser.open(self.acco_path)
    30623052        self.assertFalse('Remove' in self.browser.contents)
    30633053        self.assertFalse('val_id' in self.browser.contents)
    3064 
    30653054        # Students can pay maintenance fee now
    30663055        self.browser.open(self.payments_path)
     
    30703059        self.assertMatches('...Payment ticket created...',
    30713060                           self.browser.contents)
    3072 
    30733061        ctrl = self.browser.getControl(name='val_id')
    30743062        value = ctrl.options[0]
Note: See TracChangeset for help on using the changeset viewer.