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

Last change on this file since 8382 was 8194, checked in by Henrik Bettermann, 12 years ago

Store utc without tzinfo in persistent datetime objects. Localisation will be done in views only.

  • Property svn:keywords set to Id
File size: 9.8 KB
Line 
1## $Id: browser.py 8194 2012-04-17 11:40:06Z 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 zope.component import getUtility
23from hurry.workflow.interfaces import InvalidTransitionError
24from waeup.kofa.browser.resources import datatable
25from waeup.kofa.browser import KofaPage, KofaAddFormPage, NullValidator
26from waeup.kofa.browser.breadcrumbs import Breadcrumb
27from waeup.kofa.browser.viewlets import (
28    AdminTask, AddActionButton, SearchActionButton, BatchOpButton, ManageLink)
29from waeup.kofa.interfaces import IKofaObject, IKofaUtils
30from waeup.kofa.interfaces import MessageFactory as _
31from waeup.kofa.accesscodes.interfaces import (
32    IAccessCodeBatchContainer, IAccessCodeBatch,
33    )
34from waeup.kofa.accesscodes.catalog import search
35from waeup.kofa.browser.layout import action
36
37grok.context(IKofaObject)
38
39class BatchContainerPage(KofaPage):
40    grok.name('index')
41    grok.context(IAccessCodeBatchContainer)
42    grok.template('batchcontainer')
43    grok.require('waeup.manageACBatches')
44    archive_button = _('Archive')
45    delete_button = _('Archive and delete')
46
47    label = _('Access Code Batches')
48    pnav = 0
49
50    def update(self, batches=None, archive=None, delete=None):
51        if archive is None and delete is None:
52            return
53        if not batches:
54            self.flash(_('No batch selected.'))
55            return
56        if isinstance(batches, basestring):
57            batches = [batches]
58        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
59        for name in batches:
60            batch = self.context[name]
61            csv_file = batch.archive()
62            self.flash(_('Archived ${a} (${b})',
63                mapping = {'a':name, 'b':csv_file}))
64            message = 'archived: %s (%s)' % (name,csv_file)
65            self.context.logger_info(ob_class, message)
66            if delete is None:
67                continue
68            del self.context[name]
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.'))
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.'))
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.'))
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}))
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
158    def update(self, *args, **kw):
159        datatable.need()
160        form = self.request.form
161        self.hitlist = []
162        if 'searchterm' in form and form['searchterm']:
163            self.searchterm = form['searchterm']
164            self.searchtype = form['searchtype']
165        elif 'old_searchterm' in form:
166            self.searchterm = form['old_searchterm']
167            self.searchtype = form['old_searchtype']
168        else:
169            return
170        if not 'entries' in form:
171            self.hitlist = search(query=self.searchterm,
172                searchtype=self.searchtype, view=self)
173            return
174        entries = form['entries']
175        if isinstance(entries, basestring):
176            entries = [entries]
177        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
178        for entry in entries:
179            if 'disable' in form:
180                try:
181                    comment = _(u"disabled")
182                    self.context.disable(entry, comment)
183                    self.flash(_('${a} disabled.', mapping = {'a':entry}))
184                    message = 'disabled: %s' % entry
185                    self.context.logger_info(ob_class, message)
186                except InvalidTransitionError:
187                    self.flash(_('${a}: Disable transition not allowed.',
188                        mapping = {'a':entry}))
189            elif 'enable' in form:
190                try:
191                    comment = _(u"re-enabled")
192                    self.context.enable(entry, comment)
193                    self.flash(_('${a} (re-)enabled.', mapping = {'a':entry}))
194                    message = '(re-)enabled: %s' % entry
195                    self.context.logger_info(ob_class, message)
196                except InvalidTransitionError:
197                    self.flash(_('${a}: Re-enable transition not allowed.', mapping = {'a':entry}))
198        self.hitlist = search(query=self.searchterm,
199            searchtype=self.searchtype, view=self)
200        return
201
202class BatchContainerBreadcrumb(Breadcrumb):
203    """A breadcrumb for ac batch containers.
204    """
205    grok.require('waeup.manageACBatches')
206    grok.context(IAccessCodeBatchContainer)
207    title = _(u'Access Code Batches')
208    parent_viewname = 'administration'
209
210#class BatchContainerSearchBreadcrumb(Breadcrumb):
211#    """A breadcrumb for ac batch containers search page.
212#    """
213#    grok.require('waeup.manageACBatches')
214#    grok.context(IAccessCodeBatchContainer)
215#    grok.name('search')
216#    title = u'Search Access Codes'
217#    viewname = 'search'
218#    parent_viewname = 'index'
219
220class AdminTaskManageACBatches(AdminTask):
221    """Entry on administration page that links to batch container.
222    """
223    grok.order(5)
224    grok.require('waeup.manageACBatches')
225    grok.template('admintaskacbatches')
226
227    link_title = _('Access Code Batches')
228    target_viewname = 'accesscodes'
229
230class CreateBatchButton(AddActionButton):
231    """Action button on batch container page which links to batch creation.
232    """
233    grok.context(IAccessCodeBatchContainer)
234    grok.view(BatchContainerPage)
235    grok.require('waeup.manageACBatches')
236    text = _('Add Access Code Batch')
237
238class ReimportBatchButton(BatchOpButton):
239    """Action button on batch container page which links to batch reimport.
240    """
241    grok.context(IAccessCodeBatchContainer)
242    grok.view(BatchContainerPage)
243    grok.require('waeup.manageACBatches')
244    target = 'reimport'
245    text = _('Reimport Access Code Batch')
246
247class SearchAccessCodeButton(SearchActionButton):
248    """Action button on batch container page which links to search.
249    """
250    grok.context(IAccessCodeBatchContainer)
251    grok.view(BatchContainerPage)
252    grok.require('waeup.manageACBatches')
253    text = _('Search Access Codes')
254
255class ManageAccessCodes(ManageLink):
256    """Link in upper left box to access code management.
257    """
258    grok.order(6)
259    grok.require('waeup.manageACBatches')
260
261    link = u'accesscodes'
262    text = _(u'Access Codes')
Note: See TracBrowser for help on using the repository browser.