## $Id: browser.py 17303 2023-01-17 12:51:16Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## """UI components for basic applicants and related components. """ import grok from zope.formlib.textwidgets import BytesDisplayWidget from zope.component import getUtility from hurry.workflow.interfaces import IWorkflowState from waeup.kofa.interfaces import IKofaUtils from waeup.kofa.widgets.datewidget import ( FriendlyDateDisplayWidget, FriendlyDatetimeDisplayWidget) from waeup.kofa.applicants.pdf import PDFApplicationSlip from waeup.kofa.browser.layout import KofaEditFormPage, KofaPage, action, NullValidator from waeup.kofa.applicants.browser import ( ApplicantRegistrationPage, ApplicantsContainerPage, ApplicantDisplayFormPage, ApplicantManageFormPage, ApplicantEditFormPage, BalancePaymentAddFormPage, ExportPDFPaymentSlipPage, ApplicantBaseDisplayFormPage, ExportJobContainerJobStart) from waeup.kofa.applicants.workflow import ( INITIALIZED, STARTED, PAID, SUBMITTED, ADMITTED, NOT_ADMITTED, CREATED, PROCESSED) from waeup.kofa.students.interfaces import IStudentsUtils from waeup.kofa.applicants.interfaces import ( IApplicantOnlinePayment, IApplicantsUtils) from kofacustom.nigeria.applicants.interfaces import INigeriaApplicantOnlinePayment from kofacustom.nigeria.applicants.browser import ( NigeriaExportPDFPaymentSlipPage, NigeriaOnlinePaymentDisplayFormPage) from kofacustom.lpng.applicants.interfaces import ( ICustomApplicant, ICustomApplicantOnlinePayment, ICustomApplicantEdit, IPollingUnit, STATES, LGAS, WARDS, PUNITS ) from kofacustom.lpng.interfaces import MessageFactory as _ class CustomExportJobContainerJobStart(ExportJobContainerJobStart): """View that starts three export jobs, one for applicants, a second one for applicant payments and a third for referee reports. """ EXPORTER_LIST = ('applicants', 'applicantpayments', ) class CustomApplicantDisplayFormPage(ApplicantDisplayFormPage): """A display view for applicant data. """ @property def render_punit(self): if self.context.punit: punit = self.context.punit.split('_') return ' -> '.join([STATES[punit[0]], LGAS['_'.join(punit[:2])], WARDS['_'.join(punit[:3])] , PUNITS['_'.join(punit[:4])] ]) return @property def form_fields(self): form_fields = grok.AutoFields( ICustomApplicant).omit('locked', 'suspended', 'federalstate', 'lga', 'ward', 'punit') form_fields['perm_address'].custom_widget = BytesDisplayWidget #form_fields['notice'].custom_widget = BytesDisplayWidget if not getattr(self.context, 'student_id'): form_fields = form_fields.omit('student_id') return form_fields class CustomPDFApplicationSlip(PDFApplicationSlip): @property def form_fields(self): form_fields = grok.AutoFields(ICustomApplicant) if not getattr(self.context, 'student_id'): form_fields = form_fields.omit('student_id') return form_fields class CustomApplicantManageFormPage(ApplicantManageFormPage): """A full edit view for applicant data. """ @property def display_actions(self): actions = [[_('Save'), _('Finally Submit')], [ #_('Add online payment ticket'), _('Add balance payment ticket'), _('Remove selected tickets') ]] applicants_utils = getUtility(IApplicantsUtils) if self.context.state not in applicants_utils.BALANCE_PAYMENT_STATES: actions[1].pop(1) return actions @property def form_fields(self): form_fields = grok.AutoFields(ICustomApplicant).omit( 'federalstate', 'lga', 'ward', 'punit') if not getattr(self.context, 'student_id'): form_fields = form_fields.omit('student_id') form_fields['applicant_id'].for_display = True return form_fields class CustomApplicantEditFormPage(ApplicantEditFormPage): """An applicant-centered edit view for applicant data. """ def unremovable(self, ticket): return True @property def display_actions(self): state = IWorkflowState(self.context).getState() actions = [[_('Save')], [ #_('Remove selected tickets') ]] if state == STARTED: actions = [[_('Save'), _('Save and Make Donation')], [ #_('Add online payment ticket'), #_('Remove selected tickets') ]] elif self.context.special and state == PAID: actions = [[_('Save'), _('Finally Submit')], [ #_('Add online payment ticket'), #_('Remove selected tickets') ]] elif state == PAID: actions = [[_('Save'), _('Finally Submit')], [ #_('Remove selected tickets') ]] applicants_utils = getUtility(IApplicantsUtils) if self.context.state in applicants_utils.BALANCE_PAYMENT_STATES: actions[1].append(_('Make Donation')) return actions @property def form_fields(self): form_fields = grok.AutoFields(ICustomApplicantEdit) form_fields = form_fields.omit('locked', 'suspended', 'federalstate', 'lga', 'ward', 'punit') if not getattr(self.context, 'student_id'): form_fields = form_fields.omit('student_id') form_fields['applicant_id'].for_display = True form_fields['reg_number'].for_display = True return form_fields @action(_('Save'), style='primary') def save(self, **data): if self.upload_success is False: # False is not None! # Error during image upload. Ignore other values. return if not self.request.form.get('confirm_passport', False): self.flash(_('Please tick the checkbox above the save buttons.')) return self.applyData(self.context, **data) self.flash(_('Form has been saved.')) return @action(_('Add online payment ticket'), style='primary') def addPaymentTicket(self, **data): self.redirect(self.url(self.context, 'addafp')) return @action(_('Make Donation'), style='primary') def addBalancePaymentTicket(self, **data): self.redirect(self.url(self.context, 'addbp')) return @action(_('Save and Make Donation'), style='primary') def saveAndDonate(self, **data): if self.upload_success is False: # False is not None! # Error during image upload. Ignore other values. return if not self.request.form.get('confirm_passport', False): self.flash(_('Please tick the checkbox above the save buttons.')) return self.applyData(self.context, **data) self.redirect(self.url(self.context, 'addbp')) return class CustomBalancePaymentAddFormPage(BalancePaymentAddFormPage): """ Page to add an online payment which can balance s previous session payment. """ grok.require('waeup.payApplicant') @property def selectable_payment_options(self): options = getUtility( IKofaUtils).selectable_payment_options(self.context) return sorted(options.items(), key=lambda value: value[0]) @action(_('Create ticket'), style='primary') def createTicket(self, **data): p_category = data['p_category'] form = self.request.form p_option = form.get('form.p_option', None) balance_amount = data.get('balance_amount', None) applicants_utils = getUtility(IApplicantsUtils) error, payment = applicants_utils.setBalanceDetails( self.context, p_category, balance_amount) if error is not None: self.flash(error, type="danger") return if p_option: payment.p_option = p_option payment.p_currency = p_option self.context[payment.p_id] = payment self.flash(_('Payment ticket created.')) self.context.writeLogMessage(self,'added: %s' % payment.p_id) self.redirect(self.url(payment)) return @action(_('Cancel'), validator=NullValidator) def cancel(self, **data): self.redirect(self.url(self.context)) class CustomApplicantBaseDisplayFormPage(ApplicantBaseDisplayFormPage): @property def form_fields(self): form_fields = grok.AutoFields(ICustomApplicant).select( 'applicant_id', 'reg_number', 'email') return form_fields class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage): """ Page to view an online payment ticket """ form_fields = grok.AutoFields(INigeriaApplicantOnlinePayment).omit('ac', 'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item', 'display_item', 'p_session', 'p_split_data') form_fields[ 'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') form_fields[ 'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage): """Deliver a PDF slip of the context. """ # use IApplicantOnlinePayment alternativly form_fields = grok.AutoFields(INigeriaApplicantOnlinePayment).omit( 'p_item', 'p_option', 'p_combi', 'display_item', 'p_session', 'thirdparty_amt', 'p_split_data') form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') def render(self): if self.payment_slip_download_warning: self.flash(self.payment_slip_download_warning, type='danger') self.redirect(self.url(self.context)) return applicantview = CustomApplicantBaseDisplayFormPage(self.context.__parent__, self.request) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF(self,'payment_slip.pdf', self.context.__parent__, applicantview, note=self.note, omit_fields=()) class PunitFormPage(KofaEditFormPage): """ """ grok.context(ICustomApplicant) grok.require('waeup.handleApplication') grok.name('punitformpage') form_fields = grok.AutoFields(IPollingUnit) grok.template('puniteditpage') label = _('Locate polling unit') pnav = 3 @action(_('Save'), style='invisible') def save(self, **data): changed_fields = self.applyData(self.context, **data) # Turn list of lists into single list if changed_fields: changed_fields = reduce(lambda x, y: x+y, changed_fields.values()) if 'federalstate' in changed_fields: # Clear other form fields self.context.lga = self.context.ward = self.context.punit = None self.flash(_('Federal State has been saved.')) return if 'lga' in changed_fields: # Clear other form fields self.context.ward = self.context.punit = None self.flash(_('LGA has been saved.')) return if 'ward' in changed_fields: # Clear other form fields self.context.punit = None self.flash(_('Ward has been saved.')) return if 'punit' in changed_fields and self.context.punit: self.flash(_('Polling Unit has been successfully saved.')) self.redirect(self.url(self.context)) return class USSDInfoPage(KofaPage): """ """ grok.context(ICustomApplicantOnlinePayment) grok.require('waeup.handleApplication') grok.name('ussdinfo') label = _('Pay via USSD') grok.template('ussdinfo') pnav = 3