Ignore:
Timestamp:
11 May 2012, 14:18:47 (13 years ago)
Author:
Henrik Bettermann
Message:

Add methods for approving payments and implement pages for approving payments (work in progress).

Location:
main/waeup.kofa/trunk/src/waeup/kofa
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/browser.py

    r8404 r8420  
    591591            'b':self.context.p_id})
    592592
    593 class OnlinePaymentCallbackPage(UtilityView, grok.View):
    594     """ Callback view
     593class OnlinePaymentApprovePage(UtilityView, grok.View):
     594    """ Approval view
    595595    """
    596596    grok.context(IApplicantOnlinePayment)
    597     grok.name('simulate_callback')
    598     grok.require('waeup.payApplicant')
    599 
    600     # This update method simulates a valid callback und must be
    601     # neutralized in the customization package.
     597    grok.name('approve')
     598    grok.require('waeup.managePortal')
     599
    602600    def update(self):
    603601        self.wf_info = IWorkflowInfo(self.context.__parent__)
     
    607605            self.flash('Error: %s' % sys.exc_info()[1])
    608606            return
    609         self.context.r_amount_approved = self.context.amount_auth
    610         self.context.r_code = u'00'
    611         self.context.p_state = 'paid'
    612         self.context.payment_date = datetime.utcnow()
     607        self.context.approve()
    613608        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
    614609        self.context.__parent__.loggerInfo(
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py

    r8406 r8420  
    696696        #self.assertMatches('...Ticket not yet paid...',
    697697        #                   self.browser.contents)
    698         # Request callback
    699         self.browser.getLink("Request callback").click()
    700         self.assertMatches('...Valid callback received...',
    701                           self.browser.contents)
    702         # Callback can't be applied twice
    703         self.browser.open(payment_url + '/simulate_callback')
    704         self.assertMatches(
    705             "...Transition 'pay' requires 'started' as source state...",
    706             self.browser.contents)
     698        # Approve payment
     699        # Applicants can't approve payments
     700        self.assertRaises(
     701            Unauthorized, self.browser.open, payment_url + '/approve')
     702        # We approve the payment by bypassing the view
     703        payment_id = self.applicant.keys()[0]
     704        payment = self.applicant[payment_id]
     705        payment.approve()
    707706        # The payment slip can be downloaded now
    708707        self.browser.open(payment_url)
     
    711710        self.assertEqual(self.browser.headers['Content-Type'],
    712711                         'application/pdf')
    713         # Applicant is is in state 'paid'
     712        # Applicant is is not yet in state 'paid' because it was only
     713        # the payment which we set to paid
    714714        self.browser.open(self.view_path)
    715         self.assertMatches('...paid...',
     715        self.assertMatches('...started...',
    716716                           self.browser.contents)
    717717        state = IWorkflowState(self.applicant).getState()
     718        self.assertTrue(state == 'started')
     719        # Let's logout and approve the payment as manager
     720        self.browser.getLink("Logout").click()
     721        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
     722        # First we reset the payment
     723        payment.r_amount_approved = 0.0
     724        payment.r_code = u''
     725        payment.p_state = 'unpaid'
     726        payment.r_desc = u''
     727        payment.payment_date = None
     728        self.browser.open(payment_url)
     729        self.browser.getLink("Approve payment").click()
     730        self.assertEqual(payment.p_state, 'paid')
     731        self.assertEqual(payment.r_amount_approved, 200.0)
     732        self.assertEqual(payment.r_code, 'AP')
     733        state = IWorkflowState(self.applicant).getState()
    718734        self.assertTrue(state == 'paid')
     735        return
    719736
    720737    def test_final_submit(self):
  • main/waeup.kofa/trunk/src/waeup/kofa/applicants/viewlets.py

    r8406 r8420  
    185185        return self.view.url(self.view.context, self.target)
    186186
    187 class RequestCallbackActionButton(ManageActionButton):
     187class ApprovePaymentActionButton(ManageActionButton):
    188188    grok.order(2)
    189189    grok.context(IApplicantOnlinePayment)
    190190    grok.view(OnlinePaymentDisplayFormPage)
    191     grok.require('waeup.payApplicant')
     191    grok.require('waeup.managePortal')
    192192    icon = 'actionicon_call.png'
    193     text = _('Request callback')
    194     target = 'simulate_callback'
    195 
    196     # This button must be neutralized
    197     # in the customization package.
     193    text = _('Approve payment')
     194    target = 'approve'
     195
    198196    @property
    199197    def target_url(self):
  • main/waeup.kofa/trunk/src/waeup/kofa/payments/interfaces.py

    r8260 r8420  
    130130        readonly = False,
    131131        )
     132
     133    def approve():
     134        "Approve an online payment and set to paid."
  • main/waeup.kofa/trunk/src/waeup/kofa/payments/payment.py

    r8194 r8420  
    2424from zope.component import getUtility
    2525from waeup.kofa.interfaces import IKofaUtils
     26from waeup.kofa.interfaces import MessageFactory as _
    2627from waeup.kofa.payments.interfaces import (
    2728    IPayment, ISCPayment, IOnlinePayment,
    2829    payment_states, payment_categories)
    29 from waeup.kofa.utils.helpers import attrs_to_fields
     30from waeup.kofa.utils.helpers import attrs_to_fields, get_current_principal
    3031
    3132class Payment(grok.Container):
     
    5051        return payment_categories.getTermByToken(self.p_category).title
    5152
     53# not used
    5254class SCPayment(Payment):
    5355    """This is a scratch card payment.
     
    7476        return
    7577
     78    def approve(self):
     79        "Approve online payment and set to paid."
     80        self.r_amount_approved = self.amount_auth
     81        self.r_code = u'AP'
     82        self.p_state = 'paid'
     83        #user = get_current_principal()
     84        self.payment_date = datetime.utcnow()
     85        return
     86
    7687OnlinePayment = attrs_to_fields(OnlinePayment)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r8404 r8420  
    3232from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
    3333from waeup.kofa.accesscodes import (
    34     invalidate_accesscode, get_access_code, create_accesscode)
     34    invalidate_accesscode, get_access_code)
    3535from waeup.kofa.accesscodes.workflow import USED
    3636from waeup.kofa.browser import (
     
    11301130            'b':self.context.p_id})
    11311131
    1132 class OnlinePaymentCallbackPage(UtilityView, grok.View):
     1132class OnlinePaymentApprovePage(UtilityView, grok.View):
    11331133    """ Callback view
    11341134    """
    11351135    grok.context(IStudentOnlinePayment)
    1136     grok.name('simulate_callback')
    1137     grok.require('waeup.payStudent')
    1138 
    1139     # This update method simulates a valid callback und must be
    1140     # neutralized in the customization package.
     1136    grok.name('approve')
     1137    grok.require('waeup.managePortal')
     1138
    11411139    def update(self):
    1142         if self.context.p_state == 'paid':
    1143             self.flash(_('This ticket has already been paid.'))
    1144             return
    1145         student = self.context.getStudent()
    1146         write_log_message(self,'valid callback: %s' % self.context.p_id)
    1147         self.context.r_amount_approved = self.context.amount_auth
    1148         self.context.r_code = u'00'
    1149         self.context.p_state = 'paid'
    1150         self.context.payment_date = datetime.utcnow()
    1151         if self.context.p_category == 'clearance':
    1152             # Create CLR access code
    1153             pin, error = create_accesscode(
    1154                 'CLR',0,self.context.amount_auth,student.student_id)
    1155             if error:
    1156                 self.flash(_('Valid callback received. ${a}',
    1157                     mapping = {'a':error}))
    1158                 return
    1159             self.context.ac = pin
    1160         elif self.context.p_category == 'schoolfee':
    1161             # Create SFE access code
    1162             pin, error = create_accesscode(
    1163                 'SFE',0,self.context.amount_auth,student.student_id)
    1164             if error:
    1165                 self.flash(_('Valid callback received. ${a}',
    1166                     mapping = {'a':error}))
    1167                 return
    1168             self.context.ac = pin
    1169         elif self.context.p_category == 'bed_allocation':
    1170             # Create HOS access code
    1171             pin, error = create_accesscode(
    1172                 'HOS',0,self.context.amount_auth,student.student_id)
    1173             if error:
    1174                 self.flash(_('Valid callback received. ${a}',
    1175                     mapping = {'a':error}))
    1176                 return
    1177             self.context.ac = pin
    1178         self.flash(_('Valid callback received.'))
     1140        success, msg = self.context.approveStudentPayment()
     1141        if success:
     1142            write_log_message(self,'valid callback: %s' % self.context.p_id)
     1143        self.flash(msg)
    11791144        return
    11801145
     
    11821147        self.redirect(self.url(self.context, '@@index'))
    11831148        return
     1149
     1150class OnlinePaymentFakeApprovePage(OnlinePaymentApprovePage):
     1151    """ Approval view for students.
     1152
     1153    This view is used for browser tests only and
     1154    must be neutralized in custom pages!
     1155    """
     1156
     1157    grok.name('fake_approve')
     1158    grok.require('waeup.payStudent')
    11841159
    11851160class ExportPDFPaymentSlipPage(UtilityView, grok.View):
  • main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py

    r8409 r8420  
    510510        )
    511511
     512    def approveStudentPayment():
     513        """Approve payment and create respective activation codes.
     514
     515        """
     516
    512517IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
    513518    'p_session'].order
  • main/waeup.kofa/trunk/src/waeup/kofa/students/payments.py

    r8368 r8420  
    2222from zope.component.interfaces import IFactory
    2323from zope.interface import implementedBy
     24from waeup.kofa.interfaces import MessageFactory as _
    2425from waeup.kofa.students.interfaces import (
    2526    IStudentPaymentsContainer, IStudentNavigation, IStudentOnlinePayment)
    2627from waeup.kofa.payments import PaymentsContainer, OnlinePayment
    2728from waeup.kofa.utils.helpers import attrs_to_fields
     29from waeup.kofa.accesscodes import create_accesscode
    2830
    2931class StudentPaymentsContainer(PaymentsContainer):
     
    5860            return None
    5961
     62    def approveStudentPayment(self):
     63        """Approve payment and create respective activation code.
     64        """
     65        if self.p_state == 'paid':
     66            return False, _('This ticket has already been paid.')
     67        student = self.getStudent()
     68        self.approve()
     69        if self.p_category == 'clearance':
     70            # Create CLR access code
     71            pin, error = create_accesscode(
     72                'CLR',0,self.amount_auth,student.student_id)
     73            if error:
     74                return False, _('Valid callback received. ${a}',
     75                    mapping = {'a':error})
     76            self.ac = pin
     77        elif self.p_category == 'schoolfee':
     78            # Create SFE access code
     79            pin, error = create_accesscode(
     80                'SFE',0,self.amount_auth,student.student_id)
     81            if error:
     82                return False, _('Valid callback received. ${a}',
     83                    mapping = {'a':error})
     84            self.ac = pin
     85        elif self.p_category == 'bed_allocation':
     86            # Create HOS access code
     87            pin, error = create_accesscode(
     88                'HOS',0,self.amount_auth,student.student_id)
     89            if error:
     90                return False, _('Valid callback received. ${a}',
     91                    mapping = {'a':error})
     92            self.ac = pin
     93        return True, _('Valid callback received.')
     94
    6095StudentOnlinePayment = attrs_to_fields(StudentOnlinePayment)
    6196
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r8346 r8420  
    176176        configuration.academic_session = 2004
    177177        configuration.clearance_fee = 3456.0
     178        configuration.booking_fee = 123.4
    178179        self.app['configuration'].addSessionConfiguration(configuration)
    179180
     
    12881289                           self.browser.contents)
    12891290
    1290         # Managers can open the callback view which simulates a valid callback
     1291        # Managers can approve the payment
    12911292        self.assertEqual(len(self.app['accesscodes']['SFE-0']),0)
    12921293        self.browser.open(payment_url)
    1293         self.browser.getLink("Request callback").click()
     1294        self.browser.getLink("Approve payment").click()
    12941295        self.assertMatches('...Valid callback received...',
    12951296                          self.browser.contents)
     
    12991300            self.app['accesscodes']['SFE-0'].values()[0].cost,40000.0)
    13001301
    1301         # Callback can't be applied twice
    1302         self.browser.open(payment_url + '/simulate_callback')
     1302        # Payments can't be approved twice
     1303        self.browser.open(payment_url + '/approve')
    13031304        self.assertMatches('...This ticket has already been paid...',
    13041305                          self.browser.contents)
     
    13371338                           self.browser.contents)
    13381339
    1339         # Managers can open the callback view which simulates a valid callback
     1340        # Managers can approve the payment
    13401341        self.assertEqual(len(self.app['accesscodes']['CLR-0']),0)
    13411342        ctrl = self.browser.getControl(name='val_id')
    13421343        value = ctrl.options[1] # The clearance payment is the second in the table
    13431344        self.browser.getLink(value).click()
    1344         self.browser.open(self.browser.url + '/simulate_callback')
     1345        self.browser.open(self.browser.url + '/approve')
    13451346        self.assertMatches('...Valid callback received...',
    13461347                          self.browser.contents)
     
    13721373                           self.browser.contents)
    13731374
    1374         # Students can open the callback view which simulates a valid callback
     1375        # Students can't approve the payment
    13751376        self.assertEqual(len(self.app['accesscodes']['CLR-0']),0)
    13761377        ctrl = self.browser.getControl(name='val_id')
     
    13781379        self.browser.getLink(value).click()
    13791380        payment_url = self.browser.url
    1380         self.browser.open(payment_url + '/simulate_callback')
     1381        self.assertRaises(
     1382            Unauthorized, self.browser.open, payment_url + '/approve')
     1383        # In the base package they can 'use' a fake approval view
     1384        self.browser.open(payment_url + '/fake_approve')
    13811385        self.assertMatches('...Valid callback received...',
    13821386                          self.browser.contents)
     
    13851389          <span>Paid</span>
    13861390        </td>...'''
     1391        expected = '''...
     1392        <td>
     1393          <span>Paid</span>
     1394        </td>...'''
    13871395        self.assertMatches(expected,self.browser.contents)
     1396        payment_id = self.student['payments'].keys()[0]
     1397        payment = self.student['payments'][payment_id]
     1398        self.assertEqual(payment.p_state, 'paid')
     1399        self.assertEqual(payment.r_amount_approved, 3456.0)
     1400        self.assertEqual(payment.r_code, 'AP')
    13881401        # The new CLR-0 pin has been created
    13891402        self.assertEqual(len(self.app['accesscodes']['CLR-0']),1)
     
    14411454        self.assertEqual(self.student['payments'][value].p_level, 200)
    14421455
    1443         # Students can open the callback view which simulates a valid callback
     1456        # We simulate the approval
    14441457        self.assertEqual(len(self.app['accesscodes']['SFE-0']),0)
    1445         self.browser.open(self.browser.url + '/simulate_callback')
     1458        self.browser.open(self.browser.url + '/fake_approve')
    14461459        self.assertMatches('...Valid callback received...',
    14471460                          self.browser.contents)
     
    14531466            LookupError, self.browser.getControl, name='val_id')
    14541467        self.browser.open(self.payments_path + '/addop')
    1455         self.browser.getControl(name="form.p_category").value = ['gown']
     1468        self.browser.getControl(name="form.p_category").value = ['bed_allocation']
    14561469        self.browser.getControl("Create ticket").click()
    14571470        self.browser.open(self.payments_path)
     
    14951508        value = ctrl.options[0]
    14961509        self.browser.getLink(value).click()
    1497         self.browser.open(self.browser.url + '/simulate_callback')
     1510        self.browser.open(self.browser.url + '/approve')
    14981511        # The new HOS-0 pin has been created
    14991512        self.assertEqual(len(self.app['accesscodes']['HOS-0']),1)
     
    16081621        return
    16091622
    1610     def test_student_accommodation(self):
     1623    def xx_test_student_accommodation(self):
    16111624        # Login
    16121625        self.browser.open(self.login_path)
     
    16241637        value = ctrl.options[0]
    16251638        self.browser.getLink(value).click()
    1626         self.browser.open(self.browser.url + '/simulate_callback')
     1639        self.browser.open(self.browser.url + '/fake_approve')
    16271640        # The new HOS-0 pin has been created
    16281641        self.assertEqual(len(self.app['accesscodes']['HOS-0']),1)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py

    r8410 r8420  
    266266            academic_session = grok.getSite()['configuration'][session]
    267267        except KeyError:
    268             details['error'] = u'Session configuration object is not available.'
     268            details['error'] = _(u'Session configuration object is not available.')
    269269            return details
    270270        if category == 'schoolfee':
     
    284284            details['p_item'] = self.getAccommodationDetails(student)['bt']
    285285            details['amount'] = academic_session.booking_fee
     286        if details['amount'] in (0.0, None):
     287            details['error'] = _(u'Amount could not be determined.')
    286288        return details
    287289
  • main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py

    r8323 r8420  
    328328        return self.view.url(self.view.context, self.target)
    329329
    330 class RequestCallbackActionButton(ManageActionButton):
     330
     331class ApprovePaymentActionButton(ManageActionButton):
    331332    grok.order(2)
    332333    grok.context(IStudentOnlinePayment)
    333334    grok.view(OnlinePaymentDisplayFormPage)
    334     grok.require('waeup.payStudent')
     335    grok.require('waeup.managePortal')
    335336    icon = 'actionicon_call.png'
    336     text = _('Request callback')
    337     target = 'simulate_callback'
    338 
    339     # This button must be neutralized
    340     # in the customization package.
     337    text = _('Approve payment')
     338    target = 'approve'
     339
    341340    @property
    342341    def target_url(self):
Note: See TracChangeset for help on using the changeset viewer.