[10765] | 1 | ## $Id: browser.py 16817 2022-02-17 09:09:52Z henrik $ |
---|
| 2 | ## |
---|
| 3 | ## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann |
---|
| 4 | ## This program is free software; you can redistribute it and/or modify |
---|
| 5 | ## it under the terms of the GNU General Public License as published by |
---|
| 6 | ## the Free Software Foundation; either version 2 of the License, or |
---|
| 7 | ## (at your option) any later version. |
---|
| 8 | ## |
---|
| 9 | ## This program is distributed in the hope that it will be useful, |
---|
| 10 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 12 | ## GNU General Public License for more details. |
---|
| 13 | ## |
---|
| 14 | ## You should have received a copy of the GNU General Public License |
---|
| 15 | ## along with this program; if not, write to the Free Software |
---|
| 16 | ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
| 17 | ## |
---|
| 18 | import grok |
---|
| 19 | from zope.i18n import translate |
---|
| 20 | from zope.schema.interfaces import ConstraintNotSatisfied |
---|
| 21 | from zope.component import getUtility |
---|
| 22 | from hurry.workflow.interfaces import IWorkflowInfo |
---|
| 23 | from waeup.kofa.interfaces import REQUESTED, IExtFileStore, IKofaUtils |
---|
| 24 | from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget |
---|
[15288] | 25 | from waeup.kofa.browser.layout import ( |
---|
| 26 | KofaEditFormPage, UtilityView, action, jsaction) |
---|
[10765] | 27 | from waeup.kofa.students.browser import ( |
---|
[16817] | 28 | StudyLevelEditFormPage, StudyLevelDisplayFormPage, StudyLevelManageFormPage, |
---|
[14877] | 29 | StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip, |
---|
| 30 | CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage, |
---|
[15743] | 31 | ExportPDFTranscriptSlip, BedTicketAddPage, ExportPDFAdmissionSlip, |
---|
[14877] | 32 | msave, emit_lock_message) |
---|
[15288] | 33 | from waeup.kofa.students.interfaces import ( |
---|
| 34 | IStudentsUtils, ICourseTicket, IStudent) |
---|
[15290] | 35 | from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS, PAID |
---|
[10765] | 36 | from kofacustom.nigeria.students.browser import ( |
---|
| 37 | NigeriaOnlinePaymentDisplayFormPage, |
---|
| 38 | NigeriaStudentBaseManageFormPage, |
---|
| 39 | NigeriaStudentClearanceEditFormPage, |
---|
| 40 | NigeriaOnlinePaymentAddFormPage, |
---|
[13062] | 41 | NigeriaExportPDFPaymentSlip, |
---|
| 42 | NigeriaExportPDFClearanceSlip, |
---|
[15225] | 43 | NigeriaAccommodationManageFormPage, |
---|
[16155] | 44 | NigeriaAccommodationDisplayFormPage, |
---|
[15774] | 45 | NigeriaBedTicketAddPage, |
---|
[10765] | 46 | ) |
---|
[14716] | 47 | from kofacustom.dspg.students.interfaces import ( |
---|
[10765] | 48 | ICustomStudentOnlinePayment, ICustomStudentStudyCourse, |
---|
[15288] | 49 | ICustomStudentStudyLevel, ICustomStudent) |
---|
[14716] | 50 | from kofacustom.dspg.interfaces import MessageFactory as _ |
---|
[10765] | 51 | |
---|
[15774] | 52 | class CustomBedTicketAddPage(NigeriaBedTicketAddPage): |
---|
[15215] | 53 | with_ac = False |
---|
| 54 | |
---|
[14882] | 55 | class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage): |
---|
| 56 | """ View to edit student clearance data by student |
---|
| 57 | """ |
---|
| 58 | |
---|
[15682] | 59 | def dataNotComplete(self): |
---|
[14882] | 60 | store = getUtility(IExtFileStore) |
---|
| 61 | if not store.getFileByContext(self.context, attr=u'birth_certificate.jpg'): |
---|
| 62 | return _('No birth certificate uploaded.') |
---|
| 63 | if not store.getFileByContext(self.context, attr=u'lga_ident.jpg'): |
---|
| 64 | return _('No LGA identification letter uploaded.') |
---|
| 65 | if not store.getFileByContext(self.context, attr=u'o_level_result.jpg'): |
---|
| 66 | return _('No O Level result uploaded.') |
---|
[14883] | 67 | cm = getattr(self.context,'current_mode', None) |
---|
| 68 | if cm and cm.startswith('nd'): |
---|
[14882] | 69 | if not store.getFileByContext(self.context, attr=u'jamb_result.jpg'): |
---|
| 70 | return _('No JAMB result uploaded.') |
---|
[14883] | 71 | elif cm and cm.startswith('hnd'): |
---|
[14882] | 72 | if not store.getFileByContext(self.context, attr=u'nd_result.jpg'): |
---|
| 73 | return _('No ND result uploaded.') |
---|
| 74 | if not store.getFileByContext(self.context, attr=u'it_letter.jpg'): |
---|
| 75 | return _('No IT letter uploaded.') |
---|
[15089] | 76 | return False |
---|
| 77 | |
---|
| 78 | class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage): |
---|
| 79 | """ Page to display student study levels |
---|
| 80 | """ |
---|
| 81 | grok.template('studylevelpage') |
---|
[16817] | 82 | grok.context(ICustomStudentStudyLevel) |
---|
| 83 | form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit( |
---|
| 84 | 'level',) |
---|
| 85 | form_fields[ |
---|
| 86 | 'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') |
---|
[15089] | 87 | |
---|
| 88 | class CustomStudyLevelEditFormPage(StudyLevelEditFormPage): |
---|
| 89 | """ Page to edit the student study level data by students. |
---|
| 90 | |
---|
| 91 | """ |
---|
| 92 | grok.template('studyleveleditpage') |
---|
| 93 | |
---|
| 94 | class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage): |
---|
| 95 | """ Page to display course tickets |
---|
| 96 | """ |
---|
| 97 | form_fields = grok.AutoFields(ICourseTicket).omit('score') |
---|
| 98 | |
---|
[16817] | 99 | class CustomStudyLevelManageFormPage(StudyLevelManageFormPage): |
---|
| 100 | """ Page to edit the student study level data |
---|
| 101 | """ |
---|
| 102 | grok.context(ICustomStudentStudyLevel) |
---|
| 103 | |
---|
| 104 | form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit( |
---|
| 105 | 'validation_date', 'validated_by', 'total_credits', 'gpa', 'level', |
---|
| 106 | 'total_credits_s1', 'total_credits_s2') |
---|
| 107 | |
---|
[15089] | 108 | class CustomExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip): |
---|
| 109 | """Deliver a PDF slip of the context. |
---|
| 110 | """ |
---|
[16817] | 111 | grok.context(ICustomStudentStudyLevel) |
---|
| 112 | form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit( |
---|
| 113 | 'level', 'gpa', 'transcript_remark') |
---|
| 114 | form_fields[ |
---|
| 115 | 'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') |
---|
| 116 | prefix = 'form' |
---|
| 117 | omit_fields = ( |
---|
| 118 | 'password', 'suspended', 'phone', 'date_of_birth', |
---|
| 119 | 'adm_code', 'sex', 'suspended_comment', 'current_level', |
---|
| 120 | 'flash_notice') |
---|
[15089] | 121 | |
---|
| 122 | def render(self): |
---|
| 123 | portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE |
---|
| 124 | Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language) |
---|
| 125 | Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language) |
---|
| 126 | Dept = translate(_('Dept.'), 'waeup.kofa', target_language=portal_language) |
---|
| 127 | Faculty = translate(_('Faculty'), 'waeup.kofa', target_language=portal_language) |
---|
| 128 | Cred = translate(_('Cred.'), 'waeup.kofa', target_language=portal_language) |
---|
| 129 | #Mand = translate(_('Requ.'), 'waeup.kofa', target_language=portal_language) |
---|
| 130 | #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language) |
---|
| 131 | Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language) |
---|
| 132 | studentview = StudentBasePDFFormPage(self.context.student, |
---|
| 133 | self.request, self.omit_fields) |
---|
| 134 | students_utils = getUtility(IStudentsUtils) |
---|
| 135 | |
---|
| 136 | tabledata = [] |
---|
| 137 | tableheader = [] |
---|
| 138 | for i in range(1,7): |
---|
| 139 | tabledata.append(sorted( |
---|
| 140 | [value for value in self.context.values() if value.semester == i], |
---|
| 141 | key=lambda value: str(value.semester) + value.code)) |
---|
| 142 | tableheader.append([(Code,'code', 2.5), |
---|
| 143 | (Title,'title', 5), |
---|
| 144 | (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5), |
---|
| 145 | (Cred, 'credits', 1.5), |
---|
| 146 | #(Mand, 'mandatory', 1.5), |
---|
| 147 | #(Score, 'score', 1.5), |
---|
| 148 | (Grade, 'grade', 1.5), |
---|
| 149 | #('Auto', 'automatic', 1.5) |
---|
| 150 | ]) |
---|
| 151 | return students_utils.renderPDF( |
---|
| 152 | self, 'course_registration_slip.pdf', |
---|
| 153 | self.context.student, studentview, |
---|
| 154 | tableheader=tableheader, |
---|
| 155 | tabledata=tabledata, |
---|
| 156 | omit_fields=self.omit_fields |
---|
| 157 | ) |
---|
| 158 | |
---|
| 159 | |
---|
| 160 | class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip): |
---|
| 161 | """Deliver a PDF slip of the context. |
---|
| 162 | """ |
---|
| 163 | |
---|
| 164 | def render(self): |
---|
| 165 | portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE |
---|
| 166 | Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language) |
---|
| 167 | Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language) |
---|
| 168 | Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language) |
---|
| 169 | Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language) |
---|
| 170 | #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language) |
---|
| 171 | Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language) |
---|
| 172 | studentview = StudentBasePDFFormPage(self.context.student, |
---|
| 173 | self.request, self.omit_fields) |
---|
| 174 | students_utils = getUtility(IStudentsUtils) |
---|
| 175 | |
---|
| 176 | tableheader = [(Code,'code', 2.5), |
---|
| 177 | (Title,'title', 8.5), |
---|
| 178 | (Term, 'semester', 1.5), |
---|
| 179 | (Cred, 'credits', 1.5), |
---|
| 180 | #(Score, 'score', 1.5), |
---|
| 181 | (Grade, 'grade', 1.5), |
---|
| 182 | ] |
---|
| 183 | |
---|
[15166] | 184 | pdfstream = students_utils.renderPDFTranscript( |
---|
[15089] | 185 | self, 'transcript.pdf', |
---|
| 186 | self.context.student, studentview, |
---|
| 187 | omit_fields=self.omit_fields, |
---|
| 188 | tableheader=tableheader, |
---|
| 189 | signatures=self._signatures(), |
---|
| 190 | sigs_in_footer=self._sigsInFooter(), |
---|
[15166] | 191 | digital_sigs=self._digital_sigs(), |
---|
| 192 | save_file=self._save_file(), |
---|
[15089] | 193 | ) |
---|
[15166] | 194 | if not pdfstream: |
---|
| 195 | self.redirect(self.url(self.context.student)) |
---|
| 196 | return |
---|
| 197 | return pdfstream |
---|
[15225] | 198 | |
---|
[16155] | 199 | class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage): |
---|
| 200 | """ Page to view bed tickets. |
---|
| 201 | """ |
---|
| 202 | with_hostel_selection = True |
---|
| 203 | |
---|
[15225] | 204 | class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage): |
---|
| 205 | """ Page to manage bed tickets. |
---|
| 206 | This manage form page is for both students and students officers. |
---|
| 207 | """ |
---|
| 208 | with_hostel_selection = True |
---|
[15288] | 209 | |
---|
| 210 | class StudentGetMatricNumberPage(UtilityView, grok.View): |
---|
| 211 | """ Construct and set the matriculation number. |
---|
| 212 | """ |
---|
| 213 | grok.context(IStudent) |
---|
| 214 | grok.name('get_matric_number') |
---|
| 215 | grok.require('waeup.viewStudent') |
---|
| 216 | |
---|
| 217 | def update(self): |
---|
| 218 | students_utils = getUtility(IStudentsUtils) |
---|
| 219 | msg, mnumber = students_utils.setMatricNumber(self.context) |
---|
| 220 | if msg: |
---|
| 221 | self.flash(msg, type="danger") |
---|
| 222 | else: |
---|
| 223 | self.flash(_('Matriculation number %s assigned.' % mnumber)) |
---|
| 224 | self.context.writeLogMessage(self, '%s assigned' % mnumber) |
---|
| 225 | self.redirect(self.url(self.context)) |
---|
| 226 | return |
---|
| 227 | |
---|
| 228 | def render(self): |
---|
| 229 | return |
---|
| 230 | |
---|
| 231 | class ExportPDFMatricNumberSlip(UtilityView, grok.View): |
---|
| 232 | """Deliver a PDF notification slip. |
---|
| 233 | """ |
---|
| 234 | grok.context(ICustomStudent) |
---|
| 235 | grok.name('matric_number_slip.pdf') |
---|
| 236 | grok.require('waeup.viewStudent') |
---|
| 237 | prefix = 'form' |
---|
| 238 | |
---|
| 239 | form_fields = grok.AutoFields(ICustomStudent).select( |
---|
| 240 | 'student_id', 'matric_number') |
---|
| 241 | omit_fields = ('date_of_birth', 'current_level', 'flash_notice') |
---|
| 242 | |
---|
| 243 | @property |
---|
| 244 | def title(self): |
---|
| 245 | portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE |
---|
| 246 | return translate(_('Matriculation Number'), 'waeup.kofa', |
---|
| 247 | target_language=portal_language) |
---|
| 248 | |
---|
| 249 | @property |
---|
| 250 | def label(self): |
---|
| 251 | portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE |
---|
| 252 | return translate(_('Matriculation Number Slip\n'), |
---|
| 253 | target_language=portal_language) \ |
---|
| 254 | + ' %s' % self.context.display_fullname |
---|
| 255 | |
---|
| 256 | def render(self): |
---|
| 257 | if self.context.state not in (PAID,) or not self.context.is_fresh \ |
---|
| 258 | or not self.context.matric_number: |
---|
| 259 | self.flash('Not allowed.', type="danger") |
---|
| 260 | self.redirect(self.url(self.context)) |
---|
| 261 | return |
---|
| 262 | students_utils = getUtility(IStudentsUtils) |
---|
| 263 | return students_utils.renderPDFAdmissionLetter(self, |
---|
| 264 | self.context.student, omit_fields=self.omit_fields, |
---|
[15743] | 265 | pre_text='', post_text='') |
---|
| 266 | |
---|
| 267 | class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip): |
---|
| 268 | """Deliver a PDF Admission slip. |
---|
| 269 | """ |
---|
| 270 | |
---|
| 271 | @property |
---|
| 272 | def pre_text(self): |
---|
| 273 | return ( |
---|
| 274 | 'I am pleased to inform you that you have been offered ' |
---|
| 275 | 'provisional admission into the Delta State Polytechnic, ' |
---|
| 276 | 'Ogwashi-Uku as follows:') |
---|
| 277 | |
---|
| 278 | @property |
---|
| 279 | def post_text(self): |
---|
[15751] | 280 | return """1. Duration: 2 years |
---|
[15743] | 281 | |
---|
[15751] | 282 | 2. This offer is conditional upon the confirmation of your qualification(s) as listed by you in the application form or which you claim to possess as at when this offer of admission was made and your meeting the minimum department entry requirement. |
---|
[15743] | 283 | |
---|
[15751] | 284 | 3. At the time of Registration, you will be required to produce the original copies of your certificates or any other acceptable evidence of the qualification(s), on which this offer of admission has been based. |
---|
[15743] | 285 | |
---|
[15751] | 286 | 4. If at any time after admission it is discovered that you do not possess any of the qualifications which you claimed to have obtained, you will be required to withdraw from the Polytechnic. |
---|
[15743] | 287 | |
---|
[15751] | 288 | 5. Please, note that resumption/registration starts immediately. |
---|
[15743] | 289 | |
---|
[15751] | 290 | 6. You are required to pay all the necessary fees, such as school fees, students\' union fees, boarding fees (optional) and any other prescribed fees online and register immediately. Late registration will attract severe sanction such as payment of late registration fee of N10000 or outright withdrawal of offer of admission. |
---|
[15743] | 291 | |
---|
[15751] | 292 | 7. If you do not respond to this offer within two (2) weeks from the date of resumption, the Polytechnic will assume that you are not interested in the offer and may withdraw the offer to accommodate other candidates on awaiting list. |
---|
[15743] | 293 | |
---|
[15751] | 294 | 8. If you do not pay your school fees and register within the stipulated time frame for registration, you would not be allowed to write the Polytechnic\'s semester examinations. Should you mistakenly write the exams, your scripts would not be marked. |
---|
[15743] | 295 | |
---|
[15751] | 296 | 9. You are required to present at the time of registration, a letter of attestation from a clergy man, a lawyer, a senior civil servant (Level 13 and above) or any person of reputable standing in the society. |
---|
[15743] | 297 | |
---|
[15751] | 298 | 10. Before the commencement of registration, you will be required to undergo a medical examination which should be conducted in the Polytechnic clinic. |
---|
[15743] | 299 | |
---|
[15751] | 300 | 11. Other information/instructions about facilities at the Polytechnic, including accommodation, can be obtained from the Polytechnic Portal. The Head of your School/Department at the Polytechnic will make the details of the programme available to you. |
---|
[15743] | 301 | |
---|
[15751] | 302 | 12. At the time of registration, you are required to sign an undertaking of non-involvement in cult-related activities and acts of vandalism. |
---|
[15743] | 303 | |
---|
[15751] | 304 | 13. We hope that you will be able to take advantage of this offer or provisional admission. |
---|
[15743] | 305 | |
---|
[15751] | 306 | 14. Please, accept our hearty congratulations. |
---|
| 307 | |
---|
[15743] | 308 | Admissions Officer |
---|
| 309 | For: Registrar |
---|
| 310 | """ |
---|
| 311 | |
---|
| 312 | def render(self): |
---|
| 313 | students_utils = getUtility(IStudentsUtils) |
---|
| 314 | return students_utils.renderPDFAdmissionLetter(self, |
---|
| 315 | self.context.student, omit_fields=self.omit_fields, |
---|
| 316 | pre_text=self.pre_text, post_text=self.post_text) |
---|