## Script (Python) "interswitch_cb"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=
##
# $Id: interswitch_cb.py 7130 2011-11-17 16:37:10Z henrik $
"""
payment callback
"""
try:
    from Products.zdb import set_trace
except:
    def set_trace():
        pass
import logging
logger = logging.getLogger('Skins.interswitch_cb')
from AccessControl import Unauthorized
import DateTime

if context.portal_membership.isAnonymousUser():
    return None

request = context.REQUEST
students = context.portal_url.getPortalObject().campus.students
wftool = context.portal_workflow
mtool = context.portal_membership
member = mtool.getAuthenticatedMember()
member_id = str(member)
#student_id = context.getStudentId()
access_info = context.waeup_tool.getAccessInfo(context)
student_id = access_info['student_id']
if not context.isSectionOfficer() and (student_id is None or student_id != member_id):
    logger.info('%s tried to access payment object of %s' % (member_id,student_id))
    referer = request.get('HTTP_REFERER','none')
    logger.info('%s:%s illegal access, referer = %s' % (member_id,student_id,referer))
    real_ip = request.get('HTTP_X_REAL_IP',"none")
    logger.info('%s:%s illegal access, real_x_ip = %s' % (member_id,student_id,real_ip))
    return context.REQUEST.RESPONSE.redirect("%s/srp_anonymous_view" % context.portal_url())

referer = request.get('HTTP_REFERER','none')
real_ip = request.get('HTTP_X_REAL_IP',"none")
logger.info('%s, callback referer = %s, IP = %s' % (student_id,referer,real_ip))

ontest = False

if not ontest and not 'webpay.interswitchng.com' in referer and not 'waeup.org' in referer:
    logger.info('%s, wrong callback referer %s, callback rejected, IP = %s' % (student_id,referer,real_ip))
    return request.RESPONSE.redirect("%s/waeup_document_view" % context.absolute_url())

student = getattr(students,student_id)
resp_codes = (("desc","resp_desc"),
              ("resp","resp_code"),
              ("txnRef","pay_reference"),
              ("payRef","resp_pay_reference"),
              ("retRef","retRef"),
              ("cardNum","resp_card_num"),
              ("apprAmt","resp_approved_amount"),
              )
pd = {}
for rc,pdk in resp_codes:
    pd[pdk] = request.get(rc,'')

if ontest:
    pd['resp_desc'] = 'Simulated Callback'
    pd['resp_pay_reference'] = 'XXXX'
    pd['resp_code'] = '00'
    pd['resp_card_num'] = '0000'
    pd['resp_approved_amount'] = '4680000'

if pd['resp_code'] == '00' and len(pd['resp_approved_amount']) > 4:
    pd['resp_approved_amount'] = pd['resp_approved_amount'][:-2]
    pd['status'] = 'paid'
else:
    pd['resp_approved_amount'] = '0'
    pd['status'] = 'failed'

review_state = wftool.getInfoFor(context,'review_state',None)
if pd['resp_code'] == '':
    logger.info('%s requeried payment %s for %s and got empty response' % (member,context.getId(),student_id))
    return request.RESPONSE.redirect("%s/waeup_document_view" % context.absolute_url())
if access_info['is_student'] and review_state == 'closed':
    wftool.doActionFor(context,'open')
pay_doc = context.getContent()
resp = pd['resp_code']

#if  resp == '00':
#    try:
#        amount = int(getattr(pay_doc,'amount',0))
#        try:
#            surcharge = int(getattr(pay_doc,'surcharge',0))
#        except:
#            surcharge = 0
#        resp_approved_amount = int(pd['resp_approved_amount'])
#        #set_trace()
#        if not ontest and amount + surcharge != resp_approved_amount:
#            logger.info('Warning: %s, approved amount %s and authorized amount %s are different for payment %s of %s' % (member,resp_approved_amount,amount+surcharge,context.getId(),student_id))
#            pd['status'] = 'failed'
#            pd['resp_desc'] = 'Warning: approved amount in callback does not match!'
#            resp = ''
#        else:
#            pass
#    except:
#        logger.info('%s: approved amount could not be verified for payment %s of %s' % (member,context.getId(),student_id))
#        pd['status'] = 'failed'
#        pd['resp_desc'] = 'Warning: approved amount could not be verified!'
#        resp = ''

