source: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py @ 15344

Last change on this file since 15344 was 13139, checked in by Henrik Bettermann, 9 years ago

Repair document manage form pages. Buttons were missing.

  • Property svn:keywords set to Id
File size: 12.5 KB
RevLine 
[12206]1## $Id: browser.py 13139 2015-07-05 07:42:57Z henrik $
2##
3## Copyright (C) 2014 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 documents offered for download by the company.
19"""
20
21import sys
22import grok
23import pytz
24from urllib import urlencode
25from datetime import datetime
[12215]26from hurry.workflow.interfaces import (
27    IWorkflowInfo, IWorkflowState, InvalidTransitionError)
[12206]28from zope.event import notify
29from zope.i18n import translate
30from zope.catalog.interfaces import ICatalog
31from zope.component import queryUtility, getUtility, createObject
32from zope.schema.interfaces import ConstraintNotSatisfied, RequiredMissing
33from zope.formlib.textwidgets import BytesDisplayWidget
34from zope.security import checkPermission
[12408]35from waeup.ikoba.utils.helpers import html2dict, rest2dict
[12206]36from waeup.ikoba.interfaces import MessageFactory as _
37from waeup.ikoba.interfaces import (
[13139]38    IContactForm, IIkobaObject, IIkobaUtils, PUBLISHED)
[12206]39from waeup.ikoba.browser.layout import (
40    IkobaPage, IkobaEditFormPage, IkobaAddFormPage, IkobaDisplayFormPage,
[13066]41    NullValidator, jsaction, action, UtilityView)
[12206]42from waeup.ikoba.widgets.datewidget import (
43    FriendlyDateWidget, FriendlyDateDisplayWidget,
44    FriendlyDatetimeDisplayWidget)
45from waeup.ikoba.browser.breadcrumbs import Breadcrumb
46from waeup.ikoba.browser.pages import (
47    delSubobjects, add_local_role, del_local_roles, msave,
48    LocalRoleAssignmentUtilityView)
49
50from waeup.ikoba.documents.interfaces import (
[12408]51    IDocumentsContainer, IPublicDocument,
52    IHTMLDocument, IRESTDocument, IDocumentsUtils)
[12206]53
54grok.context(IIkobaObject) # Make IKofaObject the default context
55grok.templatedir('browser_templates')
56
57
58class DocumentsBreadcrumb(Breadcrumb):
59    """A breadcrumb for the customers container.
60    """
61    grok.context(IDocumentsContainer)
62    title = _('Documents')
63
64
65class DocumentBreadcrumb(Breadcrumb):
66    """A breadcrumb for the customer container.
67    """
[12214]68    grok.context(IPublicDocument)
[12206]69
70    def title(self):
71        return self.context.title
72
73
74class DocumentsContainerPage(IkobaDisplayFormPage):
75    """The standard view for document containers.
76    """
77    grok.context(IDocumentsContainer)
78    grok.name('index')
79    grok.require('waeup.viewDocuments')
80    grok.template('containerpage')
81    pnav = 2
82    label = _('Documents')
83
84
85class DocumentsContainerManageFormPage(IkobaEditFormPage,
86                                      LocalRoleAssignmentUtilityView):
87    """The manage page for customer containers.
88    """
89    grok.context(IDocumentsContainer)
90    grok.name('manage')
91    grok.require('waeup.manageDocuments')
92    grok.template('containermanagepage')
93    pnav = 2
94    label = _('Manage document section')
95
[12214]96    @action(_('Add document'), validator=NullValidator, style='primary')
97    def addSubunit(self, **data):
98        self.redirect(self.url(self.context, 'adddoc'))
99        return
[12206]100
[12214]101    @jsaction(_('Remove selected documents'))
[12206]102    def delDocuments(self, **data):
103        delSubobjects(self, redirect='manage', tab='2')
104        return
105
106    @action(_('Cancel'), validator=NullValidator)
107    def cancel(self, **data):
108        self.redirect(self.url(self.context))
109        return
110
111
112class DocumentAddFormPage(IkobaAddFormPage):
113    """Add-form to add a customer.
114    """
115    grok.context(IDocumentsContainer)
116    grok.require('waeup.manageDocuments')
[12214]117    grok.name('adddoc')
118    grok.template('documentaddform')
[12206]119    label = _('Add document')
120    pnav = 2
121
[12215]122    form_fields = grok.AutoFields(IPublicDocument)
123
[12214]124    @property
125    def selectable_doctypes(self):
126        doctypes = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT
127        return sorted(doctypes.items())
128
[12222]129    @action(_('Add document'), style='primary')
[12214]130    def createDocument(self, **data):
131        form = self.request.form
132        doctype = form.get('doctype', None)
133        # Here we can create various instances of PublicDocument derived
134        # classes depending on the doctype parameter given in form.
135        document = createObject('waeup.%s' % doctype)
[12206]136        self.applyData(document, **data)
[12413]137        try:
138            self.context.addDocument(document)
139        except KeyError:
140            self.flash(_('The id chosen already exists.'),
141                       type='danger')
142            return
[12214]143        doctype = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT[doctype]
144        self.flash(_('${a} added.', mapping = {'a': doctype}))
[12206]145        ob_class = self.__implemented__.__name__.replace('waeup.ikoba.','')
146        self.context.__parent__.logger.info(
[12214]147            '%s - added: %s %s' % (ob_class, doctype, document.document_id))
[12413]148        self.redirect(self.url(self.context) +
149            '/%s/manage' % document.document_id)
[12206]150        return
151
[12214]152    @action(_('Cancel'), validator=NullValidator)
153    def cancel(self, **data):
154        self.redirect(self.url(self.context))
[12206]155
[12214]156
[12206]157class DocumentDisplayFormPage(IkobaDisplayFormPage):
158    """ Page to display document data
159    """
[12214]160    grok.context(IPublicDocument)
[12206]161    grok.name('index')
162    grok.require('waeup.viewDocuments')
[12215]163    grok.template('documentpage')
[12206]164    pnav = 2
165
166    @property
[12214]167    def form_fields(self):
168        return grok.AutoFields(self.context.form_fields_interface)
169
170    @property
[12206]171    def label(self):
172        return self.context.title
173
174
[12227]175class HTMLDocumentDisplayFormPage(DocumentDisplayFormPage):
176    """ Page to display html document data
177    """
178    grok.context(IHTMLDocument)
179    grok.template('htmldocumentpage')
180
181    @property
182    def form_fields(self):
183        return grok.AutoFields(self.context.form_fields_interface).omit(
[12365]184            'html_dict', 'html_multilingual')
[12227]185
186    @property
187    def html(self):
188        lang = self.request.cookies.get('ikoba.language')
189        html = self.context.html_dict.get(lang,'')
190        if html =='':
191            portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
192            html = self.context.html_dict.get(portal_language,'')
193        return html
194
195
[12242]196class HTMLDocumentDisplayContentPage(IkobaPage):
197    """ Page to display the html content of document
198    """
199    grok.context(IHTMLDocument)
200    grok.name('display')
201    grok.template('htmldisplaypage')
[12245]202    grok.require('waeup.Public')
[12242]203
204    @property
205    def label(self):
206        return self.context.title
207
208    def update(self):
209        if self.context.state != PUBLISHED:
210            self.flash(_('The document requested has not yet been published.'),
211                type="warning")
[12243]212            self.redirect(self.application_url())
[12242]213        super(HTMLDocumentDisplayContentPage, self).update()
214        return
215
216    @property
217    def content(self):
218        lang = self.request.cookies.get('ikoba.language')
219        html = self.context.html_dict.get(lang,'')
220        if html =='':
221            portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
222            html = self.context.html_dict.get(portal_language,'')
223        return html
224
225
[12408]226class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage):
227    """ Page to display html document data
228    """
229    grok.context(IRESTDocument)
230
231    @property
232    def form_fields(self):
233        return grok.AutoFields(self.context.form_fields_interface).omit(
234            'html_dict', 'rest_multilingual')
235
236
237class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage):
238    """ Page to display the html content of document
239    """
240    grok.context(IRESTDocument)
241
242    label = None
243
244
[12206]245class DocumentManageFormPage(IkobaEditFormPage,
246                            LocalRoleAssignmentUtilityView):
247    """ View to manage document data
248    """
[12214]249    grok.context(IPublicDocument)
[12206]250    grok.name('manage')
251    grok.require('waeup.manageDocuments')
252    grok.template('documentmanagepage')
253    pnav = 2
254
255    taboneactions = [_('Save'),_('Cancel')]
[12227]256    tabthreeactions1 = [_('Remove selected local roles')]
257    tabthreeactions2 = [_('Add local role')]
[12206]258
[12225]259    deletion_warning = _('Are you sure?')
260
[12214]261    @property
262    def form_fields(self):
[12457]263        return grok.AutoFields(
264            self.context.form_fields_interface).omit('document_id')
[12214]265
[12206]266    def label(self):
267        return _('Manage document ') + self.context.document_id
268
269    @action(_('Save'), style='primary')
270    def save(self, **data):
271        return msave(self, **data)
272
273    @action(_('Cancel'), validator=NullValidator)
274    def cancel(self, **data):
275        self.redirect(self.url(self.context))
276        return
277
278    @action(_('Add local role'), validator=NullValidator)
279    def addLocalRole(self, **data):
[13139]280        return add_local_role(self,3,**data)
[12206]281
282    @action(_('Remove selected local roles'))
283    def delLocalRoles(self, **data):
[13139]284        return del_local_roles(self,3,**data)
[12215]285
286
[12227]287class HTMLDocumentManageFormPage(DocumentManageFormPage):
288    """ View to manage htmldocument data
289    """
290    grok.context(IHTMLDocument)
[12236]291    grok.template('htmldocumentmanagepage')
[12227]292
293    @action(_('Save'), style='primary')
294    def save(self, **data):
295        msave(self, **data)
[12239]296        html_multilingual = getattr(self.context, 'html_multilingual', None)
[12229]297        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
[12239]298        self.context.html_dict = html2dict(html_multilingual, portal_language)
[12227]299        return
300
[13139]301    # Actions must be repeated. They are not inherited from the parent class.
[12227]302
[13139]303    @action(_('Cancel'), validator=NullValidator)
304    def cancel(self, **data):
305        self.redirect(self.url(self.context))
306        return
307
308    @action(_('Add local role'), validator=NullValidator)
309    def addLocalRole(self, **data):
310        return add_local_role(self,3,**data)
311
312    @action(_('Remove selected local roles'))
313    def delLocalRoles(self, **data):
314        return del_local_roles(self,3,**data)
315
316
[12408]317class RESTDocumentManageFormPage(DocumentManageFormPage):
318    """ View to manage restdocument data
319    """
320    grok.context(IRESTDocument)
321    grok.template('htmldocumentmanagepage')
322
323    @action(_('Save'), style='primary')
324    def save(self, **data):
325        msave(self, **data)
326        html_multilingual = getattr(self.context, 'rest_multilingual', None)
327        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
328        self.context.html_dict = rest2dict(html_multilingual, portal_language)
329        return
330
[13139]331    # Actions must be repeated. They are not inherited from the parent class.
[12408]332
[13139]333    @action(_('Cancel'), validator=NullValidator)
334    def cancel(self, **data):
335        self.redirect(self.url(self.context))
336        return
337
338    @action(_('Add local role'), validator=NullValidator)
339    def addLocalRole(self, **data):
340        return add_local_role(self,3,**data)
341
342    @action(_('Remove selected local roles'))
343    def delLocalRoles(self, **data):
344        return del_local_roles(self,3,**data)
345
346
[12215]347class DocumentTriggerTransitionFormPage(IkobaEditFormPage):
348    """ View to trigger public document transitions
349    """
350    grok.context(IPublicDocument)
351    grok.name('trigtrans')
352    grok.require('waeup.triggerTransition')
353    grok.template('trigtrans')
354    label = _('Trigger document transition')
355    pnav = 2
356
357    def update(self):
358        return super(IkobaEditFormPage, self).update()
359
360    def getTransitions(self):
361        """Return a list of dicts of allowed transition ids and titles.
362
363        Each list entry provides keys ``name`` and ``title`` for
364        internal name and (human readable) title of a single
365        transition.
366        """
367        wf_info = IWorkflowInfo(self.context)
368        allowed_transitions = [t for t in wf_info.getManualTransitions()]
369        return [dict(name='', title=_('No transition'))] +[
370            dict(name=x, title=y) for x, y in allowed_transitions]
371
[12246]372    @action(_('Apply now'), style='primary')
373    def apply(self, **data):
[12215]374        form = self.request.form
375        if 'transition' in form and form['transition']:
376            transition_id = form['transition']
377            wf_info = IWorkflowInfo(self.context)
378            try:
379                wf_info.fireTransition(transition_id)
[12246]380                self.flash(_("Transition '%s' executed." % transition_id))
[12215]381            except InvalidTransitionError, error:
382                self.flash(error, type="warning")
[12246]383            self.redirect(self.url(self.context))
[12215]384        return
Note: See TracBrowser for help on using the repository browser.