Index: main/waeup.kofa/trunk/CHANGES.txt
===================================================================
--- main/waeup.kofa/trunk/CHANGES.txt	(revision 15332)
+++ main/waeup.kofa/trunk/CHANGES.txt	(revision 15333)
@@ -4,4 +4,7 @@
 1.6.1.dev0 (unreleased)
 =======================
+
+* Add `transcript_remark` field to study levels. Add page to allow
+  transcript officers editing the field during transcript processing.
 
 * Increase password strength. Officers are now required
@@ -77,5 +80,5 @@
   faculty_code *and* department_code in create mode.
 
-* Add 'Update all tickets' button to StudyLevelEditFormPage.
+* Add 'Update all tickets' button to `StudyLevelEditFormPage`.
 
 * Do not allow to create more than 10 students with a single request to
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 15333)
@@ -1203,4 +1203,25 @@
     pnav = 4
 
+    @property
+    def remarks(self):
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        levelremarks = ''
+        studylevelsource = StudyLevelSource().factory
+        for studylevel in self.context.values():
+            leveltitle = studylevelsource.getTitle(
+                self.context, studylevel.level)
+            url = self.url(self.context) + '/%s/remark' % studylevel.level
+            button_title = translate(
+                _('Edit'), 'waeup.kofa', target_language=portal_language)
+            levelremarks += (
+                '<tr>'
+                '<td>%s:</td>'
+                '<td>%s</td> '
+                '<td><a class="btn btn-primary btn-xs" href="%s">%s</a></td>'
+                '</tr>'
+                ) % (
+                leveltitle, studylevel.transcript_remark, url, button_title)
+        return levelremarks
+
     def update(self, SUBMIT=None):
         super(StudentTranscriptValidateFormPage, self).update()
@@ -1252,4 +1273,15 @@
     buttonname = _('Save comment and release transcript')
     pnav = 4
+
+    @property
+    def remarks(self):
+        levelremarks = ''
+        studylevelsource = StudyLevelSource().factory
+        for studylevel in self.context.values():
+            leveltitle = studylevelsource.getTitle(
+                self.context, studylevel.level)
+            levelremarks += "%s: %s <br><br>" % (
+                leveltitle, studylevel.transcript_remark)
+        return levelremarks
 
     def update(self, SUBMIT=None):
@@ -1651,4 +1683,43 @@
                 (', '.join(deleted), self.context.level))
         self.redirect(self.url(self.context, u'@@manage')+'#tab2')
+        return
+
+class StudyLevelRemarkFormPage(KofaEditFormPage):
+    """ Page to edit the student study level transcript remark only
+    """
+    grok.context(IStudentStudyLevel)
+    grok.name('remark')
+    grok.require('waeup.processTranscript')
+    grok.template('studylevelremarkpage')
+    form_fields = grok.AutoFields(IStudentStudyLevel).omit('level')
+    form_fields['level_session'].for_display = True
+    form_fields['level_verdict'].for_display = True
+    form_fields['validation_date'].for_display = True
+    form_fields['validated_by'].for_display = True
+
+    def update(self, ADD=None, course=None):
+        if self.context.student.studycourse_locked:
+            emit_lock_message(self)
+            return
+        super(StudyLevelRemarkFormPage, self).update()
+
+    @property
+    def label(self):
+        lang = self.request.cookies.get('kofa.language')
+        level_title = translate(self.context.level_title, 'waeup.kofa',
+            target_language=lang)
+        return _('Edit transcript remark of level ${a}', mapping = {'a':level_title})
+
+    @property
+    def translated_values(self):
+        return translated_values(self)
+
+    @action(_('Save remark and go and back to transcript validation page'),
+        style='primary')
+    def save(self, **data):
+        msave(self, **data)
+        self.redirect(
+            self.url(self.context.student, 'studycourse/validate_transcript')
+            +'#tab4')
         return
 
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelremarkpage.pt
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelremarkpage.pt	(revision 15333)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelremarkpage.pt	(revision 15333)
@@ -0,0 +1,84 @@
+<form action="." tal:attributes="action request/URL" method="POST"
+      i18n:domain="waeup.kofa" enctype="multipart/form-data">
+
+  <ul class="tabs nav nav-tabs" data-tabs="tabs">
+    <li class="active">
+      <a href="#tab1" data-toggle="tab">
+        <span i18n:translate="">Study Level Data</span>
+      </a>
+    </li>
+    <li>
+      <a href="#tab2" data-toggle="tab">
+        <span i18n:translate="">Course Tickets</span>
+      </a>
+    </li>
+  </ul>
+
+  <div class="tab-content">
+    <div id="tab1" class="active tab-pane">
+      <br />
+      <table class="form-table">
+      <tbody>
+        <tal:widgets content="structure provider:widgets" />
+      </tbody>
+      </table>
+      <br />
+      <div tal:condition="view/availableActions">
+        <span tal:repeat="action view/actions"
+              tal:omit-tag="">
+          <input tal:replace="structure action/render"/>
+        </span>
+      </div>
+    </div>
+
+    <div id="tab2" class="tab-pane">
+      <br /><br />
+      <table class="kofa-data-table dataTable" i18n:domain="waeup.kofa">
+        <thead>
+          <tr>
+            <th i18n:translate="">Term</th>
+            <th i18n:translate="">Code</th>
+            <th i18n:translate="">Title</th>
+            <th i18n:translate="">Dep.</th>
+            <th i18n:translate="">Fac.</th>
+            <th i18n:translate="">Cred.</th>
+            <th i18n:translate="">Requ.</th>
+            <th i18n:translate="">Score</th>
+            <th i18n:translate="">Grade</th>
+            <th i18n:translate="">CO</th>
+            <th i18n:translate="">OS</th>
+            <th i18n:translate="">Auto</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr tal:repeat="value view/translated_values">
+            <td tal:content="value/semester" nowrap>TERM</td>
+            <td> <a tal:attributes="href value/url">
+            <span tal:content="value/code">CODE</span>
+            </a></td>
+            <td tal:content="value/title">TITLE</td>
+            <td tal:content="value/dcode">DEPARTMENT</td>
+            <td tal:content="value/fcode">FACULTY</td>
+            <td tal:content="value/credits">CREDITS</td>
+            <td tal:content="value/mandatory">MANDATORY</td>
+            <td tal:content="value/score|nothing">SCORE</td>
+            <td tal:content="value/grade|nothing">GRADE</td>
+            <td tal:content="value/carry_over">CO</td>
+            <td tal:content="value/outstanding">OS</td>
+            <td tal:content="value/automatic">AUTO</td>
+          </tr>
+        </tbody>
+      </table>
+
+      <p i18n:translate="">
+        CO: Carry-over course<br />
+        OS: Outstanding course<br />
+        Requ.: Required course<br />
+        Auto: Automatically created course ticket
+      </p>
+    </div>
+  </div>
+</form>
+
+
+
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/transcriptprocess.pt
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/transcriptprocess.pt	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/transcriptprocess.pt	(revision 15333)
@@ -15,4 +15,9 @@
       <a href="#tab3" data-toggle="tab">
         <span i18n:translate="">View signatures</span>
