Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py	(revision 13975)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py	(revision 13976)
@@ -23,4 +23,5 @@
 import transaction
 from datetime import datetime, date
+from time import time
 from zope.event import notify
 from zope.component import getUtility, queryUtility, createObject, getAdapter
@@ -33,5 +34,6 @@
     IApplicantsContainer, IApplicantsContainerAdd,
     MAX_UPLOAD_SIZE, IApplicantOnlinePayment, IApplicantsUtils,
-    IApplicantRegisterUpdate, ISpecialApplicant
+    IApplicantRegisterUpdate, ISpecialApplicant,
+    IApplicantRefereeReport
     )
 from waeup.kofa.utils.helpers import html2dict
@@ -284,4 +286,13 @@
         return self.context.p_id
 
+class RefereeReportBreadcrumb(Breadcrumb):
+    """A breadcrumb for referee reports.
+    """
+    grok.context(IApplicantRefereeReport)
+
+    @property
+    def title(self):
+        return self.context.r_id
+
 class ApplicantsStatisticsPage(KofaDisplayFormPage):
     """Some statistics about applicants in a container.
@@ -900,4 +911,10 @@
             return True
         return getattr(self.context.__parent__, 'application_fee', None)
+
+    @property
+    def display_refereereports(self):
+        if self.context.refereereports:
+            return True
+        return False
 
     @property
@@ -1059,4 +1076,8 @@
     manage_applications = False
     submit_state = PAID
+
+    @property
+    def display_refereereports(self):
+        return False
 
     @property
@@ -1475,2 +1496,48 @@
     grok.context(VirtualApplicantsExportJobContainer)
     grok.require('waeup.manageApplication')
+
+class RefereeReportDisplayFormPage(KofaDisplayFormPage):
+    """A display view for referee reports.
+    """
+    grok.context(IApplicantRefereeReport)
+    grok.name('index')
+    grok.require('waeup.manageApplication')
+    label = _('Referee Report')
+    pnav = 3
+
+class RefereeReportAddFormPage(KofaAddFormPage):
+    """Add-form to add an referee report. This form
+    is protected by a mandate. (not yet ready)
+    """
+    grok.context(IApplicant)
+    grok.require('waeup.manageApplication') # XXX: Will be public
+    grok.name('addrefereereport')
+    form_fields = grok.AutoFields(
+        IApplicantRefereeReport).omit('creation_date')
+    label = _('Add referee report')
+    pnav = 3
+    #doclink = DOCLINK + '/refereereports.html'
+
+    def update(self):
+        # XXX: Check mandate
+        super(RefereeReportAddFormPage, self).update()
+        return
+
+    @action(_('Submit'),
+              warning=_('Are you really sure? '
+                        'Reports can neither be modified or added '
+                        'after submission.'),
+              style='primary')
+    def addRefereeReport(self, **data):
+        report = createObject(u'waeup.ApplicantRefereeReport')
+        timestamp = ("%d" % int(time()*10000))[1:]
+        report.r_id = "r%s" % timestamp
+        self.applyData(report, **data)
+        self.context[report.r_id] = report
+        self.flash(_('Referee report created.'))
+        self.context.writeLogMessage(self, 'added: %s' % report.r_id)
+        # XXX: Email has to be sent.
+        # XXX: Will be replaced by landing page
+        self.redirect(
+            self.url(self.context[report.r_id], 'index'))
+        return
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/applicanteditpage.pt
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/applicanteditpage.pt	(revision 13975)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/applicanteditpage.pt	(revision 13976)
@@ -87,4 +87,30 @@
   </div>
 
+  <tal:refereereports condition="view/display_refereereports">
+    <br /><br />
+    <h3 i18n:translate="">
+        Referee Reports
+    </h3>
+    <table i18n:domain="waeup.kofa" class="table table-condensed">
+      <thead>
+      <tr>
+        <th i18n:translate="">Report Id</th>
+        <th i18n:translate="">Creation Date</th>
+        <th i18n:translate="">Referee</th>
+        <th i18n:translate="">Email Address</th>
+      </tr>
+      </thead>
+      <tbody>
+        <tr tal:repeat="cl context/refereereports">
+          <td> <a tal:attributes="href python:view.url(cl)">
+            <span tal:content="cl/r_id">RID</span></a></td>
+          <td tal:content="python: layout.formatDatetime(cl.creation_date)">CREATION DATE</td>
+          <td tal:content="cl/name">REFEREE</td>
+          <td tal:content="cl/email">EMAIL</td>
+        </tr>
+      </tbody>
+    </table>
+  </tal:refereereports>
+
   <tal:payments condition="view/display_payments">
     <br /><br />
@@ -107,8 +133,7 @@
       <tbody>
         <tr tal:repeat="cl context/payments">
-           <td>
-            <input type="checkbox"
-      		 name="val_id"
-      		 tal:attributes="value cl/__name__"
+          <td>
+           <input type="checkbox"  name="val_id"
+           tal:attributes="value cl/__name__"
            tal:condition="python: not view.unremovable(cl)" />
           </td>
@@ -117,7 +142,7 @@
           <td tal:content="python: layout.formatDatetime(cl.creation_date)">CREATION DATE</td>
           <td tal:content="python: layout.formatDatetime(cl.payment_date)">PAYMENT DATE</td>
-        <td tal:content ="cl/category">CATEGORY</td>
-        <td tal:content ="cl/display_item">ITEM</td>
-        <td tal:content ="cl/p_state_title">STATE</td>
+          <td tal:content ="cl/category">CATEGORY</td>
+          <td tal:content ="cl/display_item">ITEM</td>
+          <td tal:content ="cl/p_state_title">STATE</td>
         </tr>
       </tbody>
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/interfaces.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/interfaces.py	(revision 13975)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/interfaces.py	(revision 13976)
@@ -635,4 +635,10 @@
     r_id = Attribute('Report identifier')
 
+    creation_date = schema.Datetime(
+        title = _(u'Ticket Creation Date'),
+        readonly = False,
+        required = False,
+        )
+
     name = schema.TextLine(
         title = _(u'Name'),
@@ -642,5 +648,5 @@
     email = schema.ASCIILine(
         title = _(u'Email Address'),
-        required = False,
+        required = True,
         constraint=validate_email,
         )
@@ -656,8 +662,2 @@
         required = False,
         )
-
-    creation_date = schema.Datetime(
-        title = _(u'Ticket Creation Date'),
-        readonly = False,
-        required = False,
-        )
Index: /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py	(revision 13975)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py	(revision 13976)
@@ -1519,2 +1519,34 @@
             '- discarded: job_id=%s' % job_ids[1] in logcontent
             )
+
+class ApplicantRefereeReportTests(ApplicantsFullSetup, FunctionalAsyncTestCase):
+    # Tests for ApplicantRefereeReport class views and pages
+
+    layer = FunctionalLayer
+
+    def test_add_and_view_reports(self):
+        # Managers can view reports
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.manage_path)
+        # So far no report has been added
+        self.assertFalse('Referee' in self.browser.contents)
+        # XXX: Form will be public
+        self.browser.open(self.view_path + '/addrefereereport')
+        self.browser.getControl(name="form.name").value = 'John Trust'
+        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
+        self.browser.getControl("Submit").click()
+        self.assertTrue('Referee report created' in self.browser.contents)
+        # Report has been created and we are viewing the report's index page
+        self.assertEqual(len(self.applicant.refereereports), 1)
+        report = self.applicant.refereereports[0]
+        self.assertEqual(
+            self.browser.url, self.view_path  + '/%s/index' % report.r_id)
+        # Report creation is logged
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'applicants.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'zope.mgr - applicants.browser.RefereeReportAddFormPage - '
+            '%s - added: %s\n' % (self.applicant.applicant_id, report.r_id)
+            in logcontent
+            )
