## $Id: browser.py 17777 2024-05-13 14:59:01Z 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
import os
from zope.component import getUtility, getAdapter
from zope.i18n import translate
from zope.catalog.interfaces import ICatalog
from hurry.workflow.interfaces import IWorkflowState
from zope.component import queryUtility
from zope.catalog.interfaces import ICatalog
from waeup.kofa.interfaces import (
    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
from zope.formlib.textwidgets import BytesDisplayWidget
from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
from waeup.kofa.utils.helpers import string_from_bytes, file_size
from waeup.kofa.applicants.browser import (
    ApplicantCheckStatusPage,
    AdditionalFile,
    RefereeReportAddFormPage,
    RefereeReportDisplayFormPage,
    RefereeReportManageFormPage,
    ExportPDFReportSlipPage,
    ExportPDFReportSlipPage2)
from waeup.kofa.applicants.workflow import STARTED, PAID
from waeup.kofa.applicants.viewlets import PDFActionButton
from waeup.kofa.applicants.interfaces import IApplicantRegisterUpdate
from waeup.kofa.browser.layout import UtilityView, action
from waeup.kofa.students.interfaces import IStudentsUtils
from waeup.kofa.interfaces import IPDF
from waeup.kofa.browser.viewlets import ManageActionButton
from waeup.aaue.interfaces import MessageFactory as _
from kofacustom.nigeria.applicants.browser import (
    NigeriaApplicantDisplayFormPage,
    NigeriaApplicantManageFormPage,
    NigeriaApplicantEditFormPage,
    NigeriaPDFApplicationSlip,
    NigeriaApplicantRegistrationPage,
    NigeriaExportPDFPaymentSlipPage,
    )
from kofacustom.nigeria.applicants.interfaces import OMIT_DISPLAY_FIELDS
from waeup.aaue.applicants.interfaces import (
    ICustomUGApplicant,
    ICustomPGApplicant,
    ICustomUGApplicantEdit,
    ICustomPGApplicantEdit,
    ITranscriptApplicant,
    ICertificateRequest,
    ICustomApplicant,
    IVerificationRequest,
    ISendByEmailRequest,
    IFedexRequest,
    IRecruitment,
    ICustomApplicantOnlinePayment,
    ICustomApplicantRefereeReport,
    IResultReissuanceRequest,
    )

UG_OMIT_FIELDS = (
      'hq_type', 'hq_fname', 'hq_matric_no',
      'hq_degree', 'hq_school', 'hq_session', 'hq_disc',
      'hq_type2', 'hq_fname2', 'hq_matric_no2',
      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
      'hq_type3', 'hq_fname3', 'hq_matric_no3',
      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
      'nysc_year',
      'nysc_location',
      'nysc_lga',
      'employer',
      'emp_position',
      'emp_start',
      'emp_end',
      'emp_reason',
      'employer2',
      'emp2_position',
      'emp2_start',
      'emp2_end',
      'emp2_reason',
      'former_matric',
      )
UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
    'jamb_subjects_list', 'master_sheet_number') + UG_OMIT_FIELDS
UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + UG_OMIT_FIELDS + (
      'alr_fname', 'alr_no', 'alr_date',
      'alr_results', 'notice')
UG_OMIT_MANAGE_FIELDS = (
    'special_application','jamb_subjects_list',) + UG_OMIT_FIELDS
UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
    'student_id',
    'notice',
    'jamb_age',
    'jamb_subjects',
    'jamb_score',
    'jamb_reg_number',
    'aggregate',
    'master_sheet_number',
    'screening_venue',
    'screening_score',
    'screening_date'
    )

UDE_OMIT_FIELDS = (
      'nysc_year',
      'nysc_location',
      'nysc_lga',
      'employer',
      'emp_position',
      'emp_start',
      'emp_end',
      'emp_reason',
      'employer2',
      'emp2_position',
      'emp2_start',
      'emp2_end',
      'emp2_reason',
      'former_matric',
      )
UDE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
    'jamb_subjects_list', 'master_sheet_number') + UDE_OMIT_FIELDS
UDE_OMIT_PDF_FIELDS = UDE_OMIT_DISPLAY_FIELDS + UDE_OMIT_FIELDS + (
      #'alr_fname', 'alr_no', 'alr_date', 'alr_results',
      'hq_type2', 'hq_fname2', 'hq_matric_no2',
      'hq_degree2', 'hq_school2', 'hq_session2', 'hq_disc2',
      'hq_type3', 'hq_fname3', 'hq_matric_no3',
      'hq_degree3', 'hq_school3', 'hq_session3', 'hq_disc3',
      'notice')
