source: main/waeup.ikoba/branches/uli-payments/src/waeup/ikoba/payments/payment.py @ 12704

Last change on this file since 12704 was 12700, checked in by uli, 10 years ago

Add payment catalog lookup.

  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
1## $Id: payment.py 12700 2015-03-09 04:45:52Z uli $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19These are the payment tickets.
20"""
21import decimal
22import grok
23import uuid
24from datetime import datetime
25from zope.catalog.interfaces import ICatalog
26from zope.component import getUtilitiesFor, getUtility
27from zope.event import notify
28from waeup.ikoba.interfaces import MessageFactory as _
29from waeup.ikoba.utils.helpers import attrs_to_fields
30from waeup.ikoba.utils.logger import Logger
31from waeup.ikoba.payments.interfaces import (
32    IPayment, STATE_UNPAID, STATE_FAILED, STATE_PAID,
33    IPaymentGatewayService, IPayer, IPaymentItem, IPayee,
34    IPaymentGatewayServicesLister,
35    )
36
37
38def get_payment(payment_id):
39    """Get payment by payment id.
40
41    If no such payment can be found in catalog, return none.
42    """
43    cat = getUtility(ICatalog, name='payments_catalog')
44    result_set = [x for x in cat.searchResults(
45        payment_id = (payment_id, payment_id))]
46    if len(result_set):
47        return result_set[0]
48    return None
49
50
51def format_payment_item_values(payment_item_values, currency):
52    """Format tuples (description, currency, amount) for output.
53
54    `currency` passed in is the 'target' currency.
55
56    Returns a list of formated values. Last item is total sum.
57    XXX: we do not really respect currency. If different items
58         have different currencies, we are choked.
59    """
60    result = []
61    total = decimal.Decimal("0.00")
62    for descr, item_currency, amount in payment_item_values:
63        total += amount
64        if item_currency != currency:
65            raise ValueError(
66                "Different currencies in payment items not supported.")
67        result.append((descr, '%s %0.2f' % (item_currency, amount)))
68    result.append((_('Total'), '%s %0.2f' % (currency, total)))
69    return result
70
71
72def get_payment_providers():
73    """Get all payment providers registered.
74    """
75    return dict(
76        getUtilitiesFor(IPaymentGatewayService)
77    )
78
79
80class PaymentGatewayServicesLister(grok.GlobalUtility):
81    grok.implements(IPaymentGatewayServicesLister)
82
83    def __call__(self):
84        """Get all services of payment gateways registered.
85        """
86        return get_payment_providers()
87
88
89class PaymentProviderServiceBase(grok.GlobalUtility):
90
91    grok.baseclass()
92    grok.implements(IPaymentGatewayService)
93
94    title = u'Sample Credit Card Service'
95
96
97@attrs_to_fields
98class Payment(grok.Container, Logger):
99    """This is a payment.
100    """
101    grok.implements(IPayment)
102    grok.provides(IPayment)
103
104    logger_name = 'waeup.ikoba.${sitename}.payments'
105    logger_filename = 'payments.log'
106    logger_format_str = '"%(asctime)s","%(user)s",%(message)s'
107
108    @property
109    def amount(self):
110        """The amount of a payment.
111
112        Equals the sum of items contained.
113        """
114        return sum(
115            [item.amount for item in self.values()],
116            decimal.Decimal("0.00")  # default value
117        )
118
119    def __init__(self):
120        super(Payment, self).__init__()
121        self.creation_date = datetime.utcnow()
122        self.payment_date = None
123        self.payment_id = u'PAY_' + unicode(uuid.uuid4().hex)
124        self.state = STATE_UNPAID
125        return
126
127    def approve(self, payment_date=None):
128        """A payment was approved.
129
130        Successful ending; the payment is marked as payed.
131
132        If `payment_date` is given, it must be a datetime object
133        giving a datetime in UTC timezone.
134
135        Raises ObjectModifiedEvent.
136        """
137        if payment_date is None:
138            payment_date = datetime.utcnow()
139        self.payment_date = payment_date
140        self.state = STATE_PAID
141        notify(grok.ObjectModifiedEvent(self))
142
143    def mark_failed(self, reason=None):
144        """Mark payment as failed.
145
146        Raises ObjectModifiedEvent.
147        """
148        self.state = STATE_FAILED
149        notify(grok.ObjectModifiedEvent(self))
150
151    def add_payment_item(self, item):
152        """Add `item`
153
154        Returns the key under which the `item` was stored. Please do
155        not make anby assumptions about the key. It will be a
156        string. That is all we can tell.
157
158        """
159        cnt = 0
160        while str(cnt) in self:
161            cnt += 1
162        self[str(cnt)] = item
163        return str(cnt)
164
165
166@attrs_to_fields
167class Payer(object):
168    """A Payment is for testing.
169
170    It cannot be stored in ZODB.
171    """
172    grok.implements(IPayer)
173
174
175@attrs_to_fields
176class PaymentItem(grok.Model):
177
178    grok.implements(IPaymentItem)
179
180    def __init__(self):
181        super(PaymentItem, self).__init__()
182
183
184@attrs_to_fields
185class Payee(object):
186    """Someone being paid.
187
188    This is for testing only and cannot be stored in ZODB.
189    """
190    grok.implements(IPayee)
Note: See TracBrowser for help on using the repository browser.