## $Id: browser.py 8267 2012-04-24 21:30:43Z henrik $
##
## Copyright (C) 2012 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
##
from datetime import datetime
import httplib
import urllib
from xml.dom.minidom import parseString
import grok
from waeup.kofa.browser.layout import KofaPage, UtilityView
from waeup.kofa.applicants.viewlets import RequestCallbackActionButton as RCABApplicant
from waeup.kofa.students.viewlets import RequestCallbackActionButton as RCABStudent
from waeup.uniben.interfaces import MessageFactory as _
from waeup.uniben.students.utils import actions_after_student_payment
from waeup.uniben.applicants.utils import actions_after_applicant_payment
from waeup.uniben.students.interfaces import ICustomStudentOnlinePayment
from waeup.uniben.applicants.interfaces import ICustomApplicantOnlinePayment

#TERMINAL_ID = '0500000003'
TERMINAL_ID = '0000000001'
#QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'

def query_etranzact(confirmation_number, user, payment, view):
    ob_class = view.__implemented__.__name__
    postdict = {}
    postdict['TERMINAL_ID'] = TERMINAL_ID
    #postdict['RESPONSE_URL'] = 'http://dummy'
    postdict['CONFIRMATION_NO'] = confirmation_number
    data = urllib.urlencode(postdict)
    try:
        f = urllib.urlopen(url=QUERY_URL, data=data)
        success = f.read()
        user.loggerInfo(ob_class, 'callback received: %s' % success)
        if 'COL1' not in success:
            view.flash(_('Invalid or unsuccessful callback: ${a}',
                mapping = {'a': success}))
            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
            payment.p_state = 'failed'
            return False
        success = success.replace('%20',' ').split('&')
        # We expect at least two parameters
        if len(success) < 2:
            view.flash(_('Invalid callback: ${a}',
                mapping = {'a': success}))
            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
            payment.p_state = 'failed'
            return False
        try:
            success_dict = dict([tuple(i.split('=')) for i in success])
        except ValueError:
            view.flash(_('Invalid callback: ${a}',
                mapping = {'a': success}))
            user.loggerInfo(ob_class, 'invalid callback: %s' % payment.p_id)
            payment.p_state = 'failed'
            return False
    except IOError:
        view.flash(_('eTranzact IOError'))
        return False
    payment.r_code = u'ET'
    payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
    payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
    payment.r_card_num = None
    payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
    if payment.r_amount_approved != payment.amount_auth:
        view.flash(_('Wrong amount'))
        user.loggerInfo(ob_class, 'successful callback but wrong amount: %s'
            % payment.p_id)
        payment.p_state = 'failed'
        return False
    tcode = payment.p_id
    tcode = tcode[len(tcode)-8:len(tcode)]
    col1 = success_dict.get('COL1')
    col1 = col1[len(col1)-8:len(col1)]
    if tcode != col1:
        view.flash(_('Wrong transaction code'))
        write_log_message(
            view,'successful callback but wrong transaction code: %s'
            % payment.p_id)
        user.loggerInfo(ob_class, 'successful callback wrong transaction code: %s'
            % payment.p_id)
        payment.p_state = 'failed'
        return False
    user.loggerInfo(ob_class, 'successful callback: %s' % payment.p_id)
    payment.p_state = 'paid'
    payment.payment_date = datetime.now()
    return True

class EtranzactEnterPinActionButtonApplicant(RCABApplicant):
    grok.context(ICustomApplicantOnlinePayment)
    grok.order(3)
    icon = 'actionicon_call.png'
    text = _('Query eTranzact History')
    target = 'enterpin'

class EtranzactEnterPinActionButtonStudent(RCABStudent):
    grok.context(ICustomStudentOnlinePayment)
    grok.order(3)
    icon = 'actionicon_call.png'
    text = _('Query eTranzact History')
    target = 'enterpin'

class EtranzactEnterPinPageStudent(KofaPage):
    """
    """
    grok.context(ICustomStudentOnlinePayment)
    grok.name('enterpin')
    grok.template('enterpin')
    grok.require('waeup.payStudent')

    buttonname = _('Submit to eTranzact')
    label = _('Requery eTranzact History')
    action = 'query_history'

class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
    """
    """
    grok.require('waeup.payApplicant')
    grok.context(ICustomApplicantOnlinePayment)

class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
    """ Query history of eTranzact payments
    """
    grok.context(ICustomStudentOnlinePayment)
    grok.name('query_history')
    grok.require('waeup.payStudent')

    def update(self, confirmation_number=None):
        if self.context.p_state == 'paid':
            self.flash(_('This ticket has already been paid.'))
            return
        student = self.context.getStudent()
        if query_etranzact(confirmation_number, student, self.context, self):
            actions_after_student_payment(student, self.context, self)
        return

    def render(self):
        self.redirect(self.url(self.context, '@@index'))
        return

class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
    """ Query history of eTranzact payments
    """
    grok.context(ICustomApplicantOnlinePayment)
    grok.name('query_history')
    grok.require('waeup.payApplicant')

    def update(self, confirmation_number=None):
        if self.context.p_state == 'paid':
            self.flash(_('This ticket has already been paid.'))
            return
        applicant = self.context.__parent__
        if query_etranzact(confirmation_number, applicant, self.context, self):
            actions_after_applicant_payment(applicant, self)
        return

    def render(self):
        self.redirect(self.url(self.context, '@@index'))
        return