UDE_OMIT_MANAGE_FIELDS = (
    'special_application','jamb_subjects_list',) + UDE_OMIT_FIELDS
UDE_OMIT_EDIT_FIELDS = UDE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
    'student_id',
    'notice',
    'jamb_age',
    'jamb_subjects',
    'jamb_score',
    'jamb_reg_number',
    'aggregate',
    'master_sheet_number',
    'screening_venue',
    'screening_score',
    'screening_date'
    )

#UG_OMIT_PDF_FIELDS = tuple([
#    element for element in UG_OMIT_PDF_FIELDS if not element == 'phone'])

#UG_OMIT_PDF_FIELDS += (
#      'reg_number','alr_fname', 'alr_no', 'alr_date',
#      'alr_results', 'notice'
#      )

PG_OMIT_FIELDS = (

    )
PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
    ) + PG_OMIT_FIELDS
PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + PG_OMIT_FIELDS + (
      )
PG_OMIT_MANAGE_FIELDS = (
    ) + PG_OMIT_FIELDS
PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
    )

PTEE_OMIT_FIELDS = (
    'jamb_age',
    'jamb_subjects',
    'jamb_score',
    'jamb_reg_number',
    'aggregate'
    )
PTEE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + (
    'jamb_subjects_list',) + PTEE_OMIT_FIELDS
PTEE_OMIT_PDF_FIELDS = PTEE_OMIT_DISPLAY_FIELDS + PTEE_OMIT_FIELDS + (
      'reg_number','alr_fname', 'alr_no', 'alr_date',
      'alr_results', 'notice',
      'nysc_year',
      'nysc_location',
      'nysc_lga',
      'employer',
      'emp_position',
      'emp_start',
      'emp_end',
      'emp_reason',
      'employer2',
      'emp2_position',
      'emp2_start',
      'emp2_end',
      'emp2_reason',
      'former_matric',
    )
PTEE_OMIT_MANAGE_FIELDS = (
    'special_application','jamb_subjects_list',) + PTEE_OMIT_FIELDS
PTEE_OMIT_EDIT_FIELDS = PTEE_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
    'student_id',
    'notice',
    )

UPDATE_OMIT_FIELDS = (
    'firstname',
    'middlename',
    'lastname',
    'sex',
    'lga',
    'course1',
    )

MAX_FILE_UPLOAD_SIZE = 1024 * 500

class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
    """A display view for applicant data.
    """

    @property
    def form_fields(self):
        if self.target is not None and self.target == 'trans':
            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
                'locked', 'suspended')
            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
            form_fields['perm_address'].custom_widget = BytesDisplayWidget
            return form_fields
        if self.target is not None and self.target == 'ver':
            form_fields = grok.AutoFields(IVerificationRequest).omit(
                'locked', 'suspended')
            form_fields['body_address'].custom_widget = BytesDisplayWidget
            return form_fields
        if self.target is not None and self.target == 'fedex':
            form_fields = grok.AutoFields(IFedexRequest).omit(
                'locked', 'suspended')
            return form_fields
        if self.target is not None and self.target == 'rec':
            form_fields = grok.AutoFields(IRecruitment).omit(
                'locked', 'suspended')
            form_fields['address'].custom_widget = BytesDisplayWidget
            form_fields['position'].custom_widget = BytesDisplayWidget
            return form_fields
        if self.target is not None and self.target == 'send':
            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
                'locked', 'suspended')
            form_fields['body_address'].custom_widget = BytesDisplayWidget
            return form_fields
        if self.target is not None and self.target == 'res':
            form_fields = grok.AutoFields(IResultReissuanceRequest).omit(
                'locked', 'suspended', 'request_type')
            form_fields['body_address'].custom_widget = BytesDisplayWidget
            return form_fields
        if self.target is not None and self.target == 'cert':
            form_fields = grok.AutoFields(ICertificateRequest).omit(
                'locked', 'suspended')
            return form_fields
        if self.target is not None and self.target in ('ptee','dsh',):
            form_fields = grok.AutoFields(ICustomUGApplicant)
            for field in PTEE_OMIT_DISPLAY_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('bridge', 'ude',):
            form_fields = grok.AutoFields(ICustomUGApplicant)
            for field in UDE_OMIT_DISPLAY_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target.startswith('pg'):
            form_fields = grok.AutoFields(ICustomPGApplicant)
            for field in PG_OMIT_DISPLAY_FIELDS:
                form_fields = form_fields.omit(field)
        else:
            form_fields = grok.AutoFields(ICustomUGApplicant)
            for field in UG_OMIT_DISPLAY_FIELDS:
                form_fields = form_fields.omit(field)
        if not getattr(self.context, 'student_id'):
            form_fields = form_fields.omit('student_id')
        if not getattr(self.context, 'screening_score'):
            form_fields = form_fields.omit('screening_score')
        if not getattr(self.context, 'screening_venue') or \
            self.context.state not in ('submitted', 'admitted', 'created'):
            form_fields = form_fields.omit('screening_venue')
        if not getattr(self.context, 'screening_date') or \
            self.context.state not in ('submitted', 'admitted', 'created'):
            form_fields = form_fields.omit('screening_date')
        return form_fields

    def getCourseAdmitted(self):
        """Return link, title and code in html format to the certificate
           admitted.
        """
        if self.layout.isApplicant():
            return ''
        course_admitted = self.context.course_admitted
        if getattr(course_admitted, '__parent__',None):
            url = self.url(course_admitted)
            title = course_admitted.title
            code = course_admitted.code
            return '<a href="%s">%s - %s</a>' %(url,code,title)
        return ''

