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

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

Add AccessCodeProcessor?.

  • Property svn:keywords set to Id
File size: 9.8 KB
RevLine 
[7195]1## $Id: browser.py 9265 2012-10-01 21:18:48Z 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    """
[8387]259    grok.order(4)
[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.