Ignore:
Timestamp:
20 Apr 2020, 06:30:54 (5 years ago)
Author:
Henrik Bettermann
Message:

Improve referee reports.

Location:
main/waeup.kofa/trunk/src/waeup/kofa
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py

    r16058 r16059  
    594594
    595595    @property
     596    def display_refereereports(self):
     597        if self.context.refereereports:
     598            return True
     599        return False
     600
     601    @property
    596602    def file_links(self):
    597603        html = ''
     
    11901196    manage_applications = False
    11911197    submit_state = PAID
     1198    mandate_days = 7
    11921199
    11931200    @property
     
    12891296            if referee.email_sent:
    12901297                continue
    1291             mandate = RefereeReportMandate(days=7)
     1298            mandate = RefereeReportMandate(days=self.mandate_days)
    12921299            mandate.params['name'] = referee.name
    12931300            mandate.params['email'] = referee.email
     
    12961303                    self.context.__parent__.code,
    12971304                    self.context.application_number)
     1305            mandate.params['redirect_path2'] = ''
     1306            mandate.params['applicant_id'] = self.context.applicant_id
    12981307            site['mandates'].addMandate(mandate)
    12991308            # Send invitation email
     
    13581367        # for file storage.
    13591368        image = getUtility(IExtFileStore).getFileByContext(self.context)
    1360         self.response.setHeader(
    1361             'Content-Type', 'image/jpeg')
     1369        self.response.setHeader('Content-Type', 'image/jpeg')
    13621370        if image is None:
    13631371            # show placeholder image
    13641372            return open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb').read()
    13651373        return image
     1374
     1375class PassportImageForReport(PassportImage):
     1376    """Renders the passport image for applicants for referee reports.
     1377    """
     1378    grok.name('passport_for_report.jpg')
     1379    grok.context(IApplicant)
     1380    grok.require('waeup.Public')
     1381
     1382    def render(self):
     1383        # Check mandate
     1384        form = self.request.form
     1385        self.mandate_id = form.get('mandate_id', None)
     1386        self.mandates = grok.getSite()['mandates']
     1387        mandate = self.mandates.get(self.mandate_id, None)
     1388        if mandate is None:
     1389            self.flash(_('No mandate.'), type='warning')
     1390            self.redirect(self.application_url())
     1391            return
     1392        if mandate:
     1393            # Check the mandate expiration date after redirect again
     1394            if mandate.expires < datetime.utcnow():
     1395                self.flash(_('Mandate expired.'),
     1396                           type='warning')
     1397                self.redirect(self.application_url())
     1398                return
     1399            # Check if mandate allows access
     1400            if mandate.params.get('applicant_id') != self.context.applicant_id:
     1401                self.flash(_('Wrong mandate.'),
     1402                           type='warning')
     1403                self.redirect(self.application_url())
     1404                return
     1405            return super(PassportImageForReport, self).render()
     1406        return
    13661407
    13671408class ApplicantRegistrationPage(KofaAddFormPage):
     
    16861727        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    16871728
     1729class RemoveRefereeReportPage(UtilityView, grok.View):
     1730    """
     1731    """
     1732    grok.context(IApplicantRefereeReport)
     1733    grok.name('remove')
     1734    grok.require('waeup.manageApplication')
     1735
     1736    def update(self):
     1737        redirect_url = self.url(self.context.__parent__)
     1738        self.context.__parent__.writeLogMessage(
     1739            self, 'removed: %s' % self.context.r_id)
     1740        del self.context.__parent__[self.context.r_id]
     1741        self.flash(_('Referee report removed.'))
     1742        self.redirect(redirect_url)
     1743        return
     1744
     1745    def render(self):
     1746        return
     1747
    16881748class RefereeReportAddFormPage(KofaAddFormPage):
    16891749    """Add-form to add an referee report. This form
     
    16961756        IApplicantRefereeReport).omit('creation_date')
    16971757    grok.template('refereereportpage')
    1698     label = _('Add referee report')
     1758    label = _('Referee Report Form')
    16991759    pnav = 3
    17001760    #doclink = DOCLINK + '/refereereports.html'
     
    17171777            self.redirect(self.application_url())
    17181778            return
    1719         self.passport_url = self.url(self.context, 'passport.jpg')
    17201779        if mandate:
    17211780            # Check the mandate expiration date after redirect again
     
    17251784                self.redirect(self.application_url())
    17261785                return
     1786            args = {'mandate_id':mandate.mandate_id}
     1787            # Check if report exists.
     1788            # If so, redirect to the pdf file.
     1789            if mandate.params.get('redirect_path2'):
     1790                self.redirect(
     1791                    self.application_url() +
     1792                    mandate.params.get('redirect_path2') +
     1793                    '?%s' % urlencode(args))
     1794                return
    17271795            # Prefill form with mandate params
    17281796            self.form_fields.get(
     
    17301798            self.form_fields.get(
    17311799                'email').field.default = mandate.params['email']
     1800            self.passport_url = self.url(
     1801                self.context, 'passport_for_report.jpg') + '?%s' % urlencode(args)
    17321802        super(RefereeReportAddFormPage, self).update()
    17331803        return
     
    17441814        self.applyData(report, **data)
    17451815        self.context[report.r_id] = report
    1746         self.flash(_('Referee report has been saved. Thank you!'))
     1816        # self.flash(_('Referee report has been saved. Thank you!'))
    17471817        self.context.writeLogMessage(self, 'added: %s' % report.r_id)
    1748         # Delete mandate
    1749         del self.mandates[self.mandate_id]
    1750         self.redirect(self.application_url())
     1818        # Changed on 19/04/20: We do no longer delete the mandate
     1819        # but set path to redirect to the pdf file
     1820        self.mandates[self.mandate_id].params[
     1821            'redirect_path2'] = '/applicants/%s/%s/%s/referee_report.pdf' % (
     1822                self.context.__parent__.code,
     1823                self.context.application_number,
     1824                report.r_id)
     1825        notify(grok.ObjectModifiedEvent(self.mandates[self.mandate_id]))
     1826        args = {'mandate_id':self.mandate_id}
     1827        self.redirect(self.url(report, 'referee_report.pdf')
     1828                      + '?%s' % urlencode(args))
    17511829        return
    17521830
     
    17831861            self.context.__parent__, applicantview, note=self.note)
    17841862
     1863class ExportPDFReportSlipPage2(ExportPDFReportSlipPage):
     1864    """Deliver a PDF slip of the context to referees.
     1865    """
     1866    grok.name('referee_report.pdf')
     1867    grok.require('waeup.Public')
     1868
     1869    def update(self):
     1870        # Check mandate
     1871        form = self.request.form
     1872        self.mandate_id = form.get('mandate_id', None)
     1873        self.mandates = grok.getSite()['mandates']
     1874        mandate = self.mandates.get(self.mandate_id, None)
     1875        if mandate is None:
     1876            self.flash(_('No mandate.'), type='warning')
     1877            self.redirect(self.application_url())
     1878            return
     1879        if mandate:
     1880            # Check the mandate expiration date after redirect again
     1881            if mandate.expires < datetime.utcnow():
     1882                self.flash(_('Mandate expired.'),
     1883                           type='warning')
     1884                self.redirect(self.application_url())
     1885                return
     1886            # Check if form has really been submitted
     1887            if not mandate.params.get('redirect_path2') \
     1888                or mandate.params.get(
     1889                    'applicant_id') != self.context.__parent__.applicant_id:
     1890                self.flash(_('Wrong mandate.'),
     1891                           type='warning')
     1892                self.redirect(self.application_url())
     1893                return
     1894            super(ExportPDFReportSlipPage2, self).update()
     1895        return
     1896
    17851897class AdditionalFile(grok.View):
    17861898    """Renders additional pdf files for applicants.
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/applicantdisplaypage.pt

    r15946 r16059  
    5151  </tbody>
    5252</table>
     53
     54<tal:refereereports condition="view/display_refereereports">
     55  <br /><br />
     56  <h3 i18n:translate="">
     57      Referee Reports
     58  </h3>
     59  <table i18n:domain="waeup.kofa" class="table table-condensed">
     60    <thead>
     61    <tr>
     62      <th i18n:translate="">Report Id</th>
     63      <th i18n:translate="">Creation Date</th>
     64      <th i18n:translate="">Referee</th>
     65      <th i18n:translate="">Email Address</th>
     66    </tr>
     67    </thead>
     68    <tbody>
     69      <tr tal:repeat="cl context/refereereports">
     70        <td> <a tal:attributes="href python:view.url(cl)">
     71          <span tal:content="cl/r_id">RID</span></a></td>
     72        <td tal:content="python: layout.formatDatetime(cl.creation_date)">CREATION DATE</td>
     73        <td tal:content="cl/name">REFEREE</td>
     74        <td tal:content="cl/email">EMAIL</td>
     75      </tr>
     76    </tbody>
     77  </table>
     78</tal:refereereports>
     79
    5380<tal:payments condition="view/display_payments">
    5481  <h3 i18n:domain="waeup.kofa" i18n:translate="">
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/refereereportpage.pt

    r16058 r16059  
     1
     2
    13<p i18n:domain="waeup.kofa" i18n:translate="referee_welcome">
    24  You have been invited to report about
     
    1416  </strong>
    1517  of the <span i18n:name="app_title" tal:replace="layout/getAppTitle"></span>.
    16  
    17   <br /><br />
     18</p>
    1819
    19   <img tal:condition="python: context.__parent__.with_picture"
    20        src="" height="180px" tal:attributes="src view/passport_url" />
     20<img tal:condition="python: context.__parent__.with_picture"
     21src="" height="180px" tal:attributes="src view/passport_url" />
    2122
    22   <br /><br />
     23<br /><br />
    2324
    24   Please fill and submit the following referee report form. After submission
    25   the form will be locked. You can neither view nor edit
    26   your report after submission.
     25<p i18n:translate="">
     26Please fill and submit the following referee report form.
     27After submission the form will be locked and a report pdf
     28file will be available for download.
    2729</p>
    2830
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py

    r16058 r16059  
    16611661        mandate.params['name'] = u'John Referee'
    16621662        mandate.params['email'] = 'aa@aa.aa'
     1663        mandate.params['applicant_id'] = self.applicant.applicant_id
    16631664        mandate.params[
    16641665            'redirect_path'] = '/applicants/%s/%s/addrefereereport' % (
     
    16921693            in self.browser.contents)
    16931694        self.assertEqual(self.browser.url, 'http://localhost/app')
     1695        return
    16941696
    16951697    def test_add_and_view_reports(self):
     
    16971699        mandate.params['name'] = u'John Referee'
    16981700        mandate.params['email'] = 'aa@aa.aa'
    1699         mandate.params[
    1700             'redirect_path'] = '/applicants/%s/%s/addrefereereport' % (
     1701        mandate.params['applicant_id'] = self.applicant.applicant_id
     1702        mandate.params['redirect_path'] = '/applicants/%s/%s/addrefereereport' % (
    17011703                container_name_1, self.applicant.application_number)
     1704        mandate.params['redirect_path2'] = ''
    17021705        self.app['mandates'].addMandate(mandate)
    17031706        self.assertEqual(len(self.app['mandates'].keys()), 1)
     
    17121715        self.browser.getControl(name="form.email").value = 'bb@bb.bb'
    17131716        self.browser.getControl("Submit").click()
    1714         self.assertTrue('Referee report has been saved' in self.browser.contents)
    1715         self.assertEqual(self.browser.url, 'http://localhost/app')
     1717        # Referee wil be redirected to a pdf file
     1718        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     1719        self.assertEqual(self.browser.headers['Content-Type'],
     1720                         'application/pdf')
     1721        path = os.path.join(samples_dir(), 'referee_report.pdf')
     1722        open(path, 'wb').write(self.browser.contents)
     1723        print "Sample PDF referee_report.pdf written to %s" % path
    17161724        # Report has been created
    17171725        self.assertEqual(len(self.applicant.refereereports), 1)
    17181726        report = self.applicant.refereereports[0]
     1727        # Referee can use mandate again to download the pdf report
     1728        self.browser.open('http://localhost/app/mandate?mandate_id=%s'
     1729            % mandate.mandate_id)
     1730        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     1731        self.assertEqual(self.browser.headers['Content-Type'],
     1732                         'application/pdf')
    17191733        # Managers can view the report
    17201734        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     
    17251739        self.assertTrue('John Referee' in self.browser.contents)
    17261740        # Managers can download a pdf slip
    1727         self.browser.getLink("Download report").click()
     1741        self.browser.getLink("Download referee report").click()
    17281742        self.assertEqual(self.browser.headers['Status'], '200 Ok')
    17291743        self.assertEqual(self.browser.headers['Content-Type'],
     
    17321746        open(path, 'wb').write(self.browser.contents)
    17331747        print "Sample PDF referee_report_slip.pdf written to %s" % path
    1734         # Report creation is logged
     1748        # Mandate is not deleted ...
     1749        self.assertEqual(len(self.app['mandates'].keys()), 1)
     1750        # ... but redirect_path2 attribute has been set
     1751        redirect_path2 = '/applicants/%s/%s/%s/referee_report.pdf' % (
     1752                container_name_1,
     1753                self.applicant.application_number,
     1754                report.r_id)
     1755        self.assertEqual(
     1756            self.app['mandates'].values()[0].params['redirect_path2'],
     1757            redirect_path2)
     1758        # Managers can delete referee reports
     1759        self.browser.open(self.manage_path)
     1760        self.browser.getLink("%s" % report.r_id).click()
     1761        self.assertEqual(len(self.applicant.refereereports), 1)
     1762        self.browser.getLink("Delete").click()
     1763        self.assertEqual(len(self.applicant.refereereports), 0)
     1764        self.assertTrue('Referee report removed.' in self.browser.contents)
     1765        self.assertEqual(self.browser.url, self.view_path)
     1766        # Report creation and deletion is logged
    17351767        logfile = os.path.join(
    17361768            self.app['datacenter'].storage, 'logs', 'applicants.log')
     
    17391771            'zope.anybody - applicants.browser.RefereeReportAddFormPage - '
    17401772            '%s - added: %s\n' % (self.applicant.applicant_id, report.r_id)
    1741             in logcontent
    1742             )
    1743         # Mandate is deleted
    1744         self.assertEqual(len(self.app['mandates'].keys()), 0)
     1773            in logcontent)
     1774        self.assertTrue(
     1775            'zope.mgr - applicants.browser.RemoveRefereeReportPage - '
     1776            '%s - removed: %s\n' % (self.applicant.applicant_id, report.r_id)
     1777            in logcontent)
     1778        return
    17451779
    17461780    def test_final_submit_with_referees(self):
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/utils.py

    r15946 r16059  
    4747      'form.course1': _(u'Desired Study Courses'),
    4848      'form.notice': _(u'Application Process Data'),
     49      'form.referees': _(u'Referees (automatically invited by email '
     50                          'after final submission of this form)'),
    4951      }
    5052
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/viewlets.py

    r16058 r16059  
    286286        return self.view.url(self.view.context, self.target)
    287287
    288 class ReportSlipActionButton(ManageActionButton):
    289     grok.order(1)
    290     grok.context(IApplicantRefereeReport)
    291     grok.view(RefereeReportDisplayFormPage)
    292     grok.require('waeup.manageApplication')
    293     icon = 'actionicon_pdf.png'
    294     text = _('Download report slip')
    295     target = 'referee_report_slip.pdf'
    296 
    297     @property
    298     def target_url(self):
    299         return self.view.url(self.view.context, self.target)
    300 
    301288class ApprovePaymentActionButton(ManageActionButton):
    302289    grok.order(8)
     
    313300            return ''
    314301        return self.view.url(self.view.context, self.target)
     302
     303class ReportSlipActionButton(ManageActionButton):
     304    grok.order(1)
     305    grok.context(IApplicantRefereeReport)
     306    grok.view(RefereeReportDisplayFormPage)
     307    grok.require('waeup.manageApplication')
     308    icon = 'actionicon_pdf.png'
     309    text = _('Download referee report slip')
     310    target = 'referee_report_slip.pdf'
     311
     312    @property
     313    def target_url(self):
     314        return self.view.url(self.view.context, self.target)
     315
     316deletion_warning = _(
     317    "'The report will be irrevocably deleted. Are you sure?'")
     318
     319class ReportRemoveActionButton(ManageActionButton):
     320    grok.order(2)
     321    grok.context(IApplicantRefereeReport)
     322    grok.view(RefereeReportDisplayFormPage)
     323    grok.require('waeup.manageApplication')
     324    icon = 'actionicon_reject.png'
     325    text = _('Delete referee report')
     326    target = 'remove'
     327
     328    @property
     329    def onclick(self):
     330        return "return window.confirm(%s);" % deletion_warning
  • main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py

    r15664 r16059  
    296296        constraint=validate_email,
    297297        description = _(
    298             u'Email Address (referees will be automatically invited by email '
    299              'after final submission of this form)'),
     298            u'Email Address'),
    300299        )
    301300
  • main/waeup.kofa/trunk/src/waeup/kofa/mandates/mandate.py

    r15609 r16059  
    112112class RefereeReportMandate(Mandate):
    113113    """This is a mandate which can unlock a `RefereeReportAddFormPage`.
    114     The mandate is not automatically deleted. This has to be done
    115     by the submit method of the add form page.
     114    The mandate is not automatically deleted.
    116115    """
    117116
Note: See TracChangeset for help on using the changeset viewer.