source: main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/browser.py @ 16309

Last change on this file since 16309 was 16155, checked in by Henrik Bettermann, 4 years ago

DSPG requires total credits on semester basis.

  • Property svn:keywords set to Id
File size: 13.1 KB
Line 
1## $Id: browser.py 16155 2020-07-09 07:23:40Z 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##
18import grok
19from zope.i18n import translate
20from zope.schema.interfaces import ConstraintNotSatisfied
21from zope.component import getUtility
22from hurry.workflow.interfaces import IWorkflowInfo
23from waeup.kofa.interfaces import REQUESTED, IExtFileStore, IKofaUtils
24from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
25from waeup.kofa.browser.layout import (
26    KofaEditFormPage, UtilityView, action, jsaction)
27from waeup.kofa.students.browser import (
28    StudyLevelEditFormPage, StudyLevelDisplayFormPage,
29    StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip,
30    CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage,
31    ExportPDFTranscriptSlip, BedTicketAddPage, ExportPDFAdmissionSlip,
32    msave, emit_lock_message)
33from waeup.kofa.students.interfaces import (
34    IStudentsUtils, ICourseTicket, IStudent)
35from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS, PAID
36from kofacustom.nigeria.students.browser import (
37    NigeriaOnlinePaymentDisplayFormPage,
38    NigeriaStudentBaseManageFormPage,
39    NigeriaStudentClearanceEditFormPage,
40    NigeriaOnlinePaymentAddFormPage,
41    NigeriaExportPDFPaymentSlip,
42    NigeriaExportPDFClearanceSlip,
43    NigeriaAccommodationManageFormPage,
44    NigeriaAccommodationDisplayFormPage,
45    NigeriaBedTicketAddPage,
46    )
47from kofacustom.dspg.students.interfaces import (
48    ICustomStudentOnlinePayment, ICustomStudentStudyCourse,
49    ICustomStudentStudyLevel, ICustomStudent)
50from kofacustom.dspg.interfaces import MessageFactory as _
51
52class CustomBedTicketAddPage(NigeriaBedTicketAddPage):
53    with_ac = False
54
55class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage):
56    """ View to edit student clearance data by student
57    """
58
59    def dataNotComplete(self):
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.')
67        cm = getattr(self.context,'current_mode', None)
68        if cm and cm.startswith('nd'):
69            if not store.getFileByContext(self.context, attr=u'jamb_result.jpg'):
70                return _('No JAMB result uploaded.')
71        elif cm and cm.startswith('hnd'):
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.')
76        return False
77
78class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
79    """ Page to display student study levels
80    """
81    grok.template('studylevelpage')
82
83class CustomStudyLevelEditFormPage(StudyLevelEditFormPage):
84    """ Page to edit the student study level data by students.
85
86    """
87    grok.template('studyleveleditpage')
88
89class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage):
90    """ Page to display course tickets
91    """
92    form_fields = grok.AutoFields(ICourseTicket).omit('score')
93
94class CustomExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip):
95    """Deliver a PDF slip of the context.
96    """
97
98    def render(self):
99        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
100        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
101        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
102        Dept = translate(_('Dept.'), 'waeup.kofa', target_language=portal_language)
103        Faculty = translate(_('Faculty'), 'waeup.kofa', target_language=portal_language)
104        Cred = translate(_('Cred.'), 'waeup.kofa', target_language=portal_language)
105        #Mand = translate(_('Requ.'), 'waeup.kofa', target_language=portal_language)
106        #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
107        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
108        studentview = StudentBasePDFFormPage(self.context.student,
109            self.request, self.omit_fields)
110        students_utils = getUtility(IStudentsUtils)
111
112        tabledata = []
113        tableheader = []
114        for i in range(1,7):
115            tabledata.append(sorted(
116                [value for value in self.context.values() if value.semester == i],
117                key=lambda value: str(value.semester) + value.code))
118            tableheader.append([(Code,'code', 2.5),
119                             (Title,'title', 5),
120                             (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5),
121                             (Cred, 'credits', 1.5),
122                             #(Mand, 'mandatory', 1.5),
123                             #(Score, 'score', 1.5),
124                             (Grade, 'grade', 1.5),
125                             #('Auto', 'automatic', 1.5)
126                             ])
127        return students_utils.renderPDF(
128            self, 'course_registration_slip.pdf',
129            self.context.student, studentview,
130            tableheader=tableheader,
131            tabledata=tabledata,
132            omit_fields=self.omit_fields
133            )
134
135
136class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
137    """Deliver a PDF slip of the context.
138    """
139
140    def render(self):
141        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
142        Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language)
143        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
144        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
145        Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language)
146        #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
147        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
148        studentview = StudentBasePDFFormPage(self.context.student,
149            self.request, self.omit_fields)
150        students_utils = getUtility(IStudentsUtils)
151
152        tableheader = [(Code,'code', 2.5),
153                         (Title,'title', 8.5),
154                         (Term, 'semester', 1.5),
155                         (Cred, 'credits', 1.5),
156                         #(Score, 'score', 1.5),
157                         (Grade, 'grade', 1.5),
158                         ]
159
160        pdfstream = students_utils.renderPDFTranscript(
161            self, 'transcript.pdf',
162            self.context.student, studentview,
163            omit_fields=self.omit_fields,
164            tableheader=tableheader,
165            signatures=self._signatures(),
166            sigs_in_footer=self._sigsInFooter(),
167            digital_sigs=self._digital_sigs(),
168            save_file=self._save_file(),
169            )
170        if not pdfstream:
171            self.redirect(self.url(self.context.student))
172            return
173        return pdfstream
174
175class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage):
176    """ Page to view bed tickets.
177    """
178    with_hostel_selection = True
179
180class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
181    """ Page to manage bed tickets.
182    This manage form page is for both students and students officers.
183    """
184    with_hostel_selection = True
185
186class StudentGetMatricNumberPage(UtilityView, grok.View):
187    """ Construct and set the matriculation number.
188    """
189    grok.context(IStudent)
190    grok.name('get_matric_number')
191    grok.require('waeup.viewStudent')
192
193    def update(self):
194        students_utils = getUtility(IStudentsUtils)
195        msg, mnumber = students_utils.setMatricNumber(self.context)
196        if msg:
197            self.flash(msg, type="danger")
198        else:
199            self.flash(_('Matriculation number %s assigned.' % mnumber))
200            self.context.writeLogMessage(self, '%s assigned' % mnumber)
201        self.redirect(self.url(self.context))
202        return
203
204    def render(self):
205        return
206
207class ExportPDFMatricNumberSlip(UtilityView, grok.View):
208    """Deliver a PDF notification slip.
209    """
210    grok.context(ICustomStudent)
211    grok.name('matric_number_slip.pdf')
212    grok.require('waeup.viewStudent')
213    prefix = 'form'
214
215    form_fields = grok.AutoFields(ICustomStudent).select(
216        'student_id', 'matric_number')
217    omit_fields = ('date_of_birth', 'current_level', 'flash_notice')
218
219    @property
220    def title(self):
221        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
222        return translate(_('Matriculation Number'), 'waeup.kofa',
223            target_language=portal_language)
224
225    @property
226    def label(self):
227        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
228        return translate(_('Matriculation Number Slip\n'),
229            target_language=portal_language) \
230            + ' %s' % self.context.display_fullname
231
232    def render(self):
233        if self.context.state not in (PAID,) or not self.context.is_fresh \
234            or not self.context.matric_number:
235            self.flash('Not allowed.', type="danger")
236            self.redirect(self.url(self.context))
237            return
238        students_utils = getUtility(IStudentsUtils)
239        return students_utils.renderPDFAdmissionLetter(self,
240            self.context.student, omit_fields=self.omit_fields,
241            pre_text='', post_text='')
242
243class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
244    """Deliver a PDF Admission slip.
245    """
246
247    @property
248    def pre_text(self):
249        return (
250            'I am pleased to inform you that you have been offered '
251            'provisional admission into the Delta State Polytechnic, '
252            'Ogwashi-Uku as follows:')
253
254    @property
255    def post_text(self):
256        return """1. Duration: 2 years
257
2582.      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.
259
2603. 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.
261
2624. 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.
263
2645. Please, note that resumption/registration starts immediately.
265
2666. 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.
267
2687. 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.
269
2708. 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.
271
2729. 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.
273
27410. Before the commencement of registration, you will be required to undergo a medical examination which should be conducted in the Polytechnic clinic.
275
27611. 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.
277
27812. At the time of registration, you are required to sign an undertaking of non-involvement in cult-related activities and acts of vandalism.
279
28013. We hope that you will be able to take advantage of this offer or provisional admission.
281
28214. Please, accept our hearty congratulations.
283
284Admissions Officer
285For: Registrar
286"""
287
288    def render(self):
289        students_utils = getUtility(IStudentsUtils)
290        return students_utils.renderPDFAdmissionLetter(self,
291            self.context.student, omit_fields=self.omit_fields,
292            pre_text=self.pre_text, post_text=self.post_text)
Note: See TracBrowser for help on using the repository browser.