Projet

Général

Profil

« Précédent | Suivant » 

Révision c6ba8333

Ajouté par Thomas Noël il y a environ 12 ans

add workflow item "cancel payment" (fix #1255)

+ add_part(invoice) in formdata.evolution

Voir les différences:

extra/modules/myspace.ptl
35 35
        return Directory._q_traverse(self, path)
36 36

  
37 37
    def _q_index [html] (self):
38
        user = get_request().user
39
        if not user or user.anonymous:
40
            raise errors.AccessUnauthorizedError()
41

  
38 42
        template.html_top(_('Invoices'))
39 43
        TextsDirectory.get_html_text('aq-myspace-invoice')
40 44

  
41 45
        get_session().display_message()
42 46

  
43
        invoices = Invoice.get_with_indexed_value(
44
                        str('user_id'), str(get_request().user.id))
47
        invoices = []
48
        invoices.extend(Invoice.get_with_indexed_value(
49
            str('user_id'), str(user.id)))
50
        try:
51
            invoices.extend(Invoice.get_with_indexed_value(
52
                str('user_hash'), str(user.hash)))
53
        except AttributeError:
54
            pass
45 55

  
46 56
        def cmp_invoice(a, b):
47 57
            t = cmp(a.regie_id, b.regie_id)
......
67 77
                '<ul>'
68 78

  
69 79
            '<li>'
70
            if not invoice.paid:
80
            if not (invoice.paid or invoice.canceled):
71 81
                '<input type="checkbox" name="invoice" value="%s"/>' % invoice.id
72 82
                unpaid = True
73 83
            misc.localstrftime(invoice.date)
......
77 87
            '%s' % invoice.amount
78 88
            ' &euro;'
79 89
            ' - '
80
            button = '<strong>%s</strong>' % _('Pay')
90
            button = '<span class="paybutton">%s</span>' % _('Pay')
91
            if invoice.canceled:
92
                _('canceled on %s') % misc.localstrftime(invoice.canceled_date)
93
                ' - '
94
                button = _('Details')
81 95
            if invoice.paid:
82 96
                _('paid on %s') % misc.localstrftime(invoice.paid_date)
83 97
                ' - '
extra/modules/payments.py
6 6

  
7 7
from decimal import Decimal
8 8

  
9
from quixote import redirect, get_request, get_session
9
from quixote import redirect, get_publisher, get_request, get_session
10 10
from quixote.directory import Directory
11 11

  
12 12
if not set:
......
47 47

  
48 48
class Invoice(StorableObject):
49 49
    _names = 'invoices'
50
    _hashed_indexes = ['user_id', 'regie_id']
50
    _hashed_indexes = ['user_id', 'user_hash', 'regie_id']
51 51

  
52 52
    user_id = None
53
    user_hash = None
53 54
    regie_id = None
54 55
    formdef_id = None
55 56
    formdata_id = None
......
59 60
    date = None
60 61
    paid = False
61 62
    paid_date = None
63
    canceled = False
64
    canceled_date = None
65
    canceled_reason = None
62 66
    next_status = None
63 67

  
64 68
    def __init__(self, id=None, regie_id=None, formdef_id=None):
......
90 94
            return False
91 95
    check_crc = classmethod(check_crc)
92 96

  
97
    def cancel(self, reason=None):
98
        self.canceled = True
99
        self.canceled_date = dt.now()
100
        if reason:
101
            self.canceled_reason = reason
102
        self.store()
103

  
104

  
105
INVOICE_EVO_VIEW = {
106
    'create': N_('Create Invoice <a href="%(url)s">%(id)s</a>: %(subject)s - %(amount)s &euro;'),
107
    'pay': N_('Invoice <a href="%(url)s">%(id)s</a> is paid'),
108
    'cancel': N_('Cancel Invoice <a href="%(url)s">%(id)s</a>'),
109
}
110

  
111
class InvoiceEvolutionPart:
112
    action = None
113
    id = None
114
    subject = None
115
    amount = None
116

  
117
    def __init__(self, action, invoice):
118
        self.action = action
119
        self.id = invoice.id
120
        self.subject = invoice.subject
121
        self.amount = invoice.amount
122

  
123
    def view(self):
124
        vars = {
125
            'url': '%s/invoices/%s' % (get_publisher().get_frontoffice_url(), self.id),
126
            'id': self.id,
127
            'subject': self.subject,
128
            'amount': self.amount,
129
        }
130
        return htmltext('<p class="invoice-%s">' % self.action + \
131
                _(INVOICE_EVO_VIEW[self.action]) % vars + '</p>')
132

  
93 133

  
94 134
class Transaction(StorableObject):
95 135
    _names = 'transactions'
......
168 208

  
169 209
    def perform(self, formdata):
170 210
        invoice = Invoice(regie_id=self.regie_id, formdef_id=formdata.formdef.id)
171
        invoice.user_id = get_request().user.id  # FIXME: handle user_hash
211
        invoice.user_id = formdata.user_id
212
        invoice.user_hash = formdata.user_hash
172 213
        invoice.formdata_id = formdata.id
173 214
        invoice.next_status = self.next_status
174 215
        if self.subject:
......
181 222
        invoice.amount = self.calculate_amount(formdata)
182 223
        invoice.date = dt.now()
183 224
        invoice.store()
184
        # FIXME: add a message in formdata.evolution
185

  
225
        # add a message in formdata.evolution
226
        evo = Evolution()
227
        evo.time = time.localtime()
228
        evo.status = formdata.status
229
        evo.add_part(InvoiceEvolutionPart('create', invoice))
230
        if not formdata.evolution:
231
            formdata.evolution = []
232
        formdata.evolution.append(evo)
233
        formdata.store()
234
        # redirect the user to "my invoices"
186 235
        return get_publisher().get_frontoffice_url() + '/myspace/invoices/'
187 236

  
188 237
register_item_class(PaymentWorkflowStatusItem)
189 238

  
239
class PaymentCancelWorkflowStatusItem(WorkflowStatusItem):
240
    description = N_('Payment Cancel')
241
    key = 'payment-cancel'
242
    endpoint = False
243

  
244
    reason = None
245
    regie_id = None
246

  
247
    def render_as_line(self):
248
        if self.regie_id:
249
            if self.regie_id == '_all':
250
                return _('Cancel all Payments')
251
            else:
252
                return _('Cancel Payments for %s' % Regie.get(self.regie_id).label)
253
        else:
254
            return _('Cancel Payments (non completed)')
255

  
256
    def get_parameters(self):
257
        return ('reason', 'regie_id')
258

  
259
    def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
260
        if 'reason' in parameters:
261
            form.add(StringWidget, '%sreason' % prefix, title=_('Reason'),
262
                     value=self.reason, size=40)
263
        if 'regie_id' in parameters:
264
            form.add(SingleSelectWidget, '%sregie_id' % prefix,
265
                title=_('Regie'), value=self.regie_id,
266
                options = [(None, '---'), ('_all', _('All Regies'))] + \
267
                            [(x.id, x.label) for x in Regie.select()])
268

  
269
    def perform(self, formdata):
270
        invoices_id = []
271
        # get all invoices for the formdata and the selected regie
272
        for evo in [evo for evo in formdata.evolution if evo.parts]:
273
            for part in [part for part in evo.parts if isinstance(part, InvoiceEvolutionPart)]:
274
                if part.action == 'create':
275
                    invoices_id.append(part.id)
276
                elif part.id in invoices_id:
277
                    invoices_id.remove(part.id)
278
        invoices = [Invoice.get(id) for id in invoices_id]
279
        # select invoices for the selected regie (if not "all regies")
280
        if self.regie_id != '_all':
281
            invoices = [i for i in invoices if i.regie_id == self.regie_id]
282
        # security filter: check user 
283
        invoices = [i for i in invoices if (i.user_id == formdata.user_id) \
284
                or (i.user_hash == formdata.user_hash)]
285
        # security filter: check formdata & formdef
286
        invoices = [i for i in invoices if (i.formdata_id == formdata.id) \
287
                and (i.formdef_id == formdata.formdef.id)]
288
        evo = Evolution()
289
        evo.time = time.localtime()
290
        for invoice in invoices:
291
            if not (invoice.paid or invoice.canceled):
292
                invoice.cancel(self.reason)
293
                evo.add_part(InvoiceEvolutionPart('cancel', invoice))
294
        if not formdata.evolution:
295
            formdata.evolution = []
296
        formdata.evolution.append(evo)
297
        formdata.store()
298
        return get_publisher().get_frontoffice_url() + '/myspace/invoices/'
299

  
300
register_item_class(PaymentCancelWorkflowStatusItem)
301

  
302

  
190 303
def request_payment(invoice_ids, url, add_regie=True):
191 304
    for invoice_id in invoice_ids:
192 305
        if not Invoice.check_crc(invoice_id):
193 306
            raise KeyError()
194 307
    invoices = [ Invoice.get(invoice_id) for invoice_id in invoice_ids ]
195
    invoices = filter(lambda x: not x.paid, invoices)
308
    invoices = [ i for i in invoices if not (i.paid or i.canceled) ]
196 309
    regie_ids = set([invoice.regie_id for invoice in invoices])
197
    # Do not apply if more than one regie is used or no invoice is not paid
310
    # Do not apply if more than one regie is used or no invoice is not paid or canceled
198 311
    if len(invoices) == 0 or len(regie_ids) != 1:
199 312
        url = get_publisher().get_frontoffice_url()
200 313
        if get_session().user:
extra/modules/payments_ui.ptl
39 39
        '<div class="details">'
40 40
        htmltext(invoice.details)
41 41
        '</div>'
42
    if invoice.canceled:
43
        '<p class="canceled">'
44
        '%s' % _('canceled on %s') % misc.localstrftime(invoice.canceled_date)
45
        if invoice.canceled_reason:
46
            ' (%s)' % invoice.canceled_reason
47
        '</p>'
42 48
    if invoice.paid:
43 49
        '<p class="paid">%s</p>' % _('paid on %s') % misc.localstrftime(invoice.paid_date)
44 50
    '</div>'
......
81 87
            except KeyError:
82 88
                raise errors.TraversalError()
83 89
            invoice_as_html(invoice)
84
            if not invoice.paid:
90
            if not (invoice.paid or invoice.canceled):
85 91
                regies_id.add(invoice.regie_id)
86 92

  
87 93
        if len(regies_id) == 1:

Formats disponibles : Unified diff