Ignore:
Timestamp:
5 Mar 2015, 07:28:31 (10 years ago)
Author:
Henrik Bettermann
Message:

Extend contract workflow to integrate payment.

Prepare (empty) page to select payment method and finally create a payment object.

Location:
main/waeup.ikoba/trunk/src/waeup/ikoba
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/browser.py

    r12634 r12663  
    6060    )
    6161from waeup.ikoba.customers.catalog import search
     62from waeup.ikoba.customers.workflow import PAYMENT_TRANSITIONS
    6263
    6364grok.context(IIkobaObject)
     
    14461447    grok.require('waeup.handleCustomer')
    14471448
     1449    def submission_allowed(self, action=None):
     1450        if self.context.state == CREATED and not self.context.fee_based:
     1451            return True
     1452        return False
     1453
     1454    def payment_expected(self, action=None):
     1455        if self.context.state == CREATED and self.context.fee_based:
     1456            return True
     1457        return False
     1458
    14481459    @property
    14491460    def form_fields(self):
     
    14561467        return
    14571468
    1458     @action(_('Apply now (final submit)'), warning=WARNING_CON)
    1459     def finalsubmit(self, **data):
     1469    @action(_('Apply now (final submission)'), warning=WARNING_CON,
     1470            condition=submission_allowed, style='primary')
     1471    def submit(self, **data):
    14601472        if self.terms_and_conditions and not self.request.form.get(
    14611473            'confirm_tc', False):
     
    14661478        msave(self, **data)
    14671479        IWorkflowInfo(self.context).fireTransition('submit')
    1468         self.flash(_('Form has been submitted.'))
     1480        self.flash(_('Application form has been submitted.'))
    14691481        self.redirect(self.url(self.context))
    14701482        return
    14711483
     1484    @action(_('Proceed to checkout'),
     1485            condition=payment_expected, style='primary')
     1486    def proceed_checkout(self, **data):
     1487        if self.terms_and_conditions and not self.request.form.get(
     1488            'confirm_tc', False):
     1489            self.flash(_('Please read the terms and conditions and '
     1490                     'confirm your acceptance of these by ticking '
     1491                     'the confirmation box.'), type="danger")
     1492            return
     1493        msave(self, **data)
     1494        self.redirect(self.url(self.context, 'select_payment_method'))
     1495        return
     1496
     1497
     1498class SelectPaymentMethodPage(IkobaEditFormPage):
     1499    """ Page to to select payment method
     1500    """
     1501    grok.context(IContract)
     1502    grok.name('select_payment_method')
     1503    grok.require('waeup.handleCustomer')
     1504    grok.template('selectpaymentmethodpage')
     1505    pnav = 4
     1506    label = _('Select payment method')
     1507
     1508    def update(self, CANCEL=None):
     1509        if self.context.state != CREATED or not self.context.fee_based:
     1510            emit_lock_message(self)
     1511            return
     1512        super(SelectPaymentMethodPage, self).update()
     1513        return
     1514
     1515    @action(_('Select payment method and proceed to payment gateway (final submission)'),
     1516            style='primary', warning=WARNING_CON,)
     1517    def confirm(self, **data):
     1518        IWorkflowInfo(self.context).fireTransition('await')
     1519        self.flash(_('Payment has been initiated.'))
     1520        return
    14721521
    14731522class ContractTriggerTransitionFormPage(IkobaEditFormPage):
     
    14931542        wf_info = IWorkflowInfo(self.context)
    14941543        allowed_transitions = [t for t in wf_info.getManualTransitions()]
     1544        # Skip payment transitions if total amount is zero
     1545        if not self.context.fee_based:
     1546            allowed_transitions = [t for t in allowed_transitions
     1547                                   if not t[0] in PAYMENT_TRANSITIONS]
    14951548        return [dict(name='', title=_('No transition'))] +[
    14961549            dict(name=x, title=y) for x, y in allowed_transitions]
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/contracts.py

    r12633 r12663  
    161161            return
    162162
     163    @property
     164    def fee_based(self):
     165        if self.product_options:
     166            amount = 0
     167            for option in self.product_options:
     168                amount += option.fee
     169            if amount:
     170                return True
     171        return False
     172
    163173
    164174class SampleContract(ContractBase):
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/interfaces.py

    r12633 r12663  
    303303    valid_from = Attribute('Contract valid from')
    304304    valid_to = Attribute('Contract valid to')
     305    fee_based = Attribute('Fee based contract')
    305306
    306307    contract_id = schema.TextLine(
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/reports/contract_statistics.py

    r12660 r12663  
    2222from zope.interface import implementer, Interface, Attribute
    2323from waeup.ikoba.interfaces import (
    24     IIkobaUtils, CREATED, APPROVED, SUBMITTED, EXPIRED, REJECTED)
     24    IIkobaUtils,
     25    CREATED, APPROVED,
     26    SUBMITTED, EXPIRED,
     27    REJECTED, AWAITING)
    2528from waeup.ikoba.customers.interfaces import ICustomersUtils
    2629from waeup.ikoba.interfaces import MessageFactory as _
     
    5457    types = TYPES.keys()
    5558    type_names = tuple(TYPES.values()) + (u'All',)
    56     states = (CREATED, SUBMITTED, APPROVED, EXPIRED, REJECTED)
     59    states = (CREATED, AWAITING, SUBMITTED, APPROVED, EXPIRED, REJECTED)
    5760    STATES = getUtility(ICustomersUtils).TRANSLATED_CONTRACT_STATES
    5861    state_names = tuple([STATES[state] for state in states]) + (u'Total',)
     
    108111    ('LINEAFTER', (-1,0), (-1,-1), 0.25, colors.black),
    109112    ('LINEBEFORE', (-1,0), (-1,-1), 1.0, colors.black),
    110     #('LINEABOVE', (0,-1), (-1,-1), 1.0, colors.black),
     113    ('LINEABOVE', (0,-1), (-1,-1), 1.0, colors.black),
    111114    #('LINEABOVE', (0,0), (-1,0), 0.25, colors.black),
    112115    ]
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/reports/tests/test_contract_statistics.py

    r12659 r12663  
    1717    layer = FunctionalLayer
    1818
    19     states = ('created', 'submitted for approval',  'approved', 'expired',
     19    states = ('created', 'awaiting payment',
     20              'submitted for approval',
     21              'approved', 'expired',
    2022              'rejected', 'Total')
    2123
     
    3436            ((u'Sample Contract', u'All'),
    3537             self.states,
    36              ((1, 0, 0, 0, 0, 1),
    37               (1, 0, 0, 0, 0, 1),))
     38             ((1, 0, 0, 0, 0, 0, 1),
     39              (1, 0, 0, 0, 0, 0, 1),))
    3840            )
    3941        return
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py

    r12634 r12663  
    14171417        # The form is also saved.
    14181418        self.browser.getLink("Edit").click()
    1419         self.browser.getControl("Apply").click()
     1419        self.browser.getControl("Proceed to checkout").click()
    14201420        self.assertTrue('confirm your acceptance of these by ticking' in self.browser.contents)
    14211421        self.assertEqual(contract.state, 'created')
    14221422        self.browser.getControl(name="confirm_tc").value = True
    1423         self.browser.getControl("Apply").click()
    1424         self.assertEqual(contract.state, 'submitted')
    1425         self.assertTrue('Contract State: submitted for approval' in self.browser.contents)
     1423        self.browser.getControl("Proceed to checkout").click()
     1424        self.assertEqual(contract.state, 'created')
     1425        self.browser.getControl("Select payment method").click()
     1426        self.assertEqual(contract.state, 'awaiting')
    14261427        # Customer can't edit the contract once it has been submitted
    14271428        self.browser.open(self.contracts_path + '/%s/edit' % conid)
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_export.py

    r12633 r12663  
    256256            result,
    257257            'class_name,comment,contract_category,contract_id,document_object,'
    258             'history,last_product_id,'
    259             'product_object,product_options,state,tc_dict,title,user_id,'
    260             'valid_from,valid_to\r\n'
    261 
    262             'SampleContract,,sample,CON1,,[],,,[],,{},,,,\r\n'
     258            'fee_based,history,last_product_id,'
     259            'product_object,product_options,state,tc_dict,title,'
     260            'user_id,valid_from,valid_to\r\n'
     261
     262            'SampleContract,,sample,CON1,,0,[],,,[],,{},,,,\r\n'
    263263            )
    264264        return
     
    273273        self.assertMatches(
    274274            'class_name,comment,contract_category,contract_id,document_object,'
    275             'history,last_product_id,'
    276             'product_object,product_options,state,tc_dict,title,user_id,'
    277             'valid_from,valid_to\r\n'
    278 
    279             'SampleContract,,sample,CON1,DOC1,[u\'2014-12-04 12:10:46 UTC - '
     275            'fee_based,history,last_product_id,'
     276            'product_object,product_options,state,tc_dict,title,'
     277            'user_id,valid_from,valid_to\r\n'
     278
     279            'SampleContract,,sample,CON1,DOC1,1,[u\'2014-12-04 12:10:46 UTC - '
    280280            'Contract created by system\'],,'
    281281            'SAM,"[(u\'Base Fee\', u\'800.6\', u\'USD\')]",'
     
    295295        self.assertMatches(
    296296            'class_name,comment,contract_category,contract_id,document_object,'
    297             'history,last_product_id,'
    298             'product_object,product_options,state,tc_dict,title,user_id,'
    299             'valid_from,valid_to\r\n'
    300 
    301             'SampleContract,,sample,CON1,DOC1,[u\'2014-12-04 12:10:46 UTC - '
     297            'fee_based,history,last_product_id,'
     298            'product_object,product_options,state,tc_dict,title,'
     299            'user_id,valid_from,valid_to\r\n'
     300
     301            'SampleContract,,sample,CON1,DOC1,1,[u\'2014-12-04 12:10:46 UTC - '
    302302            'Contract created by system\'],,'
    303303            'SAM,"[(u\'Base Fee\', u\'800.6\', u\'USD\')]",'
     
    317317        self.assertMatches(
    318318            'class_name,comment,contract_category,contract_id,document_object,'
    319             'history,last_product_id,'
    320             'product_object,product_options,state,tc_dict,title,user_id,'
    321             'valid_from,valid_to\r\n'
    322 
    323             'SampleContract,,sample,CON1,DOC1,[u\'2014-12-04 12:10:46 UTC - '
     319            'fee_based,history,last_product_id,'
     320            'product_object,product_options,state,tc_dict,title,'
     321            'user_id,valid_from,valid_to\r\n'
     322
     323            'SampleContract,,sample,CON1,DOC1,1,[u\'2014-12-04 12:10:46 UTC - '
    324324            'Contract created by system\'],,'
    325325            'SAM,"[(u\'Base Fee\', u\'800.6\', u\'USD\')]",'
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/utils.py

    r12634 r12663  
    3838from waeup.ikoba.interfaces import (
    3939    STARTED, CREATED, REQUESTED, APPROVED, SUBMITTED, VERIFIED, REJECTED,
    40     EXPIRED, PROVISIONALLY,
     40    EXPIRED, PROVISIONALLY, AWAITING,
    4141    IIkobaUtils, IExtFileStore)
    4242from waeup.ikoba.customers.interfaces import ICustomersUtils
     
    308308    TRANSLATED_CONTRACT_STATES = {
    309309        CREATED: _('created'),
     310        AWAITING: _('awaiting payment'),
    310311        SUBMITTED: _('submitted for approval'),
    311312        APPROVED: _('approved'),
  • main/waeup.ikoba/trunk/src/waeup/ikoba/customers/workflow.py

    r12553 r12663  
    2828    IObjectHistory, IIkobaWorkflowInfo, IIkobaUtils, IUserAccount,
    2929    STARTED, CREATED, REQUESTED, PROVISIONALLY, APPROVED,
    30     SUBMITTED, VERIFIED, REJECTED, EXPIRED)
     30    SUBMITTED, VERIFIED, REJECTED, EXPIRED, AWAITING)
    3131from waeup.ikoba.interfaces import MessageFactory as _
    3232from waeup.ikoba.workflow import (
     
    191191
    192192    Transition(
     193        transition_id = 'await',
     194        title = _('Initiate payment'),
     195        source = CREATED,
     196        condition = NullCondition,
     197        msg = _('Payment initiated'),
     198        destination = AWAITING),
     199
     200    Transition(
     201        transition_id = 'discard',
     202        title = _('Discard payment'),
     203        source = AWAITING,
     204        condition = NullCondition,
     205        msg = _('Payment discarded'),
     206        destination = CREATED),
     207
     208    Transition(
    193209        transition_id = 'submit',
    194210        title = _('Submit for approval'),
     
    198214
    199215    Transition(
     216        transition_id = 'confirm',
     217        title = _('Confirm payment'),
     218        msg = _('Payment and submission confirmed'),
     219        source = AWAITING,
     220        destination = SUBMITTED),
     221
     222    Transition(
    200223        transition_id = 'approve',
    201224        title = _('Approve'),
     
    245268        source = EXPIRED,
    246269        destination = CREATED),
     270
    247271    )
     272
     273PAYMENT_TRANSITIONS = ['await', 'discard', 'confirm']
    248274
    249275contract_workflow = IkobaWorkflow(CONTRACT_TRANSITIONS)
     
    286312    history = IObjectHistory(obj)
    287313    history.addMessage(msg)
    288     if event.transition.transition_id not in ('create', 'submit') \
    289         and obj.customer:
     314    if event.transition.transition_id not in (
     315        'create', 'submit', 'confirm', 'await') and obj.customer:
    290316        ikoba_utils = getUtility(IIkobaUtils)
    291317        ikoba_utils.sendTransitionInfo(IUserAccount(obj.customer), obj, msg)
  • main/waeup.ikoba/trunk/src/waeup/ikoba/interfaces.py

    r12607 r12663  
    5555
    5656SUBMITTED = 'submitted'
    57 VERIFIED = 'verified'
     57AWAITING = 'awaiting'
    5858REJECTED = 'rejected'
    5959EXPIRED = 'expired'
     60
     61VERIFIED = 'verified'
    6062PUBLISHED = 'published'
    6163
Note: See TracChangeset for help on using the changeset viewer.