Changeset 12671 for main/waeup.ikoba/trunk/src/waeup/ikoba/payments
- Timestamp:
- 6 Mar 2015, 23:12:36 (10 years ago)
- Location:
- main/waeup.ikoba/trunk/src/waeup/ikoba/payments
- Files:
-
- 4 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.ikoba/trunk/src/waeup/ikoba/payments/catalog.py
r12311 r12671 32 32 payment_id = grok.index.Field(attribute='payment_id') 33 33 payer_id = grok.index.Field(attribute='payer_id') 34 payed_item_id = grok.index.Field(attribute='payed_item_id')35 34 state = grok.index.Field(attribute='state') 36 35 amount = grok.index.Field(attribute='amount') -
main/waeup.ikoba/trunk/src/waeup/ikoba/payments/interfaces.py
r12319 r12671 20 20 from zope import schema 21 21 from zope.component import getUtilitiesFor 22 from zope.interface import Interface 22 from zope.container.interfaces import IContainer 23 from zope.container.constraints import contains 24 from zope.interface import Interface, Attribute 23 25 from waeup.ikoba.interfaces import ( 24 26 IIkobaObject, SimpleIkobaVocabulary, ContextualDictSourceFactoryBase) … … 86 88 ) 87 89 88 def create_payment(payer, payment_item , payee):90 def create_payment(payer, payment_item_list, payee): 89 91 """Create a payment. 90 92 … … 101 103 102 104 105 class IPaymentGatewayServicesLister(Interface): 106 """A utility that lists all valid payment gateways. 107 108 This is a subset of the available payment methods, as some might 109 be disabled in some site. 110 111 Register your own lister in customized sites! 112 """ 113 114 103 115 class PaymentCategorySource(ContextualDictSourceFactoryBase): 104 116 """A payment category source delivers all categories of payments. … … 115 127 116 128 117 class IPayment(IIkobaObject): 129 class ICreditCard(Interface): 130 """A credit card. 131 132 A credit card is connected to a Payer. 133 """ 134 credit_card_id = schema.TextLine( 135 title=u'Internal Credit Card ID', 136 required=True, 137 ) 138 139 140 class IPaymentItem(Interface): 141 """Something to sell. 142 """ 143 item_id = schema.TextLine( 144 title=u'Payment Item ID', 145 required=True, 146 ) 147 148 title = schema.TextLine( 149 title=u'Title', 150 description=u'A short title of the good sold.', 151 required=True, 152 default=u'Unnamed' 153 ) 154 155 amount = schema.Decimal( 156 title=u'Amount', 157 description=u'Total amount, includung any taxes, fees, etc.', 158 required=True, 159 default=decimal.Decimal('0.00'), 160 ) 161 162 163 class IPayment(IContainer): 118 164 """A base representation of payments. 119 165 … … 139 185 we mark the payment 'failed'. 140 186 """ 187 contains(IPaymentItem) 188 141 189 payment_id = schema.TextLine( 142 190 title=u'Payment Identifier', … … 151 199 ) 152 200 153 paye d_item_id = schema.TextLine(154 title=u'Paye d Item ID',155 default=None, 156 required= True,157 201 payee_id = schema.TextLine( 202 title=u'Payee', 203 default=None, 204 required=False, 205 ) 158 206 159 207 gateway_service = schema.Choice( … … 184 232 ) 185 233 186 amount = schema.Decimal(187 title= _(u'Amount'),188 description=_(189 'The overall sum payed, including all taxes fees, etc.'),190 default= decimal.Decimal("0.00"),191 required=True,192 readonly=False, 193 234 currency = schema.Choice( 235 title=u'Currency', 236 source=ISO_4217_CURRENCIES_VOCAB, 237 required=True, 238 default='USD', 239 ) 240 241 amount = Attribute("Sum of amounts of items contained") 194 242 195 243 def approve(): … … 208 256 """ 209 257 210 211 class IOnlinePayment(IPayment): 212 """A payment via payment gateways. 213 214 """ 215 216 ac = schema.TextLine( 217 title=_(u'Activation Code'), 218 default=None, 219 required=False, 220 readonly=False, 221 ) 222 223 r_amount_approved = schema.Float( 224 title=_(u'Response Amount Approved'), 225 default=0.0, 226 required=False, 227 readonly=False, 228 ) 229 230 r_code = schema.TextLine( 231 title=_(u'Response Code'), 232 default=None, 233 required=False, 234 readonly=False, 235 ) 236 237 r_desc = schema.TextLine( 238 title=_(u'Response Description'), 239 default=None, 240 required=False, 241 readonly=False, 242 ) 243 244 def approve(): 245 "Approve an online payment and set to paid." 246 247 248 class ICreditCard(Interface): 249 """A credit card. 250 251 A credit card is connected to a Payer. 252 """ 253 credit_card_id = schema.TextLine( 254 title=u'Internal Credit Card ID', 255 required=True, 256 ) 258 def add_payment_item(item): 259 """Payments contain payment items. 260 261 Add one 262 """ 257 263 258 264 … … 283 289 required=True 284 290 ) 285 286 287 class IPaymentItem(Interface):288 """Something to sell.289 """290 item_id = schema.TextLine(291 title=u'Payment Item ID',292 required=True,293 )294 295 title = schema.TextLine(296 title=u'Title',297 description=u'A short title of the good sold.',298 required=True,299 default=u'Unnamed'300 )301 302 amount = schema.Decimal(303 title=u'Amount',304 description=u'Total amount, includung any taxes, fees, etc.',305 required=True,306 default=decimal.Decimal('0.00'),307 )308 309 currency = schema.Choice(310 title=u'Currency',311 source=ISO_4217_CURRENCIES_VOCAB,312 required=True,313 default='USD',314 ) -
main/waeup.ikoba/trunk/src/waeup/ikoba/payments/payment.py
r12461 r12671 28 28 from waeup.ikoba.payments.interfaces import ( 29 29 IPayment, STATE_UNPAID, STATE_FAILED, STATE_PAID, 30 IPaymentGatewayService, IPayer, IPaymentItem, 30 IPaymentGatewayService, IPayer, IPaymentItem, IPayee, 31 IPaymentGatewayServicesLister, 31 32 ) 32 33 from waeup.ikoba.utils.logger import Logger … … 34 35 35 36 def get_payment_providers(): 36 """Get all services of payment gateways registered.37 """Get all payment providers registered. 37 38 """ 38 39 return dict( 39 40 getUtilitiesFor(IPaymentGatewayService) 40 ) 41 ) 42 43 44 class PaymentGatewayServicesLister(grok.GlobalUtility): 45 grok.implements(IPaymentGatewayServicesLister) 46 47 def __call__(self): 48 """Get all services of payment gateways registered. 49 """ 50 return get_payment_providers() 41 51 42 52 … … 49 59 50 60 51 class Payment(grok.Model, Logger): 61 @attrs_to_fields 62 class Payment(grok.Container, Logger): 52 63 """This is a payment. 53 64 """ … … 59 70 logger_format_str = '"%(asctime)s","%(user)s",%(message)s' 60 71 72 @property 73 def amount(self): 74 """The amount of a payment. 75 76 Equals the sum of items contained. 77 """ 78 return sum( 79 [item.amount for item in self.values()], 80 decimal.Decimal("0.00") # default value 81 ) 82 61 83 def __init__(self): 62 84 super(Payment, self).__init__() … … 64 86 self.payment_date = None 65 87 self.payment_id = u'PAY_' + unicode(uuid.uuid4().hex) 66 self.gateway_service = None67 self.amount = decimal.Decimal("0.00")68 self.payed_item_id = None69 self.payer_id = None70 88 self.state = STATE_UNPAID 71 89 return … … 95 113 notify(grok.ObjectModifiedEvent(self)) 96 114 115 def add_payment_item(self, item): 116 """Add `item` 117 118 Returns the key under which the `item` was stored. Please do 119 not make anby assumptions about the key. It will be a 120 string. That is all we can tell. 121 122 """ 123 cnt = 0 124 while str(cnt) in self: 125 cnt += 1 126 self[str(cnt)] = item 127 return str(cnt) 128 129 130 @attrs_to_fields 131 class Payer(object): 132 """A Payment is for testing. 133 134 It cannot be stored in ZODB. 135 """ 136 grok.implements(IPayer) 137 97 138 98 139 @attrs_to_fields … … 100 141 101 142 grok.implements(IPaymentItem) 143 144 def __init__(self): 145 super(PaymentItem, self).__init__() 146 147 148 @attrs_to_fields 149 class Payee(object): 150 """Someone being paid. 151 152 This is for testing only and cannot be stored in ZODB. 153 """ 154 grok.implements(IPayee) -
main/waeup.ikoba/trunk/src/waeup/ikoba/payments/tests/test_payment.py
r12461 r12671 17 17 ## 18 18 import datetime 19 import decimal 19 20 import re 20 21 import unittest 21 from zope.component import getUtilitiesFor, getSiteManager 22 from zope.component import getUtilitiesFor, getSiteManager, queryUtility 22 23 from zope.interface import implements 23 24 from zope.interface.verify import verifyClass, verifyObject 24 25 from waeup.ikoba.payments.interfaces import ( 25 26 IPayment, STATE_UNPAID, STATE_PAID, STATE_FAILED, 26 IPaymentGatewayService, IPaymentItem 27 IPaymentGatewayService, IPaymentItem, IPaymentGatewayServicesLister, 27 28 ) 28 29 from waeup.ikoba.payments.payment import ( 29 30 Payment, get_payment_providers, PaymentItem, 30 31 ) 32 from waeup.ikoba.testing import (FunctionalLayer, FunctionalTestCase) 31 33 32 34 … … 58 60 assert result.keys() == ['some_name', ] 59 61 assert result['some_name'] is fake_util 62 63 64 class FunctionalHelperTests(FunctionalTestCase): 65 66 layer = FunctionalLayer 67 68 def test_services_lister_is_registered(self): 69 # a lister of gateway services is registered on startup 70 util = queryUtility(IPaymentGatewayServicesLister) 71 assert util is not None 72 73 def test_services_are_really_listed(self): 74 # we can really get locally registered gateways when calling 75 util = queryUtility(IPaymentGatewayServicesLister) 76 assert len(util()) > 0 60 77 61 78 … … 113 130 assert p1.state == STATE_FAILED 114 131 132 def test_add_payment_item(self): 133 # we can add payment items 134 p1 = Payment() 135 item1 = PaymentItem() 136 result = p1.add_payment_item(item1) 137 assert len(p1) == 1 # do not make assumptions about result content 138 assert isinstance(result, basestring) 139 140 def test_add_payment_item_multiple(self): 141 # we can add several items 142 p1 = Payment() 143 item1 = PaymentItem() 144 item2 = PaymentItem() 145 result1 = p1.add_payment_item(item1) 146 result2 = p1.add_payment_item(item2) 147 assert len(p1) == 2 # do not make assumptions about result content 148 assert isinstance(result1, basestring) 149 assert isinstance(result2, basestring) 150 151 def test_amount(self): 152 # the amount of a payment is the sum of amounts of its items 153 p1 = Payment() 154 item1 = PaymentItem() 155 item2 = PaymentItem() 156 p1.add_payment_item(item1) 157 p1.add_payment_item(item2) 158 item1.amount = decimal.Decimal("12.25") 159 item2.amount = decimal.Decimal("0.5") 160 assert p1.amount == decimal.Decimal("12.75") 161 162 def test_amount_negative(self): 163 # we can sum up negative numbers 164 p1 = Payment() 165 item1 = PaymentItem() 166 item2 = PaymentItem() 167 p1.add_payment_item(item1) 168 p1.add_payment_item(item2) 169 item1.amount = decimal.Decimal("2.21") 170 item2.amount = decimal.Decimal("-3.23") 171 assert p1.amount == decimal.Decimal("-1.02") 172 173 def test_amount_empty(self): 174 # the amount of zero items is 0.00. 175 p1 = Payment() 176 assert p1.amount == decimal.Decimal("0.00") 177 assert isinstance(p1.amount, decimal.Decimal) 178 115 179 116 180 class PaymentItemTests(unittest.TestCase):
Note: See TracChangeset for help on using the changeset viewer.