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

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

Add viewlets for reports.py

Add permission to roles.

Set label attribbute of views.

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