Projet

Général

Profil

Télécharger (11,6 ko) Statistiques
| Branche: | Tag: | Révision:

root / extra / modules / payments_ui.ptl @ c6ba8333

1
import time
2

    
3
from quixote import get_request, get_response, get_session, redirect
4
from quixote.directory import Directory, AccessControlled
5

    
6
import wcs
7
import wcs.admin.root
8
from wcs.backoffice.menu import *
9
from wcs.formdef import FormDef
10

    
11
from qommon import errors, misc, template
12
from qommon.form import *
13
from qommon.strftime import strftime
14

    
15
from payments import eopayment, Regie, is_payment_supported, Invoice
16

    
17
from qommon.admin.texts import TextsDirectory
18

    
19
if not set:
20
    from sets import Set as set
21

    
22
def invoice_as_html [html] (invoice):
23
    '<div id="invoice">'
24
    '<h2>%s</h2>' % _('Invoice: %s') % invoice.subject
25
    '<h3>%s' % _('Amount: %s') % invoice.amount
26
    ' &euro;</h3>'
27
    if invoice.formdef_id and invoice.formdata_id and \
28
            get_session().user == invoice.user_id:
29
        formdef = FormDef.get(invoice.formdef_id)
30
        formdata = formdef.data_class().get(invoice.formdata_id)
31
        name = _('%(form_name)s #%(formdata_id)s') % {
32
                'form_name': formdata.formdef.name,
33
                'formdata_id': formdata.id }
34
        '<p class="from">%s <a href="%s">%s</a></p>' % (_('From:'), formdata.get_url(), name)
35
    '<p class="regie">%s</p>' % _('Regie: %s') % Regie.get(invoice.regie_id).label
36
    '<p class="date">%s</p>' % _('Created on: %s') % misc.localstrftime(invoice.date)
37
    if invoice.details:
38
        '<p class="details">%s</p>' % _('Details:')
39
        '<div class="details">'
40
        htmltext(invoice.details)
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>'
48
    if invoice.paid:
49
        '<p class="paid">%s</p>' % _('paid on %s') % misc.localstrftime(invoice.paid_date)
50
    '</div>'
51

    
52
class InvoicesDirectory(Directory):
53
    _q_exports = ['', 'multiple']
54

    
55
    def _q_traverse(self, path):
56
        if not is_payment_supported():
57
            raise errors.TraversalError()
58
        get_response().filter['bigdiv'] = 'profile'
59
        if get_session().user:
60
            # fake breadcrumb
61
            get_response().breadcrumb.append(('myspace/', _('My Space')))
62
            get_response().breadcrumb.append(('invoices/', _('Invoices')))
63
        return Directory._q_traverse(self, path)
64

    
65
    def multiple [html] (self):
66
        invoice_ids = get_request().form.get('invoice')
67
        if type(invoice_ids) is not list:
68
            return redirect('%s' % invoice_ids)
69
        return redirect('+'.join(invoice_ids))
70

    
71
    def _q_lookup [html] (self, component):
72
        if str('+') in component:
73
            invoice_ids = component.split(str('+'))
74
        else:
75
            invoice_ids = [component]
76
        for invoice_id in invoice_ids:
77
            if not Invoice.check_crc(invoice_id):
78
                raise errors.TraversalError()
79

    
80
        template.html_top(_('Invoices'))
81
        TextsDirectory.get_html_text('aq-invoice')
82

    
83
        regies_id = set()
84
        for invoice_id in invoice_ids:
85
            try:
86
                invoice = Invoice.get(invoice_id)
87
            except KeyError:
88
                raise errors.TraversalError()
89
            invoice_as_html(invoice)
90
            if not (invoice.paid or invoice.canceled):
91
                regies_id.add(invoice.regie_id)
92

    
93
        if len(regies_id) == 1:
94
            '<p class="command">'
95
            '<a href="%s/payment/init?invoice_ids=%s">' % (get_publisher().get_frontoffice_url(), component)
96
            if len(invoice_ids) > 1:
97
                _('Pay Selected Invoices')
98
            else:
99
                _('Pay')
100
            '</a></p>'
101
        if len(regies_id) > 1:
102
            _('You can not pay to different regies.')
103

    
104
    def _q_index(self):
105
        return redirect('..')