+      </a>
+    </li>
+    <li>
+      <a href="#tab4" data-toggle="tab">
+        <span i18n:translate="">View remarks</span>
       </a>
     </li>
@@ -50,4 +55,13 @@
       <br /><p tal:content="structure view/signees"></p>
     </div>
+
+    <div id="tab4" class="tab-pane">
+      <br />
+      <table class="table-condensed">
+        <tbody>
+          <span tal:omit-tag="" tal:content="structure view/remarks"></span>
+        </tbody>
+      </table>
+    </div>
   </div>
 
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 15333)
@@ -614,4 +614,10 @@
         )
 
+    transcript_remark = schema.TextLine(
+        title = _(u'Transcript Remark'),
+        required = False,
+        readonly = False,
+        )
+
     def addCourseTicket(ticket, course):
         """Add a course ticket object.
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/permissions.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/permissions.py	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/permissions.py	(revision 15333)
@@ -159,5 +159,6 @@
     """The Transcript Officer is allowed to view, to validate and to
     release student transcripts. The officer is not allowed to
-    manage student data.
+    manage student data but to edit the transcript remark on a separate
+    manage page.
     """
     grok.name('waeup.TranscriptOfficer')
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 15333)
@@ -490,7 +490,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,,,0,0,,,,0,\r\n'
+            '0.00,,,0,0,,,,,0,\r\n'
             )
         return
@@ -508,7 +508,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
             )
         return
@@ -524,7 +524,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
             )
         return
@@ -539,7 +539,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
             )
         return
@@ -558,7 +558,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
             )
         return
@@ -577,7 +577,7 @@
             result,
             'gpa,level,level_session,level_verdict,total_credits,'
-            'validated_by,validation_date,'
+            'transcript_remark,validated_by,validation_date,'
             'student_id,number_of_tickets,certcode\r\n'
-            '0.00,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
             )
         return
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 15332)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 15333)
@@ -295,7 +295,8 @@
         #sgpa = '%s: %.2f' % (trans('Sessional GPA (rectified)', lang), level['sgpa'])
         data.append(Paragraph(sgpa, style["Normal"]))
-        if getattr(level_obj, 'remark', None):
+        if getattr(level_obj, 'transcript_remark', None):
             remark = '%s: %s' % (
-                trans('Remark', lang), getattr(level_obj, 'remark'))
+                trans('Transcript Remark', lang),
+                getattr(level_obj, 'transcript_remark'))
             data.append(Paragraph(remark, style["Normal"]))
     return data
