- Timestamp:
- 2 Feb 2017, 08:15:48 (8 years ago)
- Location:
- main/waeup.aaue/trunk/src/waeup/aaue
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.aaue/trunk/src/waeup/aaue/browser/pdf.py
r14454 r14496 23 23 import grok 24 24 from reportlab.lib.pagesizes import A4, A3, landscape, portrait 25 from waeup.kofa.browser.pdf import PDFCreator, LandscapePDFCreator 25 from waeup.kofa.browser.pdf import ( 26 PDFCreator, LandscapePDFCreator, A3LandscapePDFCreator) 26 27 27 28 class CustomPDFCreator(PDFCreator): … … 50 51 logo_pos = [750, 465, 60] 51 52 52 class A3LandscapePDFCreator(LandscapePDFCreator):53 class CustomA3LandscapePDFCreator(A3LandscapePDFCreator): 53 54 """A utility to help with generating PDF docs in 54 55 A3 landscape format. No watermark is shown. 55 56 """ 56 57 grok.name('A3landscape')58 57 59 58 header_logo_path = os.path.join( -
main/waeup.aaue/trunk/src/waeup/aaue/students/reports/raw_score_report.py
r14489 r14496 16 16 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 17 ## 18 import grok19 import textwrap20 from zope.i18n import translate21 from zope.catalog.interfaces import ICatalog22 from zope.component import queryUtility, getUtility23 from zope.interface import implementer, Interface, Attribute24 from waeup.kofa.interfaces import (25 IKofaUtils,26 academic_sessions_vocab, registration_states_vocab)27 from waeup.kofa.interfaces import MessageFactory as _28 from waeup.kofa.reports import IReport29 from waeup.kofa.browser.pdf import get_signature_tables30 from waeup.kofa.students.vocabularies import StudyLevelSource31 from waeup.kofa.students.reports.level_report import LevelReportGeneratorPage32 from waeup.kofa.students.reports.student_statistics import (33 StudentStatisticsReportPDFView)34 18 35 class IRawScoreReport(IReport): 19 from waeup.kofa.students.reports.raw_score_report import ( 20 RawScoreReport, RawScoreReportGenerator) 36 21 37 session = Attribute('Session to report')38 level = Attribute('Level to report')39 faccode = Attribute('Faculty to report')40 depcode = Attribute('Department to report')41 certcode = Attribute('Certzificate to report')42 creation_dt_string = Attribute('Human readable report creation datetime')43 22 44 def get_courses(faccode, depcode, certcode, session, level): 45 """Method 1: Get certificate courses of a 46 certain department/certificate at a certain level. 47 """ 48 site = grok.getSite() 49 course_codes = [] 50 department = site['faculties'][faccode][depcode] 51 if certcode == 'all': 52 for cert in department.certificates.values(): 53 for certcourse in cert.values(): 54 if certcourse.level == level: 55 course_codes.append(certcourse.getCourseCode()) 56 else: 57 certificate = site['faculties'][faccode][depcode].certificates[certcode] 58 for certcourse in certificate.values(): 59 if certcourse.level == level: 60 course_codes.append(certcourse.getCourseCode()) 61 return course_codes 23 class CustomRawScoreReport(RawScoreReport): 62 24 63 def get_students(faccode, depcode, certcode, session, level, course_codes): 64 """Get students in a certain department/certificate who registered courses 65 in a certain session at a certain level. 25 signatures = ['Head of Department', 'Dean of Faculty'] 66 26 67 Returns a list of student data tuples.68 """69 cat = queryUtility(ICatalog, name="students_catalog")70 if certcode == 'all':71 certcode = None72 result = cat.searchResults(73 depcode = (depcode, depcode), faccode = (faccode, faccode),74 certcode = (certcode, certcode)75 )76 table = []77 for stud in result:78 if not stud['studycourse'].has_key(str(level)):79 continue80 level_obj = stud['studycourse'][str(level)]81 if level_obj.level_session != session:82 continue83 scores = dict()84 for ticket in level_obj.values():85 if ticket.code in course_codes:86 if not None in (ticket.score, ticket.ca):87 scores[ticket.code] = (88 ticket.score + ticket.ca, ticket.grade)89 else:90 scores[ticket.code] = ('NIL', '')91 fullname = textwrap.fill(stud.display_fullname, 26)92 line = (93 stud.matric_number,94 fullname,95 scores,96 )97 table.append(line)98 return sorted(table, key=lambda value:value[0])99 27 100 from reportlab.lib import colors 101 from reportlab.lib.styles import getSampleStyleSheet 102 from reportlab.lib.units import cm 103 from reportlab.platypus import Paragraph, Table, Spacer 104 from reportlab.platypus.flowables import Flowable 105 from waeup.kofa.reports import IReport, IReportGenerator 106 from waeup.kofa.reports import Report 107 from waeup.kofa.browser.interfaces import IPDFCreator 108 109 STYLE = getSampleStyleSheet() 110 111 class TTR(Flowable): #TableTextRotate 112 '''Rotates a text in a table cell.''' 113 114 def __init__(self, text): 115 Flowable.__init__(self) 116 self.text=text 117 118 def draw(self): 119 canvas = self.canv 120 canvas.rotate(25) 121 canvas.drawString( 0, -1, self.text) 122 123 #def wrap(self,aW,aH): 124 # canv = self.canv 125 # return canv._leading, canv.stringWidth(self.text) 126 127 def tbl_data_to_table(data, course_codes): 128 col_names = ( 129 #'Student Id', 130 'S/N', 131 'Matric No.', 132 'Name', 133 ) 134 catalog = getUtility(ICatalog, name='courses_catalog') 135 for code in course_codes: 136 course = list(catalog.searchResults(code=(code, code)))[0] 137 col_names += (TTR('%s (%s)' % (code, course.credits)),) 138 table = [col_names] 139 sn = 1 140 for line in data: 141 scores = tuple() 142 composed_line = (sn,) + line[:-1] 143 for code in course_codes: 144 result = line[-1].get(code) 145 if not result: 146 scores += ('N/R',) 147 else: 148 scores += ('%s%s' % (result[0], result[1]),) 149 composed_line += scores 150 table.append(composed_line) 151 sn += 1 152 return table 153 154 TABLE_STYLE = [ 155 ('FONT', (0,0), (-1,-1), 'Helvetica', 8), 156 ('VALIGN', (0, 1), (-1,-1), 'TOP'), 157 #('FONT', (0,0), (0,-1), 'Helvetica-Bold', 8), # 1st column 158 ('FONT', (0,0), (-1,0), 'Helvetica-Bold', 8), # 1st row 159 #('FONT', (0,-1), (-1,-1), 'Helvetica-Bold', 8), # last row 160 #('FONT', (-1,0), (-1,-1), 'Helvetica-Bold', 8), # last column 161 ('ALIGN', (3,1), (-1,-1), 'RIGHT'), 162 ('ALIGN', (0,0), (0,-1), 'RIGHT'), 163 #('ALIGN', (6,0), (6,-1), 'LEFT'), 164 ('INNERGRID', (0,1), (-1,-1), 0.25, colors.black), 165 ('BOX', (0,1), (-1,-1), 1, colors.black), 166 ] 167 168 @implementer(IRawScoreReport) 169 class RawScoreReport(Report): 170 data = None 171 session = None 172 level = None 173 faccode = None 174 depcode = None 175 certcode = None 176 177 note = "" 178 179 # note = """ 180 #<br /><br /><br /><br /> 181 #<font size='10'> 182 #<strong>Note:</strong> This copy is subject to correction for typographical errors and ratification by the departmental board. 183 #</font> 184 #""" 185 186 signatures = [ 187 translate(_('Head of Department')), 188 translate(_('Dean of Faculty'))] 189 190 def __init__(self, faccode, depcode, certcode, session, level, 191 author='System'): 192 super(RawScoreReport, self).__init__( 193 args=[faccode, depcode, certcode, session, level], 194 kwargs={'author':author}) 195 site = grok.getSite() 196 self.studylevelsource = StudyLevelSource().factory 197 self.portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE 198 self.session = academic_sessions_vocab.getTerm(session).title 199 self.levelcode = level 200 self.sessioncode = session 201 self.faccode = faccode 202 self.depcode = depcode 203 self.certcode = certcode 204 self.factitle = site['faculties'][faccode].longtitle 205 self.deptitle = site['faculties'][faccode][depcode].longtitle 206 if self.certcode == 'all': 207 self.certtitle = translate( 208 _('All Certificates'), 'waeup.kofa', 209 target_language=self.portal_language) 210 self.level = translate( 211 self.studylevelsource.getTitle(None, int(level)), 212 'waeup.kofa', target_language=self.portal_language) 213 else: 214 certificate = site[ 215 'faculties'][faccode][depcode].certificates[certcode] 216 self.certtitle = certificate.longtitle 217 self.level = translate( 218 self.studylevelsource.getTitle(certificate, int(level)), 219 'waeup.kofa', target_language=self.portal_language) 220 self.author = author 221 self.creation_dt_string = self.creation_dt.astimezone( 222 getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z") 223 self.past_levels = range(int(level/100)*100, 0, -100) 224 self.course_codes = dict() 225 self.data = dict() 226 for level in self.past_levels: 227 course_codes = get_courses( 228 faccode, depcode, certcode, session, level) 229 self.course_codes[level] = course_codes 230 self.data[level] = get_students( 231 faccode, depcode, certcode, session, self.levelcode, course_codes) 232 233 def create_pdf(self, job_id): 234 creator = getUtility(IPDFCreator, name='A3landscape') 235 table_data = dict() 236 for level in self.past_levels: 237 table_data[level] = tbl_data_to_table( 238 self.data[level], self.course_codes[level]) 239 col_widths = [1*cm, 4*cm, 5*cm] + [1*cm] * len(self.course_codes) 240 pdf_data = [Paragraph('<b>%s - Report %s</b>' 241 % (self.creation_dt_string, job_id), 242 STYLE["Normal"]), 243 Spacer(1, 12),] 244 pdf_data += [Paragraph( 245 translate( 246 '${a}<br />${b}<br />${c}<br /><br />Session: ${d}<br />Level: ${e}', 247 mapping = {'a':self.certtitle, 248 'b':self.deptitle, 249 'c':self.factitle, 250 'd':self.session, 251 'e':self.level, 252 }), 253 STYLE["Normal"]), 254 Spacer(1, 12),] 255 256 for level in self.past_levels: 257 pdf_data.append(Spacer(1, 40)) 258 pdf_data += [Paragraph('<b>Level %s Courses</b>' % level, 259 STYLE["Normal"]), Spacer(1, 20),] 260 pdf_data += [ 261 Table(table_data[level], 262 style=TABLE_STYLE, 263 colWidths=col_widths)] 264 doc_title = translate(_('Raw Score Report')) 265 pdf_data.append(Spacer(1, 40)) 266 if self.signatures: 267 signaturetables = get_signature_tables( 268 self.signatures, landscape=True) 269 pdf_data.append(signaturetables[0]) 270 271 pdf = creator.create_pdf( 272 pdf_data, None, doc_title, self.author, 273 doc_title + ' - %s/%s/%s - %s - %s -' % ( 274 self.faccode, self.depcode, self.certcode, 275 self.levelcode, self.sessioncode), 276 note=self.note 277 ) 278 return pdf 279 280 @implementer(IReportGenerator) 281 class RawScoreReportGenerator(grok.GlobalUtility): 282 283 title = _('RAW Score Report') 284 grok.name('raw_score_report') 28 class RawScoreReportGenerator(RawScoreReportGenerator): 285 29 286 30 def generate(self, site, faccode=None, depcode=None, certcode=None, 287 31 session=None, level=None, author=None): 288 result = RawScoreReport(faccode=faccode, depcode=depcode,32 result = CustomRawScoreReport(faccode=faccode, depcode=depcode, 289 33 certcode=certcode, session=session, level=level, author=author) 290 34 return result 291 292 ###############################################################293 ## Browser related stuff294 ##295 ## XXX: move to local browser module296 ###############################################################297 from waeup.kofa.browser.layout import KofaPage298 from waeup.kofa.interfaces import academic_sessions_vocab299 from waeup.kofa.reports import get_generators300 from waeup.kofa.browser.breadcrumbs import Breadcrumb301 grok.templatedir('browser_templates')302 class RawScoreReportGeneratorPage(LevelReportGeneratorPage):303 304 grok.context(RawScoreReportGenerator)305 306 label = _('Create raw score report')307 308 class RawScoreReportPDFView(StudentStatisticsReportPDFView):309 310 grok.context(IRawScoreReport)311 grok.name('pdf')312 grok.require('waeup.handleReports')313 prefix = 'RawScoreReport'314 315 def _filename(self):316 return 'RawScoreReport_%s_%s_%s_%s_%s_%s.pdf' % (317 self.context.faccode, self.context.depcode, self.context.certcode,318 self.context.sessioncode, self.context.levelcode,319 self.context.creation_dt_string)320 321 class RawScoreReportBreadcrumb(Breadcrumb):322 """A breadcrumb for reports.323 """324 grok.context(RawScoreReportGenerator)325 title = _(u'Raw Score Report')326 target = None -
main/waeup.aaue/trunk/src/waeup/aaue/students/reports/tests/test_raw_score_report.py
r14483 r14496 8 8 from waeup.kofa.tests.test_async import FunctionalAsyncTestCase 9 9 from waeup.kofa.browser.tests.test_pdf import samples_dir 10 11 from waeup.aaue.students.reports.raw_score_report import ( 12 get_students, RawScoreReport, IRawScoreReport, 13 get_courses) 10 from waeup.kofa.students.reports.raw_score_report import ( 11 get_students, IRawScoreReport, get_courses) 12 from waeup.aaue.students.reports.raw_score_report import CustomRawScoreReport 14 13 from waeup.aaue.testing import FunctionalLayer 15 14 … … 22 21 self.course = createObject('waeup.Course') 23 22 self.course.code = 'Course1' 23 self.course.credits = 25 24 24 self.app['faculties']['fac1']['dep1'].courses.addCourse( 25 25 self.course) … … 29 29 def test_iface(self): 30 30 # ensure we fullfill interface contracts 31 obj = RawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)32 verifyClass(IRawScoreReport, RawScoreReport)31 obj = CustomRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100) 32 verifyClass(IRawScoreReport, CustomRawScoreReport) 33 33 verifyObject(IRawScoreReport, obj) 34 34 return … … 56 56 self.course = createObject('waeup.Course') 57 57 self.course.code = 'Course2' 58 self.course.credits = 30 58 59 self.app['faculties']['fac1']['dep1'].courses.addCourse( 59 60 self.course) … … 72 73 self.student.firstname = u'Osahenokese Tessy' 73 74 self.student.lastname = u'Emwinyomwanru' 74 report = RawScoreReport('fac1', 'dep1', 'CERT1', 2011, 200)75 report = CustomRawScoreReport('fac1', 'dep1', 'CERT1', 2011, 200) 75 76 result = report.create_pdf('JOB_ID') 76 77 self.assertTrue(result.startswith('%PDF-'))
Note: See TracChangeset for help on using the changeset viewer.