## Script (Python) "logged_in"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
"""Prepare user login
modified from cps_default/logged_in.py

$Id: logged_in.py 1933 2007-06-19 05:05:29Z henrik $
"""
try:
    from Products.zdb import set_trace
except:
    def set_trace():
        pass
import DateTime
import os
current = DateTime.DateTime()
import logging
logger = logging.getLogger('Skins.logged_in')


from urllib import unquote

request = context.REQUEST
response = request.RESPONSE
utool = context.portal_url
mtool = context.portal_membership
wftool = context.portal_workflow
portal = utool.getPortalObject()

redirect_to_portal = False
is_anon = mtool.isAnonymousUser()
member = mtool.getAuthenticatedMember()
member_id = str(member)

try:
    cred = context.waeup_tool.getCredentialFromAuthHeader(request)
except:
    cred = "no authentication header"

if context.isStaff():
    is_unsecure = context.waeup_tool.checkGenericPassword(member_id)
    if is_unsecure:
        response.expireCookie('__ac', path='/')
        return response.redirect("%s/user_logged_in_disabled" % context.portal_url())

#load_passport = hasattr(context.waeup_tool,'loadStudentFoto')

if not is_anon:
    if "Student" in member.getRoles():
        students = context.portal_url.getPortalObject().campus.students
        student = getattr(students,member_id)
        student_app = getattr(student,'application',None)
        student_per = getattr(student,'personal',None)


        #########################################################

        # perform makeStudentData for returning students who login for the first time
        # the returning key comes from set_access_data

        if request.has_key('returning') and  student_per is None:
            email=request.get("email")
            phone=request.get("phone_nr")
            context.waeup_tool.makeStudentData(member_id,
                                                   email=email,
                                                   phone_nr=phone,
                                                   )
            #d = {}
            #d['id'] = member_id
            #d['email'] = email
            #d['phone'] = phone
            #context.students_catalog.modifyRecord(**d)
        elif student_per is None:
            context.waeup_tool.makeStudentData(member_id)

        #########################################################

        # add missing payments folder

        if 'payments' not in student.objectIds():
            student.invokeFactory('PaymentsFolder','payments')
            payments = getattr(student,'payments')
            wftool.doActionFor(payments,'open')
            d = {}
            d['Title'] = 'Online Payments'
            payments.getContent().edit(mapping=d)

        #########################################################

        #student_pume = getattr(student,'pume',None)
        s_review_state = context.getStudentReviewState(student.id)
        a_review_state = wftool.getInfoFor(student_app,'review_state',None)
        student_per = getattr(student,'personal',None)
        p_review_state = wftool.getInfoFor(student_per,'review_state',None)
        logger.info('%s logged in, review_state %s' % (member,s_review_state))
        if student_app is None:
            logger.info('%s logged in, without application object' % (member))
        else:
            app_doc = student_app.getContent()

        res = context.students_catalog(id = member_id)
        matric_no = res[0].matric_no
        jamb_reg_no = res[0].jamb_reg_no
        entry_mode = res[0].entry_mode
        verdict = res[0].verdict
        level = res[0].level
        has_level = level
        has_verdict = verdict and not verdict == 'N/A'

        #########################################################

        # save email and phone of returning students after all objects have been created

        if request.has_key('returning') and student_app:
            email=request.get("email")
            phone=request.get("phone_nr")
            # should be always closed, however ...
            #if a_review_state != 'opened':
            #    wftool.doActionFor(student_app,'open')
            # should be always opened after import, however ...
            if p_review_state != 'opened':
                wftool.doActionFor(student_per,'open')
            per_doc = student_per.getContent()
            #app_doc.edit(mapping = {'app_email' : email})
            per_doc.edit(mapping = {'email' : email, 'phone' : phone})
            #wftool.doActionFor(student_app,'close')

        #########################################################

        # look for passport pictures of returning students

        if s_review_state == 'returning' and\
           not context.waeup_tool.picturesExist(('passport',), member_id):
            folder = 'pictures_returning'
            #res = context.students_catalog(id = member_id)
            filename = res[0].matric_no.upper()
            msg = context.waeup_tool.loadStudentFoto(student,filename,folder)
            logger.info('%s (%s), %s' % (member,s_review_state,msg))

        #########################################################

        # look for passport pictures of transfer students

        if entry_mode == 'transfer' and\
           s_review_state in ('returning','school_fee_paid',) and\
           not context.waeup_tool.picturesExist(('passport',), member_id):
            res_both = context.students_catalog(jamb_reg_no = jamb_reg_no)
            #set_trace()
            if len(res_both) == 2:
                for ts in res_both:
                    if ts.id != member_id:
                        msg = context.waeup_tool.loadTransferStudentFoto(ts.id,member_id)
                        logger.info('%s (%s on transfer), %s' % (member,s_review_state,msg))

        #########################################################

        # look for passport pictures of new students

        if s_review_state in ('admitted',
                              'student_created',
                              'clearance_pin_entered',
                              'clearance_requested'
                             )  and not context.waeup_tool.picturesExist(('passport',),
                                                                         member_id):
            folder = 'pictures_admitted_latest'
            #filename = app_doc.jamb_reg_no.replace('/','_')
            filename = member_id
            msg = context.waeup_tool.loadStudentFoto(student,filename,folder)
            logger.info('%s (%s), %s' % (member,s_review_state,msg))
            if 'passport picture not found' in msg:
                filename = app_doc.app_reg_pin.replace('-','')
                msg = context.waeup_tool.loadStudentFoto(student,filename,folder)
                logger.info('%s (%s), %s' % (member,s_review_state,msg))

        #########################################################

        # perform necessary updates for new students

        # 1. add pin and application date to app_doc

        if s_review_state == "student_created":
            wftool.doActionFor(student,'admit')
            s_review_state = 'admitted'

        if s_review_state == "admitted" and a_review_state == 'created':
            wftool.doActionFor(student_app,'open')
            #if student_pume is not None:
            #  wftool.doActionFor(student_pume,'close')
            da = {}
            pin = request.get('pin')

            # if the student comes directly, add missing pin or pin with wrong syntax (fix)
            if not pin:
                jamb_reg_no = app_doc.jamb_reg_no
                for reg_no in (jamb_reg_no,jamb_reg_no.lower(),jamb_reg_no.upper()):
                    res = context.portal_pins(student=reg_no)
                    if len(res) > 0:
                        break
                if len(res) > 0:
                    p = res[0].pin
                    if len(p) > 10:
                        if p.startswith('IPTP'):
                            pin = "%s-%s-%s" % (p[:4],p[4:5],p[5:])
                        else:
                            pin = "%s-%s-%s" % (p[:3],p[3:-10],p[-10:])
                    else:
                        pin = p
            da['app_ac_pin'] = pin
            da['app_ac_date'] = current
            app_doc.edit(mapping = da)

        # 2. same as 1 but without opening app_doc, assuming that the student already logged in
        #    but the pin is missing in app_doc (fix)

        elif s_review_state in ("admitted") and a_review_state == 'opened' and\
                                            (not app_doc.app_ac_pin or app_doc.app_ac_pin.startswith('IPT-P')):
            jamb_reg_no = app_doc.jamb_reg_no
            for reg_no in (jamb_reg_no,jamb_reg_no.lower(),jamb_reg_no.upper()):
                res = context.portal_pins(student=reg_no)
                if len(res) > 0:
                    break
            if len(res) > 0:
                p = res[0].pin
                if len(p) > 10:
                    if p.startswith('IPTP'):
                        pin = "%s-%s-%s" % (p[:4],p[4:5],p[5:])
                    else:
                        pin = "%s-%s-%s" % (p[:3],p[3:-10],p[-10:])
                else:
                    pin = p
                da = {}
                da['app_ac_pin'] = pin
                app_doc.edit(mapping = da)

        # 3. open clearance object and close application object in state clearance_pin_entered

        elif s_review_state == "clearance_pin_entered":
            student_clr = getattr(student,'clearance',None)
            clr_review_state = wftool.getInfoFor(student_clr,'review_state',None)
            if a_review_state != 'closed':
                wftool.doActionFor(student_app,'close')
            if clr_review_state != 'opened':
                wftool.doActionFor(student_clr,'open')

        # 4. open personal object (fix). This should be done in clearance_edit.

        if p_review_state == 'created':
            wftool.doActionFor(student_per,'open')

        #########################################################

        #if matric_no:
        #    has_results = context.results_import(matric_no = matric_no)
        #else:
        #    has_results = ''

        #########################################################

        # fetch current verdict via getVerdict and level via getLevelFromResultsCosCode

        #if s_review_state in ('returning','school_fee_paid') and not (has_verdict and has_level):
        #    if has_results:
        #        study_course = getattr(student,'study_course')
        #        sc_review_state = wftool.getInfoFor(study_course,'review_state',None)
        #        dsc = {}
        #        if not has_verdict and s_review_state == 'returning':
        #            dsc['current_verdict'] = context.getVerdict(has_results[0].Verdict)[0]
        #        if not has_level and s_review_state == 'returning':
        #            lnr = context.getLevelFromResultsCosCode(has_results)
        #            dsc['current_level'] = "%d00" % lnr
        #        elif not has_level and s_review_state == 'school_fee_paid':
        #            lnr = context.getLevelFromResultsCosCode(has_results)
        #            cv = context.getVerdict(has_results[0].Verdict)[0]
        #            if cv in ('A','B',):
        #                lnr += 1
        #            dsc['current_level'] = "%d00" % lnr
        #            dsc['previous_verdict'] = cv
        #        if sc_review_state != 'opened':
        #            wftool.doActionFor(study_course,'open')
        #        study_course_doc =study_course.getContent()
        #        study_course_doc.edit(mapping = dsc)
        #        wftool.doActionFor(study_course,'close_for_edit')

        #########################################################


        # determine appropriate redirect url

        if s_review_state == "application_pin_entered":
            redirect_url = "%s/application_edit_form" % student.absolute_url()
        elif s_review_state in ('admitted', 'objection_raised',):
            redirect_url = "%s/admission_form" % student.absolute_url()
        elif s_review_state == "clearance_pin_entered":
            redirect_url = "%s/clearance_edit_form" % student.absolute_url()
        elif s_review_state == "cleared_and_validated":
            redirect_url = "%s/personal_edit_form" % student.absolute_url()
        #elif s_review_state == "returning" and has_results:
        #    redirect_url = "%s/session_results_view" % student.absolute_url()
        elif s_review_state in ('school_fee_paid','courses_registered'):
            redirect_url = "%s/study_course/study_course_view" % student.absolute_url()
        else:
            redirect_url = "%s/student_index" % student.absolute_url()


    else:
        logger.info('%s logged in' % (member))
        redirect_url = portal.absolute_url()
#Anonymous
else:
    logger.info('failed login with %s' % cred)
    response.expireCookie('__ac', path='/')
    return context.user_logged_in_failed()

# Setup skins
if (getattr(utool, 'updateSkinCookie', False) and
    utool.updateSkinCookie()):
    context.setupCurrentSkin()

response.redirect(redirect_url)
