Changeset 10576 for main/waeup.kofa/trunk/src
- Timestamp:
- 2 Sep 2013, 06:42:16 (11 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa/students
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_results_presentation.py
r10574 r10576 25 25 from waeup.kofa.students.interfaces import IStudentsUtils 26 26 from waeup.kofa.interfaces import MessageFactory as _ 27 from waeup.kofa.browser.pdf import get_signature_tables 27 28 from waeup.kofa.reports import IReport 28 from waeup.kofa.browser.pdf import get_signature_tables 29 from waeup.kofa.students.reports.level_report import ( 30 ILevelReport, LevelReportGeneratorPage) 31 from waeup.kofa.students.reports.student_statistics import ( 32 StudentStatisticsReportPDFView) 29 33 34 35 class ISessionResultsPresentation(ILevelReport): 36 37 """ Same interface as for level reports. 38 """ 30 39 31 40 def get_students(faccode, depcode, session, level=None): … … 58 67 continue 59 68 else: 69 # XXX: Not yet supported by by generator page 60 70 itemcount = 0 61 71 for item in stud['studycourse'].values(): … … 73 83 return table 74 84 85 from reportlab.lib import colors 86 from reportlab.lib.styles import getSampleStyleSheet 87 from reportlab.lib.units import cm 88 from reportlab.platypus import Paragraph, Table, Spacer 89 from reportlab.platypus.flowables import Flowable 90 from waeup.kofa.reports import IReport, IReportGenerator 91 from waeup.kofa.reports import Report 92 from waeup.kofa.browser.interfaces import IPDFCreator 93 from waeup.kofa.university.vocabularies import course_levels 94 95 STYLE = getSampleStyleSheet() 96 97 TABLE_STYLE = [ 98 ('FONT', (0,0), (-1,-1), 'Helvetica', 8), 99 ('FONT', (0,0), (-1,0), 'Helvetica-Bold', 8), # 1st row 100 ('ALIGN', (3,1), (-1,-1), 'RIGHT'), 101 #('ALIGN', (1,0), (1,-1), 'LEFT'), 102 #('ALIGN', (2,0), (2,-1), 'LEFT'), 103 #('INNERGRID', (0,1), (-1,-1), 0.25, colors.black), 104 #('BOX', (0,1), (-1,-1), 1, colors.black), 105 ] 106 107 @implementer(ISessionResultsPresentation) 108 class SessionResultsPresentation(Report): 109 data = None 110 session = None 111 level = None 112 faccode = None 113 depcode = None 114 115 def __init__(self, faccode, depcode, session, level, author='System'): 116 super(SessionResultsPresentation, self).__init__( 117 args=[faccode, depcode, session, level], kwargs={'author':author}) 118 site = grok.getSite() 119 self.session = academic_sessions_vocab.getTerm(session).title 120 self.level = course_levels.getTerm(level).title 121 self.levelcode = level 122 self.sessioncode = session 123 self.faccode = faccode 124 self.depcode = depcode 125 self.factitle = site['faculties'][faccode].longtitle() 126 self.deptitle = site['faculties'][faccode][depcode].longtitle() 127 self.author = author 128 self.creation_dt_string = self.creation_dt.astimezone( 129 getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z") 130 self.data = get_students(faccode, depcode, session, level) 131 132 def create_pdf(self): 133 creator = getUtility(IPDFCreator) 134 #col_widths = [2*cm, 4*cm, 5*cm, 0.8*cm, 0.8*cm, 0.8*cm, 6*cm, ] 135 pdf_data = [Paragraph('<b>%s</b>' % self.creation_dt_string, 136 STYLE["Normal"]), 137 Spacer(1, 12),] 138 pdf_data += [Paragraph('%s<br />%s<br />Level: %s<br />Session: %s' % ( 139 self.factitle, self.deptitle, self.level, self.session), 140 STYLE["Normal"]), 141 Spacer(1, 12),] 142 143 for table in self.data: 144 table_data = [('Student Id', 'Matric No.', 'Name')] + table 145 pdf_data += [ 146 Table(table_data, style=TABLE_STYLE)] #, colWidths=col_widths)] 147 doc_title = 'Presentation of Session Results' 148 149 pdf_data.append(Spacer(1, 40)) 150 signatures = ['Ag. Head of Department', 'External Examiner', 'Dean of Faculty'] 151 signaturetables = get_signature_tables(signatures) 152 pdf_data.append(signaturetables[0]) 153 154 pdf = creator.create_pdf( 155 pdf_data, None, doc_title, self.author, 156 'Session Results Presentation %s/%s/%s/%s' % ( 157 self.faccode, self.depcode, self.levelcode, self.sessioncode) 158 ) 159 return pdf 160 161 @implementer(IReportGenerator) 162 class SessionResultsPresentationGenerator(grok.GlobalUtility): 163 164 title = _('Session Results Presentation') 165 grok.name('session_results_presentation') 166 167 def generate(self, site, faccode=None, depcode=None, 168 session=None, level=None, author=None): 169 result = SessionResultsPresentation(faccode=faccode, depcode=depcode, 170 session=session, level=level, author=author) 171 return result 172 173 ############################################################### 174 ## Browser related stuff 175 ## 176 ## XXX: move to local browser module 177 ############################################################### 178 from waeup.kofa.browser.layout import KofaPage 179 from waeup.kofa.interfaces import academic_sessions_vocab 180 from waeup.kofa.reports import get_generators 181 grok.templatedir('browser_templates') 182 class SessionResultsPresentationGeneratorPage(LevelReportGeneratorPage): 183 184 grok.context(SessionResultsPresentationGenerator) 185 grok.template('levelreportgeneratorpage') 186 label = _('Create session results presentation') 187 188 class SessionResultsPresentationPDFView(StudentStatisticsReportPDFView): 189 190 grok.context(ISessionResultsPresentation) 191 grok.name('pdf') 192 grok.require('waeup.Public') 193 prefix = 'SessionResultsPresentation' 194 195 def _filename(self): 196 return 'SessionResultsPresentation_%s_%s_%s_%s_%s.pdf' % ( 197 self.context.faccode, self.context.depcode, 198 self.context.sessioncode, self.context.levelcode, 199 self.context.creation_dt_string) -
main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_results_presentation.py
r10574 r10576 6 6 from waeup.kofa.interfaces import IJobManager 7 7 from waeup.kofa.students.reports.level_results_presentation import ( 8 get_students )8 get_students, SessionResultsPresentation, ISessionResultsPresentation) 9 9 from waeup.kofa.students.tests.test_catalog import CatalogTestSetup 10 10 from waeup.kofa.students.tests.test_browser import StudentsFullSetup … … 14 14 from waeup.kofa.students.studylevel import StudentStudyLevel 15 15 16 class LevelReportTests(CatalogTestSetup):16 class SessionResultsPresentationTests(CatalogTestSetup): 17 17 18 18 layer = FunctionalLayer 19 20 def test_iface(self): 21 # ensure we fullfill interface contracts 22 obj = SessionResultsPresentation('fac1', 'dep1', 2010, 100) 23 verifyClass(ISessionResultsPresentation, SessionResultsPresentation) 24 verifyObject(ISessionResultsPresentation, obj) 25 return 19 26 20 27 def test_get_students(self): … … 48 55 return 49 56 57 def test_create_pdf(self): 58 report = SessionResultsPresentation('fac1', 'dep1', 2010, 100) 59 result = report.create_pdf() 60 self.assertTrue(result.startswith('%PDF-')) 61 path = os.path.join(samples_dir(), 'session_results_presentation.pdf') 62 open(path, 'wb').write(result) 63 print "Sample session_results_presentation.pdf written to %s" % path 64 return 65 66 class SessionResultsPresentationUITests(StudentsFullSetup, FunctionalAsyncTestCase): 67 68 layer = FunctionalLayer 69 70 def wait_for_report_job_completed(self): 71 # helper function waiting until the current export job is completed 72 manager = getUtility(IJobManager) 73 job_id = self.app['reports'].running_report_jobs[0][0] 74 job = manager.get(job_id) 75 wait_for_result(job) 76 return job_id 77 78 def stored_in_reports(self, job_id): 79 # tell whether job_id is stored in reports's running jobs list 80 for entry in list(self.app['reports'].running_report_jobs): 81 if entry[0] == job_id: 82 return True 83 return False 84 85 def trigger_report_creation(self): 86 self.browser.addHeader('Authorization', 'Basic mgr:mgrpw') 87 self.browser.open('http://localhost/app/reports') 88 self.assertEqual(self.browser.headers['Status'], '200 Ok') 89 self.browser.getLink("Create new report").click() 90 self.browser.getControl(name="generator").value = ['session_results_presentation'] 91 self.browser.getControl("Configure").click() 92 self.browser.getControl(name="level").value = ['100'] 93 self.browser.getControl(name="session").value = ['2010'] 94 self.browser.getControl(name="faccode_depcode").value = ['fac1_dep1'] 95 self.browser.getControl("Create").click() 96 return 97 98 def test_report_download(self): 99 # We can download a generated report 100 self.trigger_report_creation() 101 # When the job is finished and we reload the page... 102 job_id = self.wait_for_report_job_completed() 103 self.browser.open('http://localhost/app/reports') 104 # ... the pdf file can be downloaded ... 105 self.browser.getControl("Download").click() 106 self.assertEqual(self.browser.headers['content-type'], 107 'application/pdf') 108 self.assertTrue( 109 'filename="SessionResultsPresentation_fac1_dep1_2010_100_' in 110 self.browser.headers['content-disposition']) 111 self.assertEqual(len(self.app['reports'].running_report_jobs), 1) 112 job_id = self.app['reports'].running_report_jobs[0][0] 113 # ... and discarded 114 self.browser.open('http://localhost/app/reports') 115 self.browser.getControl("Discard").click() 116 self.assertEqual(len(self.app['reports'].running_report_jobs), 0) 117 # Creation, downloading and discarding is logged 118 logfile = os.path.join( 119 self.app['datacenter'].storage, 'logs', 'main.log') 120 logcontent = open(logfile).read() 121 self.assertTrue( 122 'INFO - zope.mgr - students.reports.level_results_presentation.SessionResultsPresentationGeneratorPage - ' 123 'report %s created: Session Results Presentation (faculty=fac1, department=dep1, session=2010, level=100)' 124 % job_id in logcontent 125 ) 126 self.assertTrue( 127 'INFO - zope.mgr - students.reports.level_results_presentation.SessionResultsPresentationPDFView - ' 128 'report %s downloaded: SessionResultsPresentation_fac1_dep1_2010_100_' 129 % job_id in logcontent 130 ) 131 self.assertTrue( 132 'INFO - zope.mgr - browser.reports.ReportsContainerPage - ' 133 'report %s discarded' % job_id in logcontent 134 ) 135 return -
main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py
r10479 r10576 663 663 return pdf_stream 664 664 665 gpa_boundaries = (1, 1.5, 2.4, 3.5, 4.5, 5) 666 665 667 def getClassFromCGPA(self, gpa): 666 if gpa < 1:667 return 'Fail'668 if gpa < 1.5:669 return 'Pass'670 if gpa < 2.4:671 return '3rd Class'672 if gpa < 3.5:673 return '2nd Class Lower'674 if gpa < 4.5:675 return '2nd Class Upper'676 if gpa <= 5:677 return '1st Class'678 return 'N/A'668 if gpa < self.gpa_boundaries[0]: 669 return 0, 'Fail' 670 if gpa < self.gpa_boundaries[1]: 671 return 1, 'Pass' 672 if gpa < self.gpa_boundaries[2]: 673 return 2, '3rd Class' 674 if gpa < self.gpa_boundaries[3]: 675 return 3, '2nd Class Lower' 676 if gpa < self.gpa_boundaries[4]: 677 return 4, '2nd Class Upper' 678 if gpa <= self.gpa_boundaries[5]: 679 return 5, '1st Class' 680 return 999, 'N/A' 679 681 680 682 def renderPDFTranscript(self, view, filename='transcript.pdf', … … 754 756 f_label = trans(_('Cumulative GPA:'), portal_language) 755 757 f_label = Paragraph(f_label, ENTRY1_STYLE) 756 f_text = formatted_text('%s (%s)' % (gpa, self.getClassFromCGPA(gpa) ))758 f_text = formatted_text('%s (%s)' % (gpa, self.getClassFromCGPA(gpa)[1])) 757 759 f_text = Paragraph(f_text, ENTRY1_STYLE) 758 760 contextdata.append([f_label,f_text])
Note: See TracChangeset for help on using the changeset viewer.