pay_doc.edit(mapping = pd)
s_brain = context.students_catalog(id=student_id)[0]
session = s_brain.session

next_info = context.getNextInfo(s_brain)
next_session_id = next_info['next_session_id']
next_session_str = next_info['next_session_str']
next_level_id = next_info['next_level_id']
next_transition = next_info['next_transition']
next_verdict = next_info['next_verdict']
next_previous_verdict = next_info['next_previous_verdict']
if  resp == '00':
    if pay_doc.category == 'schoolfee':
        if context.getStudentReviewState() == "school_fee_paid":
            logger.info('%s paid school_fee in state school_fee_paid' % (student_id))
        else:
            study_course = getattr(student,'study_course')
            try:
                wftool.doActionFor(study_course,'open')
            except:
                pass
            verdict = s_brain.verdict
            if next_previous_verdict == 'N/A':
                next_previous_verdict = ''
            study_course.getContent().edit(mapping= {'current_level': next_level_id,
                                                     'current_session': next_session_id,
                                                     'current_verdict': next_verdict,
                                                     'previous_verdict': next_previous_verdict,
                                                     })
            if next_transition:
                wftool.doActionFor(student,next_transition)


    elif pay_doc.category == 'hostel_maintenance':

        ## callback function for accommodation_catalog method
        data={}
        data['acco_maint_date'] = pay_doc.date
        data['catkey'] =student_id + '|' + pay_doc.session_id
        data['acco_maint_fee'] = pay_doc.amount
        data['acco_maint_pay_id'] = context.getId()
        data['reservation_status'] = 'maintenance_fee_paid'
        context.accommodation_catalog.modifyRecord(**data)

        ## callback function for accommodation object method (deactivated since March 2011)
        #acco_info = context.getAccommodationInfo()
        #d = {}
        #d['acco_maint_date'] = pay_doc.date
        #d['acco_maint_fee'] = pay_doc.amount
        #d['acco_maint_pay_id'] = context.getId()
        #try:
        #    acco_info['acco_doc'].edit(mapping=d)
        #except:
        #    logger.info('%s requeried payment though maintenance already paid' % student_id)
        #try:
        #    wftool.doActionFor(acco_info['acco'],'pay_maintenance_fee',dest_container=acco_info['acco'])
        #except:
        #    logger.info('%s no workflow action pay_maintenance_fee' % student_id)

    elif pay_doc.category == 'acceptance':
        if context.getStudentReviewState() in ('admitted', 'objection_raised'):
            logger.info('%s paid acceptance fee' % (student_id))
            current = DateTime.DateTime()
            wf = context.portal_workflow
            info = context.getClearanceInfo()
            wftool.doActionFor(student,'enter_clearance_pin')
            context.waeup_tool.changeWorkflowState(info['clear'], 'opened')
            context.waeup_tool.changeWorkflowState(info['app'], 'closed')
            dc = {}
            app_doc = info['app_doc']
            #dc['clr_ac_pin'] = pay_doc.order_id
            dc['clr_ac_date'] = current
            dc['entry_date'] = current
            info['clear_doc'].edit(mapping = dc)
            if info['penalty']:
                logger.info('%s started late clearance' % (info['id']))
            #return redirect("%s/clearance_edit_form" % info['clear'].absolute_url())

    logger.info('%s received valid callback' % student_id)

else:
    logger.info('%s received unsuccessful callback: %s' % (student_id,pd['resp_desc']))

#review_state = wftool.getInfoFor(context,'review_state',None)
#if review_state == 'opened':
#    wftool.doActionFor(context,'close')
context.waeup_tool.changeWorkflowState(context, 'closed')

return request.RESPONSE.redirect("%s/waeup_document_view" % context.absolute_url())