106

    
107

    
108
class RegieDirectory(Directory):
109
    _q_exports = ['', 'edit', 'delete', 'options']
110

    
111
    def __init__(self, regie):
112
        self.regie = regie
113

    
114
    def _q_index [html] (self):
115
        form = Form(enctype='multipart/form-data')
116
        form.add_submit('edit', _('Edit'))
117
        form.add_submit('delete', _('Delete'))
118
        form.add_submit('back', _('Back'))
119

    
120
        if form.get_submit() == 'edit':
121
            return redirect('edit')
122
        if form.get_submit() == 'delete':
123
            return redirect('delete')
124
        if form.get_submit() == 'back':
125
            return redirect('..')
126

    
127
        html_top('payments', title = _('Regie: %s') % self.regie.label)
128
        '<h2>%s</h2>' % _('Regie: %s') % self.regie.label
129

    
130
        get_session().display_message()
131

    
132
        if self.regie.description:
133
            '<p>'
134
            self.regie.description
135
            '</p>'
136

    
137
        if self.regie.service:
138
            '<p>'
139
            '%s %s' % (_('Banking Service:'), self.regie.service)
140
            ' (<a href="options">%s</a>)' % _('options')
141
            '</p>'
142

    
143
        form.render()
144

    
145
    def edit [html] (self):
146
        form = self.form()
147
        if form.get_submit() == 'cancel':
148
            return redirect('.')
149

    
150
        if form.is_submitted() and not form.has_errors():
151
            self.submit(form)
152
            return redirect('..')
153

    
154
        html_top('payments', title = _('Edit Regie: %s') % self.regie.label)
155
        '<h2>%s</h2>' % _('Edit Regie: %s') % self.regie.label
156
        form.render()
157

    
158

    
159
    def form(self):
160
        form = Form(enctype='multipart/form-data')
161
        form.add(StringWidget, 'label', title=_('Label'), required=True,
162
                value=self.regie.label)
163
        form.add(TextWidget, 'description', title=_('Description'),
164
                value=self.regie.description, rows=5, cols=60)
165
        form.add(SingleSelectWidget, 'service', title=_('Banking Service'),
166
                value=self.regie.service, required=True,
167
                options = [
168
                        ('dummy', _('Dummy (for tests)')),
169
                        ('sips', 'SIPS'),
170
                        ('systempayv2', 'systempay (Banque Populaire)'),
171
                        ('spplus', _('SP+ (Caisse d\'epargne)'))])
172
        form.add_submit('submit', _('Submit'))
173
        form.add_submit('cancel', _('Cancel'))
174
        return form
175

    
176
    def submit(self, form):
177
        for k in ('label', 'description', 'service'):
178
            widget = form.get_widget(k)
179
            if widget:
180
                setattr(self.regie, k, widget.parse())
181
        self.regie.store()
182

    
183
    def delete [html] (self):
184
        form = Form(enctype='multipart/form-data')
185
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
186
                        'You are about to irrevocably delete this regie.')))
187
        form.add_submit('submit', _('Submit'))
188
        form.add_submit('cancel', _('Cancel'))
189
        if form.get_submit() == 'cancel':
190
            return redirect('..')
191
        if not form.is_submitted() or form.has_errors():
192
            get_response().breadcrumb.append(('delete', _('Delete')))
193
            html_top('payments', title = _('Delete Regie'))
194
            '<h2>%s</h2>' % _('Deleting Regie: %s') % self.regie.label
195
            form.render()
196
        else:
197
            self.regie.remove_self()
198
            return redirect('..')
199

    
200
    def options [html] (self):
201
        form = Form(enctype='multipart/form-data')
202
        module = eopayment.get_backend(self.regie.service)
203
        try:
204
            '<!-- \n'
205
            module.description['parameters']
206
            '-->'
207
        except:
208
            return template.error_page(_('Payment backend do not list its options'))
209
            raise errors.TraversalError()
210
        service_options = self.regie.service_options or {}
211
        banking_titles = {
212
            ('dummy', 'direct_notification_url'): N_('Direct Notification URL'),
213
            ('dummy', 'siret'): N_('Dummy SIRET'),
214
        }
215
        for parameter, infos in module.description['parameters'].items():
216
            title = banking_titles.get((self.regie.service, parameter), infos.get('caption'))
217
            if 'type' not in infos or infos['type'] is str:
218
                form.add(StringWidget, parameter, title=title,
219
                         value=service_options.get(parameter))
220
            elif infos['type'] is bool:
221
                form.add(CheckboxWidget, parameter, title=title,
222
                         value=service_options.get(parameter))
223
        form.add_submit('submit', _('Submit'))
224
        form.add_submit('cancel', _('Cancel'))
225

    
226
        if form.get_submit() == 'cancel':
227
            return redirect('.')
228

    
229
        if form.is_submitted() and not form.has_errors():
230
            self.submit_options(form, module)
231
            return redirect('..')
232

    
233
        html_top('payments', title=_('Edit Service Options'))
234
        '<h2>%s</h2>' % _('Edit Service Options')
235
        form.render()
236

    
237
    def submit_options(self, form, module):
238
        if not self.regie.service_options:
239
            self.regie.service_options = {}
240
        for parameter, infos in module.description['parameters'].items():
241
            self.regie.service_options[parameter] = form.get_widget(parameter).parse()
242
        self.regie.store()
243

    
244
class RegiesDirectory(Directory):
245
    _q_exports = ['', 'new']
246

    
247
    def _q_traverse(self, path):
248
        get_response().breadcrumb.append(('regie/', _('Regies')))
249
        return Directory._q_traverse(self, path)
250

    
251
    def _q_index [html] (self):
252
        return redirect('..')
253

    
254
    def new [html] (self):
255
        regie_ui = RegieDirectory(Regie())
256

    
257
        form = regie_ui.form()
258
        if form.get_submit() == 'cancel':
259
            return redirect('.')
260

    
261
        if form.is_submitted() and not form.has_errors():
262
            regie_ui.submit(form)
263
            return redirect('%s/' % regie_ui.regie.id)
264

    
265
        get_response().breadcrumb.append(('new', _('New Regie')))
266
        html_top('payments', title = _('New Regie'))
267
        '<h2>%s</h2>' % _('New Regie')
268
        form.render()
269

    
270
    def _q_lookup(self, component):
271
        try:
272
            regie = Regie.get(component)
273
        except KeyError:
274
            raise errors.TraversalError()
275
        get_response().breadcrumb.append((str(regie.id), regie.label))
276
        return RegieDirectory(regie)
277

    
278

    
279
class PaymentsDirectory(AccessControlled, Directory):
280
    _q_exports = ['', 'regie']
281
    label = N_('Payments')
282

    
283
    regie = RegiesDirectory()
284

    
285
    def _q_access(self):
286
        user = get_request().user
287
        if not user:
288
            raise errors.AccessUnauthorizedError()
289
        admin_role = get_cfg('aq-permissions', {}).get('payments', None)
290
        if not (user.is_admin or admin_role in (user.roles or [])):
291
            raise errors.AccessForbiddenError(
292
                    public_msg = _('You are not allowed to access Payments Management'),
293
                    location_hint = 'backoffice')
294

    
295
        get_response().breadcrumb.append(('payments/', _('Payments')))
296

    
297

    
298
    def _q_index [html] (self):
299
        html_top('payments', _('Payments'))
300

    
301
        '<ul id="main-actions">'
302
        '  <li><a class="new-item" href="regie/new">%s</a></li>' % _('New Regie')
303
        '</ul>'
304

    
305
        if not is_payment_supported:
306
            '<p class="infonotice">'
307
            _('Payment is not supported.')
308
            '</p>'
309

    
310
        regies = Regie.select()
311
        '<h2>%s</h2>' % _('Regies')
312
        if not regies:
313
            '<p>'
314
            _('There are no regies defined at the moment.')
315
            '</p>'
316
        '<ul class="biglist" id="regies-list">'
317
        for l in regies:
318
            regie_id = l.id
319
            '<li class="biglistitem" id="itemId_%s">' % regie_id
320
            '<strong class="label"><a href="regie/%s/">%s</a></strong>' % (regie_id, l.label)
321
            '<p class="commands">'
322
            command_icon('regie/%s/edit' % regie_id, 'edit')
323
            command_icon('regie/%s/delete' % regie_id, 'remove')
324
            '</p></li>'
325
        '</ul>'
326

    
327

    
328
TextsDirectory.register('aq-invoice',
329
        N_('Message on top of an invoice'),
330
        category = N_('Invoices'))
(21-21/26)