class CustomPDFActionButton(PDFActionButton):

    @property
    def target_url(self):
        if self.context.state in ('initialized', 'started', 'paid'):
            # or self.context.special or self.view.target in ('trans', 'cert'):
            return
        return self.view.url(self.view.context, self.target)


class CustomPDFApplicationSlip(NigeriaPDFApplicationSlip):

    column_two_fields = ('applicant_id', 'reg_number',
        'firstname', 'middlename', 'lastname', 'sex', 'date_of_birth')
    #two_columns_design_fields = [
    #    'fst_sit_fname', 'fst_sit_no', 'fst_sit_date',
    #    'fst_sit_type', 'fst_sit_results',
    #    'scd_sit_fname', 'scd_sit_no', 'scd_sit_date',
    #    'scd_sit_type', 'scd_sit_results']

    def _getCourseAdmittedLink(self, view):
        return None

    def _getDeptAndFaculty(self):
        return [None, None]

    @property
    def note(self):
        note = getattr(self.context.__parent__, 'application_slip_notice', None)
        if note:
            return '<br /><br />' + note
        if self.target is not None and self.target in (
            'trans', 'cert', 'ver', 'send', 'fedex'):
            return
        if self.context.sex == 'm':
            pronoun = 'he'
        else:
            pronoun = 'she'
        return '''
The applicant has acknowledged that, if discovered at any time that %s does not possess
any of the qualifications which %s claims %s has obtained, %s will be expelled from the
University not be re-admitted for the same or any other programme, even if %s has
upgraded previous qualifications or possess additional qualifications.

''' % (
    pronoun, pronoun, pronoun, pronoun, pronoun)

    @property
    def form_fields(self):
        # AAUE is using the same interface for all regular applications.
        form_fields = grok.AutoFields(ICustomUGApplicant)
        if self.target is not None and self.target.startswith('pg'):
            for field in PG_OMIT_PDF_FIELDS:
                form_fields = grok.AutoFields(ICustomPGApplicant)
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('ptee', 'dsh',):
            for field in PTEE_OMIT_PDF_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('bridge', 'ude',):
            for field in UDE_OMIT_PDF_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target == 'trans':
            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
                'locked', 'suspended')
        elif self.target is not None and self.target == 'ver':
            form_fields = grok.AutoFields(IVerificationRequest).omit(
                'locked', 'suspended')
        elif self.target is not None and self.target == 'send':
            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
                'locked', 'suspended')
        if self.target is not None and self.target == 'res':
            form_fields = grok.AutoFields(IResultReissuanceRequest).omit(
                'locked', 'suspended', 'request_type')
        elif self.target is not None and self.target == 'cert':
            form_fields = grok.AutoFields(ICertificateRequest).omit(
                'locked', 'suspended')
        elif self.target is not None and self.target == 'fedex':
            form_fields = grok.AutoFields(IFedexRequest).omit(
                'locked', 'suspended')
        else:
            for field in UG_OMIT_PDF_FIELDS:
                form_fields = form_fields.omit(field)
        if not getattr(self.context, 'student_id'):
            form_fields = form_fields.omit('student_id')
        if not getattr(self.context, 'screening_score'):
            form_fields = form_fields.omit('screening_score')
        if not getattr(self.context, 'screening_venue'):
            form_fields = form_fields.omit('screening_venue')
        if not getattr(self.context, 'screening_date'):
            form_fields = form_fields.omit('screening_date')
        hqfields = ('hq_type', 'hq_fname', 'hq_matric_no',
                    'hq_degree', 'hq_school', 'hq_session', 'hq_disc')
        if not getattr(self.context, 'hq_type'):
            for hq in hqfields:
                form_fields = form_fields.omit(hq)
        if not getattr(self.context, 'hq_type2'):
            for hq in hqfields:
                form_fields = form_fields.omit(hq + '2')
        if not getattr(self.context, 'hq_type3'):
            for hq in hqfields:
                form_fields = form_fields.omit(hq + '3')
        if not getattr(self.context, 'hq_type4'):
            for hq in hqfields:
                form_fields = form_fields.omit(hq + '4')
        return form_fields

