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

Last change on this file since 9217 was 9217, checked in by uli, 12 years ago

Merge changes from uli-async-update back into trunk.

  • Property svn:keywords set to Id
File size: 9.8 KB
RevLine 
[7195]1## $Id: browser.py 9217 2012-09-21 11:21:05Z 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##
[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]
[7719]69            self.flash(_('Deleted batch ${a}', mapping = {'a':name}))
[7747]70            message = 'deleted: %s' % name
71            self.context.logger_info(ob_class, message)
[5104]72
[7819]73class AddBatchPage(KofaAddFormPage):
[5084]74    grok.name('add')
75    grok.context(IAccessCodeBatchContainer)
[5104]76    grok.require('waeup.manageACBatches')
[5084]77
[7719]78    label = _('Create Access Code Batch')
[5084]79    pnav = 0
80
[5088]81    form_fields = grok.AutoFields(IAccessCodeBatch).select(
[6417]82        'prefix', 'entry_num', 'cost')
[5088]83
[7719]84    @action(_('Create batch'), style='primary')
[5084]85    def createBatch(self, **data):
[5088]86        creator = self.request.principal.id
[8194]87        creation_date = datetime.utcnow()
[5088]88        data.update(creation_date=creation_date, creator=creator)
[5126]89        batch = self.context.createBatch(**data)
[5113]90        csv_file = batch.createCSVLogFile()
[5088]91        self.context._p_changed = True
[7720]92        self.flash(_('Batch created (${a} entries)',
93            mapping = {'a':data['entry_num']}))
94        self.flash(_('Data written to ${a}', mapping = {'a':csv_file}))
[7811]95        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
[7747]96        message = 'created: %s (%d, %f)' % (
97            csv_file, data['entry_num'], data['cost'])
98        self.context.logger_info(ob_class, message)
[5084]99        self.redirect(self.url(self.context))
100
[7719]101    @action(_('Cancel'), validator=NullValidator)
[7488]102    def cancel(self, *args, **kw):
[7719]103        self.flash(_('Batch creation cancelled.'))
[7488]104        self.redirect(self.url(self.context))
105
[7819]106class ReimportBatchPage(KofaPage):
[5132]107    """Screen for reimporting AC batches.
108    """
[5130]109    grok.name('reimport')
110    grok.context(IAccessCodeBatchContainer)
111    grok.template('reimportbatchpage')
112    grok.require('waeup.manageACBatches')
[7719]113    reimport_button = _('Reimport')
114    cancel_button = _('Cancel')
[5130]115
[7719]116    label = _('Reimport Access Code Batches')
[5130]117    pnav = 0
118
[5132]119    def update(self, filenames=None, reimport=None, cancel=None):
120        if cancel is not None:
[7719]121            self.flash(_('Reimport cancelled.'))
[5132]122            self.redirect(self.url(self.context))
123            return
124        if reimport is None:
125            return
126        if not filenames:
[7719]127            self.flash(_('No file chosen. Action cancelled.'))
[5132]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:
[7719]137                self.flash(_('This batch already exists: ${a}',
138                    mapping = {'a':filename}))
[5132]139                continue
[7719]140            self.flash(_('Successfully reimported: ${a}',
141                mapping = {'a':filename}))
[7811]142            ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
[7747]143            message = 'reimported: %s' % filename
144            self.context.logger_info(ob_class, message)
[5132]145        self.redirect(self.url(self.context))
[6388]146
[7819]147class BatchContainerSearchPage(KofaPage):
[5155]148    grok.name('search')
149    grok.context(IAccessCodeBatchContainer)
150    grok.template('searchpage')
151    grok.require('waeup.manageACBatches')
152    pnav = 0
[7719]153    label = _('Search and Manage Access Codes')
154    search_button = _('Search')
155    disable_button = _('Disable ACs')
156    enable_button = _('Enable ACs')
[5155]157
[6450]158    def update(self, *args, **kw):
[6455]159        datatable.need()
[6450]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:
[5155]169            return
[6450]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']
[5155]175        if isinstance(entries, basestring):
176            entries = [entries]
[7811]177        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
[5155]178        for entry in entries:
[6450]179            if 'disable' in form:
180                try:
[7745]181                    comment = _(u"disabled")
[6459]182                    self.context.disable(entry, comment)
[7719]183                    self.flash(_('${a} disabled.', mapping = {'a':entry}))
[7747]184                    message = 'disabled: %s' % entry
185                    self.context.logger_info(ob_class, message)
[6450]186                except InvalidTransitionError:
[7719]187                    self.flash(_('${a}: Disable transition not allowed.',
188                        mapping = {'a':entry}))
[6450]189            elif 'enable' in form:
190                try:
[7745]191                    comment = _(u"re-enabled")
[6459]192                    self.context.enable(entry, comment)
[7719]193                    self.flash(_('${a} (re-)enabled.', mapping = {'a':entry}))
[7747]194                    message = '(re-)enabled: %s' % entry
195                    self.context.logger_info(ob_class, message)
[6450]196                except InvalidTransitionError:
[7719]197                    self.flash(_('${a}: Re-enable transition not allowed.', mapping = {'a':entry}))
[6450]198        self.hitlist = search(query=self.searchterm,
199            searchtype=self.searchtype, view=self)
[5155]200        return
201
[5082]202class BatchContainerBreadcrumb(Breadcrumb):
203    """A breadcrumb for ac batch containers.
[5104]204    """
205    grok.require('waeup.manageACBatches')
[5082]206    grok.context(IAccessCodeBatchContainer)
[7719]207    title = _(u'Access Code Batches')
[5082]208    parent_viewname = 'administration'
209
[7488]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'
[5155]219
[5082]220class AdminTaskManageACBatches(AdminTask):
221    """Entry on administration page that links to batch container.
222    """
223    grok.order(5)
[5104]224    grok.require('waeup.manageACBatches')
[5082]225    grok.template('admintaskacbatches')
226
[7719]227    link_title = _('Access Code Batches')
[5082]228    target_viewname = 'accesscodes'
[5084]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)
[5104]235    grok.require('waeup.manageACBatches')
[7719]236    text = _('Add Access Code Batch')
[5104]237
[5129]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'
[7719]245    text = _('Reimport Access Code Batch')
[5129]246
[5155]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')
[7719]253    text = _('Search Access Codes')
[6388]254
[5381]255class ManageAccessCodes(ManageLink):
256    """Link in upper left box to access code management.
[5104]257    """
[8387]258    grok.order(4)
[5104]259    grok.require('waeup.manageACBatches')
260
[5381]261    link = u'accesscodes'
[7719]262    text = _(u'Access Codes')
Note: See TracBrowser for help on using the repository browser.