- Timestamp:
- 20 Apr 2020, 06:30:54 (5 years ago)
- Location:
- main/waeup.kofa/trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/CHANGES.txt
r16046 r16059 4 4 1.6.1.dev0 (unreleased) 5 5 ======================= 6 7 * Improve referee reports. 6 8 7 9 * Use consistent flow value formatting for CGPA. -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py
r16058 r16059 594 594 595 595 @property 596 def display_refereereports(self): 597 if self.context.refereereports: 598 return True 599 return False 600 601 @property 596 602 def file_links(self): 597 603 html = '' … … 1190 1196 manage_applications = False 1191 1197 submit_state = PAID 1198 mandate_days = 7 1192 1199 1193 1200 @property … … 1289 1296 if referee.email_sent: 1290 1297 continue 1291 mandate = RefereeReportMandate(days= 7)1298 mandate = RefereeReportMandate(days=self.mandate_days) 1292 1299 mandate.params['name'] = referee.name 1293 1300 mandate.params['email'] = referee.email … … 1296 1303 self.context.__parent__.code, 1297 1304 self.context.application_number) 1305 mandate.params['redirect_path2'] = '' 1306 mandate.params['applicant_id'] = self.context.applicant_id 1298 1307 site['mandates'].addMandate(mandate) 1299 1308 # Send invitation email … … 1358 1367 # for file storage. 1359 1368 image = getUtility(IExtFileStore).getFileByContext(self.context) 1360 self.response.setHeader( 1361 'Content-Type', 'image/jpeg') 1369 self.response.setHeader('Content-Type', 'image/jpeg') 1362 1370 if image is None: 1363 1371 # show placeholder image 1364 1372 return open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb').read() 1365 1373 return image 1374 1375 class 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 1366 1407 1367 1408 class ApplicantRegistrationPage(KofaAddFormPage): … … 1686 1727 'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') 1687 1728 1729 class 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 1688 1748 class RefereeReportAddFormPage(KofaAddFormPage): 1689 1749 """Add-form to add an referee report. This form … … 1696 1756 IApplicantRefereeReport).omit('creation_date') 1697 1757 grok.template('refereereportpage') 1698 label = _(' Add referee report')1758 label = _('Referee Report Form') 1699 1759 pnav = 3 1700 1760 #doclink = DOCLINK + '/refereereports.html' … … 1717 1777 self.redirect(self.application_url()) 1718 1778 return 1719 self.passport_url = self.url(self.context, 'passport.jpg')1720 1779 if mandate: 1721 1780 # Check the mandate expiration date after redirect again … … 1725 1784 self.redirect(self.application_url()) 1726 1785 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 1727 1795 # Prefill form with mandate params 1728 1796 self.form_fields.get( … … 1730 1798 self.form_fields.get( 1731 1799 'email').field.default = mandate.params['email'] 1800 self.passport_url = self.url( 1801 self.context, 'passport_for_report.jpg') + '?%s' % urlencode(args) 1732 1802 super(RefereeReportAddFormPage, self).update() 1733 1803 return … … 1744 1814 self.applyData(report, **data) 1745 1815 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!')) 1747 1817 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)) 1751 1829 return 1752 1830 … … 1783 1861 self.context.__parent__, applicantview, note=self.note) 1784 1862 1863 class 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 1785 1897 class AdditionalFile(grok.View): 1786 1898 """Renders additional pdf files for applicants. -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/applicantdisplaypage.pt
r15946 r16059 51 51 </tbody> 52 52 </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 53 80 <tal:payments condition="view/display_payments"> 54 81 <h3 i18n:domain="waeup.kofa" i18n:translate=""> -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser_templates/refereereportpage.pt
r16058 r16059 1 2 1 3 <p i18n:domain="waeup.kofa" i18n:translate="referee_welcome"> 2 4 You have been invited to report about … … 14 16 </strong> 15 17 of the <span i18n:name="app_title" tal:replace="layout/getAppTitle"></span>. 16 17 <br /><br /> 18 </p> 18 19 19 20 20 <img tal:condition="python: context.__parent__.with_picture" 21 src="" height="180px" tal:attributes="src view/passport_url" /> 21 22 22 23 <br /><br /> 23 24 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=""> 26 Please fill and submit the following referee report form. 27 After submission the form will be locked and a report pdf 28 file will be available for download. 27 29 </p> 28 30 -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py
r16058 r16059 1661 1661 mandate.params['name'] = u'John Referee' 1662 1662 mandate.params['email'] = 'aa@aa.aa' 1663 mandate.params['applicant_id'] = self.applicant.applicant_id 1663 1664 mandate.params[ 1664 1665 'redirect_path'] = '/applicants/%s/%s/addrefereereport' % ( … … 1692 1693 in self.browser.contents) 1693 1694 self.assertEqual(self.browser.url, 'http://localhost/app') 1695 return 1694 1696 1695 1697 def test_add_and_view_reports(self): … … 1697 1699 mandate.params['name'] = u'John Referee' 1698 1700 mandate.params['email'] = 'aa@aa.aa' 1699 mandate.params[ 1700 1701 mandate.params['applicant_id'] = self.applicant.applicant_id 1702 mandate.params['redirect_path'] = '/applicants/%s/%s/addrefereereport' % ( 1701 1703 container_name_1, self.applicant.application_number) 1704 mandate.params['redirect_path2'] = '' 1702 1705 self.app['mandates'].addMandate(mandate) 1703 1706 self.assertEqual(len(self.app['mandates'].keys()), 1) … … 1712 1715 self.browser.getControl(name="form.email").value = 'bb@bb.bb' 1713 1716 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 1716 1724 # Report has been created 1717 1725 self.assertEqual(len(self.applicant.refereereports), 1) 1718 1726 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') 1719 1733 # Managers can view the report 1720 1734 self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') … … 1725 1739 self.assertTrue('John Referee' in self.browser.contents) 1726 1740 # Managers can download a pdf slip 1727 self.browser.getLink("Download re port").click()1741 self.browser.getLink("Download referee report").click() 1728 1742 self.assertEqual(self.browser.headers['Status'], '200 Ok') 1729 1743 self.assertEqual(self.browser.headers['Content-Type'], … … 1732 1746 open(path, 'wb').write(self.browser.contents) 1733 1747 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 1735 1767 logfile = os.path.join( 1736 1768 self.app['datacenter'].storage, 'logs', 'applicants.log') … … 1739 1771 'zope.anybody - applicants.browser.RefereeReportAddFormPage - ' 1740 1772 '%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 1745 1779 1746 1780 def test_final_submit_with_referees(self): -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/utils.py
r15946 r16059 47 47 'form.course1': _(u'Desired Study Courses'), 48 48 'form.notice': _(u'Application Process Data'), 49 'form.referees': _(u'Referees (automatically invited by email ' 50 'after final submission of this form)'), 49 51 } 50 52 -
main/waeup.kofa/trunk/src/waeup/kofa/applicants/viewlets.py
r16058 r16059 286 286 return self.view.url(self.view.context, self.target) 287 287 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 @property298 def target_url(self):299 return self.view.url(self.view.context, self.target)300 301 288 class ApprovePaymentActionButton(ManageActionButton): 302 289 grok.order(8) … … 313 300 return '' 314 301 return self.view.url(self.view.context, self.target) 302 303 class 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 316 deletion_warning = _( 317 "'The report will be irrevocably deleted. Are you sure?'") 318 319 class 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 296 296 constraint=validate_email, 297 297 description = _( 298 u'Email Address (referees will be automatically invited by email ' 299 'after final submission of this form)'), 298 u'Email Address'), 300 299 ) 301 300 -
main/waeup.kofa/trunk/src/waeup/kofa/mandates/mandate.py
r15609 r16059 112 112 class RefereeReportMandate(Mandate): 113 113 """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. 116 115 """ 117 116
Note: See TracChangeset for help on using the changeset viewer.