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

Last change on this file since 16948 was 16817, checked in by Henrik Bettermann, 3 years ago

Show semester credits on study level pages.

  • Property svn:keywords set to Id
File size: 14.2 KB
Line 
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##
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, StudyLevelManageFormPage,
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    grok.context(ICustomStudentStudyLevel)
83    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
84        'level',)
85    form_fields[
86        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
87
88class CustomStudyLevelEditFormPage(StudyLevelEditFormPage):
89    """ Page to edit the student study level data by students.
90
91    """
92    grok.template('studyleveleditpage')
93
94class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage):
95    """ Page to display course tickets
96    """
97    form_fields = grok.AutoFields(ICourseTicket).omit('score')
98
99class 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
108class CustomExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip):
109    """Deliver a PDF slip of the context.
110    """
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')
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
160class 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
184        pdfstream = students_utils.renderPDFTranscript(
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(),
191            digital_sigs=self._digital_sigs(),
192            save_file=self._save_file(),
193            )
194        if not pdfstream:
195            self.redirect(self.url(self.context.student))
196            return
197        return pdfstream
198
199class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage):
200    """ Page to view bed tickets.
201    """
202    with_hostel_selection = True
203
204class 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
209
210class 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
231class 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,
265            pre_text='', post_text='')
266
267class 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):
280        return """1. Duration: 2 years
281
2822.      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.
283
2843. 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.
285
2864. 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.
287
2885. Please, note that resumption/registration starts immediately.
289
2906. 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.
291
2927. 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.
293
2948. 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.
295
2969. 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.
297
29810. Before the commencement of registration, you will be required to undergo a medical examination which should be conducted in the Polytechnic clinic.
299
30011. 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.
301
30212. At the time of registration, you are required to sign an undertaking of non-involvement in cult-related activities and acts of vandalism.
303
30413. We hope that you will be able to take advantage of this offer or provisional admission.
305
30614. Please, accept our hearty congratulations.
307
308Admissions Officer
309For: 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)
Note: See TracBrowser for help on using the repository browser.