class CustomApplicantManageFormPage(NigeriaApplicantManageFormPage):
    """A full edit view for applicant data.
    """

    def display_fileupload(self, filename):
        if filename[1] == 'stateresult':
            if self.target in ('trans', 'cert'):
                return True
        if filename[1] == 'verificationdoc':
            if self.target in ('ver', 'send'):
                return True
        return False

    @property
    def form_fields(self):
        if self.target is not None and self.target == 'trans':
            form_fields = grok.AutoFields(ITranscriptApplicant)
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'cert':
            form_fields = grok.AutoFields(ICertificateRequest)
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'ver':
            form_fields = grok.AutoFields(IVerificationRequest)
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'send':
            form_fields = grok.AutoFields(ISendByEmailRequest)
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'res':
            form_fields = grok.AutoFields(IResultReissuanceRequest).omit(
                'request_type')
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'fedex':
            form_fields = grok.AutoFields(IFedexRequest)
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'rec':
            form_fields = grok.AutoFields(IRecruitment)
            form_fields['applicant_id'].for_display = True
            return form_fields
        # AAUE is using the same interface for all regular applications.
        form_fields = grok.AutoFields(ICustomUGApplicant)
        if self.target is not None and self.target.startswith('pg'):
            form_fields = grok.AutoFields(ICustomPGApplicant)
            for field in PG_OMIT_MANAGE_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('ptee', 'dsh',):
            for field in PTEE_OMIT_MANAGE_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('bridge', 'ude',):
            for field in UDE_OMIT_MANAGE_FIELDS:
                form_fields = form_fields.omit(field)
        else:
            for field in UG_OMIT_MANAGE_FIELDS:
                form_fields = form_fields.omit(field)
        form_fields['student_id'].for_display = True
        form_fields['applicant_id'].for_display = True
        return form_fields

