source: main/waeup.kofa/trunk/src/waeup/kofa/accesscodes/browser.py @ 16000

Last change on this file since 16000 was 11254, checked in by uli, 11 years ago

Merge changes from uli-diazo-themed back into trunk. If this works, then a miracle happened.

  • Property svn:keywords set to Id
File size: 10.0 KB
Line 
1## $Id: browser.py 11254 2014-02-22 15:46:03Z 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"""UI components for accesscodes.
19"""
20import grok
21from datetime import datetime
22from zope.component import getUtility
23from hurry.workflow.interfaces import InvalidTransitionError
24from waeup.kofa.browser.layout import KofaPage, KofaAddFormPage, NullValidator
25from waeup.kofa.browser.breadcrumbs import Breadcrumb
26from waeup.kofa.browser.viewlets import (
27    AdminTask, AddActionButton, SearchActionButton, BatchOpButton, ManageLink)
28from waeup.kofa.interfaces import IKofaObject, IKofaUtils
29from waeup.kofa.interfaces import MessageFactory as _
30from waeup.kofa.accesscodes.interfaces import (
31    IAccessCodeBatchContainer, IAccessCodeBatch,
32    )
33from waeup.kofa.accesscodes.catalog import search
34from waeup.kofa.browser.layout import action
35
36grok.context(IKofaObject)
37
38class BatchContainerPage(KofaPage):
39    grok.name('index')
40    grok.context(IAccessCodeBatchContainer)
41    grok.template('batchcontainer')
42    grok.require('waeup.manageACBatches')
43    archive_button = _('Archive')
44    delete_button = _('Archive and delete')
45
46    label = _('Access Code Batches')
47    pnav = 0
48
49    def update(self, batches=None, archive=None, delete=None):
50        if archive is None and delete is None:
51            return
52        if not batches:
53            self.flash(_('No batch selected.'), type='warning')
54            return
55        if isinstance(batches, basestring):
56            batches = [batches]
57        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
58        for name in batches:
59            batch = self.context[name]
60            csv_file = batch.archive()
61            self.flash(_('Archived ${a} (${b})',
62                mapping = {'a':name, 'b':csv_file}))
63            message = 'archived: %s (%s)' % (name,csv_file)
64            self.context.logger_info(ob_class, message)
65            if delete is None:
66                continue
67            del self.context[name]
68            self.context._p_changed = True
69            self.flash(_('Deleted batch ${a}', mapping = {'a':name}))
70            message = 'deleted: %s' % name
71            self.context.logger_info(ob_class, message)
72
73class AddBatchPage(KofaAddFormPage):
74    grok.name('add')
75    grok.context(IAccessCodeBatchContainer)
76    grok.require('waeup.manageACBatches')
77
78    label = _('Create Access Code Batch')
79    pnav = 0
80
81    form_fields = grok.AutoFields(IAccessCodeBatch).select(
82        'prefix', 'entry_num', 'cost')
83
84    @action(_('Create batch'), style='primary')
85    def createBatch(self, **data):
86        creator = self.request.principal.id
87        creation_date = datetime.utcnow()
88        data.update(creation_date=creation_date, creator=creator)
89        batch = self.context.createBatch(**data)
90        csv_file = batch.createCSVLogFile()
91        self.context._p_changed = True
92        self.flash(_('Batch created (${a} entries)',
93            mapping = {'a':data['entry_num']}))
94        self.flash(_('Data written to ${a}', mapping = {'a':csv_file}))
95        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
96        message = 'created: %s (%d, %f)' % (
97            csv_file, data['entry_num'], data['cost'])
98        self.context.logger_info(ob_class, message)
99        self.redirect(self.url(self.context))
100
101    @action(_('Cancel'), validator=NullValidator)
102    def cancel(self, *args, **kw):
103        self.flash(_('Batch creation cancelled.'), type='warning')
104        self.redirect(self.url(self.context))
105
106class ReimportBatchPage(KofaPage):
107    """Screen for reimporting AC batches.
108    """
109    grok.name('reimport')
110    grok.context(IAccessCodeBatchContainer)
111    grok.template('reimportbatchpage')
112    grok.require('waeup.manageACBatches')
113    reimport_button = _('Reimport')
114    cancel_button = _('Cancel')
115
116    label = _('Reimport Access Code Batches')
117    pnav = 0
118
119    def update(self, filenames=None, reimport=None, cancel=None):
120        if cancel is not None:
121            self.flash(_('Reimport cancelled.'), type='warning')
122            self.redirect(self.url(self.context))
123            return
124        if reimport is None:
125            return
126        if not filenames:
127            self.flash(_('No file chosen. Action cancelled.'), type='warning')
128            self.redirect(self.url(self.context))
129            return
130        if isinstance(filenames, basestring):
131            filenames = [filenames]
132        userid = self.request.principal.id
133        for filename in filenames:
134            try:
135                self.context.reimport(filename, userid)
136            except KeyError:
137                self.flash(_('This batch already exists: ${a}',
138                    mapping = {'a':filename}), type='warning')
139                continue
140            self.flash(_('Successfully reimported: ${a}',
141                mapping = {'a':filename}))
142            ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
143            message = 'reimported: %s' % filename
144            self.context.logger_info(ob_class, message)
145        self.redirect(self.url(self.context))
146
147class BatchContainerSearchPage(KofaPage):
148    grok.name('search')
149    grok.context(IAccessCodeBatchContainer)
150    grok.template('searchpage')
151    grok.require('waeup.manageACBatches')
152    pnav = 0
153    label = _('Search and Manage Access Codes')
154    search_button = _('Search')
155    disable_button = _('Disable ACs')
156    enable_button = _('Enable ACs')
157    cancel_button = _('Cancel Search')
158
159    def update(self, *args, **kw):
160        form = self.request.form
161        if 'cancel' in form:
162            self.redirect(self.url(self.context))
163            return
164        self.hitlist = []
165        if 'searchterm' in form and form['searchterm']:
166            self.searchterm = form['searchterm']
167            self.searchtype = form['searchtype']
168        elif 'old_searchterm' in form:
169            self.searchterm = form['old_searchterm']
170            self.searchtype = form['old_searchtype']
171        else:
172            return
173        if not 'entries' in form:
174            self.hitlist = search(query=self.searchterm,
175                searchtype=self.searchtype, view=self)
176            return
177        entries = form['entries']
178        if isinstance(entries, basestring):
179            entries = [entries]
180        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
181        for entry in entries:
182            if 'disable' in form:
183                try:
184                    comment = _(u"disabled")
185                    self.context.disable(entry, comment)
186                    self.flash(_('${a} disabled.', mapping = {'a':entry}))
187                    message = 'disabled: %s' % entry
188                    self.context.logger_info(ob_class, message)
189                except InvalidTransitionError:
190                    self.flash(_('${a}: Disable transition not allowed.',
191                        mapping = {'a':entry}), type='danger')
192            elif 'enable' in form:
193                try:
194                    comment = _(u"re-enabled")
195                    self.context.enable(entry, comment)
196                    self.flash(_('${a} (re-)enabled.', mapping = {'a':entry}))
197                    message = '(re-)enabled: %s' % entry
198                    self.context.logger_info(ob_class, message)
199                except InvalidTransitionError:
200                    self.flash(_('${a}: Re-enable transition not allowed.',
201                               mapping = {'a':entry}), type='danger')
202        self.hitlist = search(query=self.searchterm,
203            searchtype=self.searchtype, view=self)
204        return
205
206class BatchContainerBreadcrumb(Breadcrumb):
207    """A breadcrumb for ac batch containers.
208    """
209    grok.require('waeup.manageACBatches')
210    grok.context(IAccessCodeBatchContainer)
211    title = _(u'Access Code Batches')
212    parent_viewname = 'administration'
213
214#class BatchContainerSearchBreadcrumb(Breadcrumb):
215#    """A breadcrumb for ac batch containers search page.
216#    """
217#    grok.require('waeup.manageACBatches')
218#    grok.context(IAccessCodeBatchContainer)
219#    grok.name('search')
220#    title = u'Search Access Codes'
221#    viewname = 'search'
222#    parent_viewname = 'index'
223
224class AdminTaskManageACBatches(AdminTask):
225    """Entry on administration page that links to batch container.
226    """
227    grok.order(5)
228    grok.require('waeup.manageACBatches')
229    grok.template('admintaskacbatches')
230
231    link_title = _('Access Code Batches')
232    target_viewname = 'accesscodes'
233
234class CreateBatchButton(AddActionButton):
235    """Action button on batch container page which links to batch creation.
236    """
237    grok.context(IAccessCodeBatchContainer)
238    grok.view(BatchContainerPage)
239    grok.require('waeup.manageACBatches')
240    text = _('Add Access Code Batch')
241
242class ReimportBatchButton(BatchOpButton):
243    """Action button on batch container page which links to batch reimport.
244    """
245    grok.context(IAccessCodeBatchContainer)
246    grok.view(BatchContainerPage)
247    grok.require('waeup.manageACBatches')
248    target = 'reimport'
249    text = _('Reimport Access Code Batch')
250
251class SearchAccessCodeButton(SearchActionButton):
252    """Action button on batch container page which links to search.
253    """
254    grok.context(IAccessCodeBatchContainer)
255    grok.view(BatchContainerPage)
256    grok.require('waeup.manageACBatches')
257    text = _('Search Access Codes')
258
259class ManageAccessCodes(ManageLink):
260    """Link in upper left box to access code management.
261    """
262    grok.order(5)
263    grok.require('waeup.manageACBatches')
264
265    link = u'accesscodes'
266    text = _(u'Access Codes')
Note: See TracBrowser for help on using the repository browser.