source: main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/browser.py @ 9003

Last change on this file since 9003 was 7747, checked in by Henrik Bettermann, 13 years ago

Add logger for accesscodes.

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