class CustomApplicantEditFormPage(NigeriaApplicantEditFormPage):
    """An applicant-centered edit view for applicant data.
    """

    def display_fileupload(self, filename):
        if filename[1] == 'stateresult':
            if self.target in ('trans', 'cert'):
                return True
        if filename[1] == 'verificationdoc':
            if self.target in ('ver', 'send'):
                return True
        return False

    def unremovable(self, ticket):
        return True

    def dataNotComplete(self, data):
        store = getUtility(IExtFileStore)
        # Temporarily enable passport upload also for cert and trans
        # applications.
        if self.picture_editable:
            if not store.getFileByContext(self.context, attr=u'passport.jpg'):
                return _('No passport picture uploaded.')
            if not self.target in ('cert', 'trans') and \
                not self.request.form.get('confirm_passport', False):
                return _('Passport picture confirmation box not ticked.')
        if self.target in ('trans', 'cert') and \
            not store.getFileByContext(self.context, attr=u'stateresult'):
            return _('No statement of result pdf file uploaded.')
        if self.target in ('ver',) and \
            not store.getFileByContext(self.context, attr=u'verificationdoc'):
            return _('No pdf file uploaded.')
        if self.target == 'fedex':
            cat = getUtility(ICatalog, name='applicants_catalog')
            results = list(cat.searchResults(
                applicant_id=(data['trans_id'], data['trans_id'])))
            if not results:
                return _('The transcript application id does not exist.')
        return False

    # AAUE applicants never see the 'Remove Selected Tickets' button.
    @property
    def display_actions(self):
        # If the form is unlocked, applicants are allowed to save the form
        # and remove unused tickets.
        actions = [[_('Save')], []]
        # Only in state started they can also add tickets.
        if self.context.state == STARTED:
            actions = [[_('Save')],
                [_('Add online payment ticket')]]
        # In state paid, they can submit the data and further add tickets
        # if the application is special.
        elif self.context.special and self.context.state == PAID:
            actions = [[_('Save'), _('Finally Submit')],
                [_('Add online payment ticket')]]
        elif self.context.state == PAID:
            actions = [[_('Save'), _('Finally Submit')], []]
        return actions

    @property
    def form_fields(self):
        if self.target is not None and self.target == 'trans':
            form_fields = grok.AutoFields(ITranscriptApplicant).omit(
                'locked', 'suspended')
            form_fields['applicant_id'].for_display = True
            form_fields['reg_number'].for_display = True
            form_fields['place_of_birth'].field.required = True
            form_fields['date_of_birth'].field.required = True
            form_fields['nationality'].field.required = True
            form_fields['email'].field.required = True
            form_fields['phone'].field.required = True
            form_fields['perm_address'].field.required = True
            form_fields['dispatch_address'].field.required = True
            form_fields['entry_mode'].field.required = True
            form_fields['entry_session'].field.required = True
            form_fields['end_session'].field.required = True
            form_fields['course_studied'].field.required = True
            return form_fields
        if self.target is not None and self.target == 'cert':
            form_fields = grok.AutoFields(ICertificateRequest).omit(
                'locked', 'suspended')
            form_fields['applicant_id'].for_display = True
            form_fields['reg_number'].for_display = True
            form_fields['place_of_birth'].field.required = True
            form_fields['date_of_birth'].field.required = True
            form_fields['nationality'].field.required = True
            form_fields['email'].field.required = True
            form_fields['phone'].field.required = True
            form_fields['entry_session'].field.required = True
            form_fields['end_session'].field.required = True
            form_fields['course_studied'].field.required = True
            form_fields['certificate_type'].field.required = True
            # Additional omissions
            if self.context.__parent__.code == 'cert5':
                for field in ('firstname', 'middlename', 'lastname'):
                    form_fields[field].for_display = True
            return form_fields
        if self.target is not None and self.target == 'ver':
            form_fields = grok.AutoFields(IVerificationRequest).omit(
                'locked', 'suspended')
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'send':
            form_fields = grok.AutoFields(ISendByEmailRequest).omit(
                'locked', 'suspended')
            return form_fields
        if self.target is not None and self.target == 'res':
            form_fields = grok.AutoFields(IResultReissuanceRequest).omit(
                'locked', 'suspended', 'request_type')
            return form_fields
        if self.target is not None and self.target == 'fedex':
            form_fields = grok.AutoFields(IFedexRequest).omit(
                'locked', 'suspended')
            form_fields['applicant_id'].for_display = True
            return form_fields
        if self.target is not None and self.target == 'rec':
            form_fields = grok.AutoFields(IRecruitment).omit(
                'locked', 'suspended')
            form_fields['applicant_id'].for_display = True
            return form_fields
        # AAUE is using the same interface for all regular applications.
        form_fields = grok.AutoFields(ICustomUGApplicantEdit)
        if self.target is not None and self.target.startswith('pg'):
            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
            for field in PG_OMIT_EDIT_FIELDS:
                form_fields = form_fields.omit(field)
            form_fields['screening_venue'].for_display = True
            form_fields['screening_date'].for_display = True
            form_fields['screening_score'].for_display = True
            form_fields['student_id'].for_display = True
            form_fields['notice'].for_display = True
        elif self.target is not None and self.target in ('ptee','dsh',):
            for field in PTEE_OMIT_EDIT_FIELDS:
                form_fields = form_fields.omit(field)
        elif self.target is not None and self.target in ('bridge', 'ude',):
            for field in UDE_OMIT_EDIT_FIELDS:
                form_fields = form_fields.omit(field)
        else:
            for field in UG_OMIT_EDIT_FIELDS:
                form_fields = form_fields.omit(field)
        # Additional omissions
        if self.target is not None and self.target in ('ude', 'utme'):
            for field in UPDATE_OMIT_FIELDS:
                form_fields[field].for_display = True
        form_fields['applicant_id'].for_display = True
        form_fields['reg_number'].for_display = True
        return form_fields

    def update(self):
        if self.context.locked or (
            self.context.__parent__.expired and
            self.context.__parent__.strict_deadline):
            self.emit_lock_message()
            return
        course1_in_form = self.request.form.get('form.course1', None)
        course2_in_form = self.request.form.get('form.course2', None)
        course3_in_form = self.request.form.get('form.course3', None)
        cat = queryUtility(ICatalog, name='certificates_catalog')
        if self.target is not None and self.target == 'utme':
            if course2_in_form:
                if  not self.context.jamb_score:
                    self.flash(("Total JAMB score not set."), type='danger')
                    self.redirect(self.url(self.context))
                    return
                results = list(
                    cat.searchResults(code=(course2_in_form, course2_in_form)))
                cutoff = getattr(results[0], 'custom_float_1')
                if cutoff and cutoff > self.context.jamb_score:
                    self.flash("You do not meet the minimum cutoff mark for your 2nd choice course. Please consider selecting an alternative choice.",
                        type='danger')
                    self.redirect(self.url(self.context))
                    return
            if course3_in_form:
                if  not self.context.jamb_score:
                    self.flash(("Total JAMB score not set."), type='danger')
                    self.redirect(self.url(self.context))
                    return
                results = list(
                    cat.searchResults(code=(course3_in_form, course3_in_form)))
                cutoff = getattr(results[0], 'custom_float_1')
                if cutoff and cutoff > self.context.jamb_score:
                    self.flash("You do not meet the minimum cutoff mark for your 3rd choice course. Please consider selecting an alternative choice.",
                        type='danger')
                    self.redirect(self.url(self.context))
                    return
        if getattr(self.context.course1, 'code', 'nocourse') == course2_in_form:
            self.flash(_('2nd choice course must differ from 1st choice course.'),
                       type='danger')
            self.redirect(self.url(self.context))
            return
        if getattr(self.context.course1, 'code', 'nocourse') == course3_in_form:
            self.flash(_('3rd choice course must differ from 1st choice course.'),
                       type='danger')
            self.redirect(self.url(self.context))
            return
        super(CustomApplicantEditFormPage, self).update()
        return

class CustomApplicantRegistrationPage(NigeriaApplicantRegistrationPage):
    """Captcha'd registration page for applicants.
    """

    @property
    def form_fields(self):
        form_fields = None
        if self.context.mode == 'update':
            form_fields = grok.AutoFields(IApplicantRegisterUpdate).select(
                'lastname','reg_number','email')
            target = getattr(self.context, 'prefix', None)
            if target in ('trans', 'cert'):
                form_fields.get('reg_number').field.title = u'Matriculation Number'
        else: #if self.context.mode == 'create':
            form_fields = grok.AutoFields(ICustomUGApplicantEdit).select(
                'firstname', 'middlename', 'lastname', 'email', 'phone')
        return form_fields

    def _redirect(self, email, password, applicant_id):
        # Forward email and credentials to landing page.
        self.redirect(self.url(self.context, 'registration_complete',
            data = dict(email=email, password=password,
            applicant_id=applicant_id)))
        return

    @property
    def _postfix(self):
        """Alumni records have to be imported into several containers.
        Therefore a string must be added to their registration number
        to make it unique.
        """
        if self.context.prefix in ('trans', 'cert'):
            return self.context.code
        return ''

class ApplicantBaseDisplayFormPage(CustomApplicantDisplayFormPage):
    grok.context(ICustomApplicant)
    grok.name('base')

    @property
    def form_fields(self):
        if self.context.__parent__.prefix in ('fedex',):
            form_fields = grok.AutoFields(IFedexRequest).select(
                'applicant_id', 'trans_id', 'email',)
        else:
            form_fields = grok.AutoFields(ICustomApplicant).select(
                'applicant_id', 'reg_number', 'email', 'course1')
        if self.context.__parent__.prefix in ('special',):
            form_fields['reg_number'].field.title = u'Identification Number'
            return form_fields
        return form_fields

class CustomExportPDFPaymentSlipPage(NigeriaExportPDFPaymentSlipPage):

    form_fields = grok.AutoFields(ICustomApplicantOnlinePayment).omit(
        'ac', 'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item',
        'p_split_data')
    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')

    @property
    def payment_slip_download_warning(self):
        return ''

    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 = ApplicantBaseDisplayFormPage(self.context.__parent__,
            self.request)
        students_utils = getUtility(IStudentsUtils)
        return students_utils.renderPDF(self,'payment_slip.pdf',
            self.context.__parent__, applicantview, note=self.note)

class CustomApplicantCheckStatusPage(ApplicantCheckStatusPage):
    """Captcha'd status checking page for applicants.
    """
    grok.template('applicantcheckstatus')

class ScreeningInvitationActionButton(ManageActionButton):
    grok.order(8) # This button should always be the last one.
    grok.context(ICustomApplicant)
    grok.view(CustomApplicantDisplayFormPage)
    grok.require('waeup.viewApplication')
    icon = 'actionicon_pdf.png'
    text = _('Download screening invitation letter')
    target = 'screening_invitation.pdf'

    @property
    def target_url(self):
        if not self.context.screening_date or not self.context.state in (
            'submitted', 'admitted', 'created'):
            return ''
        return self.view.url(self.view.context, self.target)

class ExportScreeningInvitationLetter(UtilityView, grok.View):
    """Deliver a slip with only screening data.
    This form page is available only in AAUE.
    """
    grok.context(ICustomApplicant)
    grok.name('screening_invitation.pdf')
    grok.require('waeup.viewApplication')
    prefix = 'form'

    label = u'Screening Invitation Letter'

    form_fields = []

    @property
    def note(self):
        if self.context.screening_date:
            year = self.context.__parent__.year
            session = '%s/%s' % (year, year + 1)
            sdate = self.context.screening_date
            stime = ''
            if '@' in self.context.screening_date:
                sdate = self.context.screening_date.split('@')[0].strip()
                stime = self.context.screening_date.split('@')[1].strip()
            return """
<br /><br /><br /><br /><font size='12'>
Dear %s,
<br /><br />
You are invited to the Ambrose Alli University %s Admissions Screening Exercise.
<br /><br />
<strong>Date: %s
<br /><br />
Time: %s
<br /><br />
Venue: %s
</strong>
<br /><br />
Please bring this letter of invitation and the downloaded application form along with you on your screening date.
<br /><br />
You are expected to be available 30 minutes before the commencement of your Screening.
</font>

""" % (
       self.context.display_fullname,
       session,
       sdate,
       stime,
       self.context.screening_venue)
        return

    @property
    def title(self):
        return None

    def update(self):
        if not self.context.screening_date or not self.context.state in (
            'submitted', 'admitted', 'created'):
            self.flash(_('Forbidden'), type="warning")
            self.redirect(self.url(self.context))

    def render(self):
        applicantview = ApplicantBaseDisplayFormPage(self.context, self.request)
        students_utils = getUtility(IStudentsUtils)
        return students_utils.renderPDF(self,'screening_data.pdf',
            self.context, applicantview, note=self.note)

class CustomRefereeReportAddFormPage(RefereeReportAddFormPage):
    """Add-form to add an referee report. This form
    is protected by a mandate.
    """
    form_fields = grok.AutoFields(
        ICustomApplicantRefereeReport).omit('creation_date')

class CustomRefereeReportDisplayFormPage(RefereeReportDisplayFormPage):
    """A display view for referee reports.
    """
    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
    form_fields[
        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')

class CustomRefereeReportManageFormPage(RefereeReportManageFormPage):
    """A displaymanage for referee reports.
    """
    form_fields = grok.AutoFields(ICustomApplicantRefereeReport).omit('creation_date')

class CustomExportPDFReportSlipPage(ExportPDFReportSlipPage):
    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
    form_fields[
        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')

class CustomExportPDFReportSlipPage2(ExportPDFReportSlipPage2):
    form_fields = grok.AutoFields(ICustomApplicantRefereeReport)
    form_fields[
        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')

class StateResult(AdditionalFile):
    """Renders the pdf form extension for applicants.
    """
    grok.name('stateresult')

class VerificationDoc(AdditionalFile):
    """Renders the pdf form extension for applicants.
    """
    grok.name('verificationdoc')
