source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser.py @ 5876

Last change on this file since 5876 was 5861, checked in by uli, 14 years ago

Make also containers available to ApplicationsPage? template.

File size: 11.3 KB
Line 
1##
2## browser.py
3## Login : <uli@pu.smp.net>
4## Started on  Sun Jun 27 11:03:10 2010 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2010 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""UI components for basic applicants and related components.
23"""
24import grok
25
26from datetime import datetime
27from hurry.jquery import jquery
28from hurry.jqueryui import jqueryui
29from zope.component import getUtility, getAllUtilitiesRegisteredFor
30from zope.formlib.widgets import FileWidget, DateWidget
31from waeup.sirp.browser import (
32    WAeUPPage, WAeUPEditFormPage, WAeUPAddFormPage,
33    WAeUPDisplayFormPage, NullValidator)
34from waeup.sirp.browser.pages import LoginPage
35from waeup.sirp.interfaces import IWAeUPObject
36from waeup.sirp.browser.resources import datepicker
37from waeup.sirp.browser.viewlets import (
38    AddActionButton, ManageActionButton, PrimaryNavTab,
39    )
40from waeup.sirp.browser.breadcrumbs import Breadcrumb
41from waeup.sirp.applicants import get_applicant_data, ResultEntry
42from waeup.sirp.applicants.interfaces import (
43    IApplicant, IApplicantPrincipal, IApplicantPDEEditData,
44    IApplicantsRoot, IApplicantsContainer, IApplicantsContainerProvider,
45    )
46from waeup.sirp.widgets.passportwidget import (
47    PassportWidget, PassportDisplayWidget
48    )
49#from zope.formlib.objectwidget import ObjectWidget
50from zope.formlib.sequencewidget import ListSequenceWidget, SequenceDisplayWidget
51from zope.formlib.widget import CustomWidgetFactory
52from waeup.sirp.utils.helpers import ReST2HTML
53from waeup.sirp.widgets.objectwidget import (
54    WAeUPObjectWidget, WAeUPObjectDisplayWidget)
55from waeup.sirp.widgets.multilistwidget import (
56    MultiListWidget, MultiListDisplayWidget)
57from waeup.sirp.image.browser.widget import (
58    ThumbnailWidget, EncodingImageFileWidget,
59    )
60
61results_widget = CustomWidgetFactory(
62    WAeUPObjectWidget, ResultEntry)
63
64results_display_widget = CustomWidgetFactory(
65    WAeUPObjectDisplayWidget, ResultEntry)
66
67#list_results_widget = CustomWidgetFactory(
68#    ListSequenceWidget, subwidget=results_widget)
69
70list_results_widget = CustomWidgetFactory(
71    MultiListWidget, subwidget=results_widget)
72
73list_results_display_widget = CustomWidgetFactory(
74    MultiListDisplayWidget, subwidget=results_display_widget)
75
76#: A date widget that renders with CSS class `datepicker` thus
77#  enabling : the jQuery datepicker for this field if the form loaded
78#  the jQuery code.
79FriendlyDateWidget = CustomWidgetFactory(
80    DateWidget, cssClass='datepicker')
81
82class ApplicationsPage(WAeUPPage):
83    grok.context(IApplicantsRoot)
84    grok.name('index')
85    title = 'Applicants'
86    pnav = 3
87   
88    def getApplications(self):
89        """Get a list of all stored applicant containers.
90        """
91        for key, val in self.context.items():
92            url = self.url(val)
93            yield(dict(url=url, name=key, container=val))
94
95class ManageApplicantsRootActionButton(ManageActionButton):
96    grok.context(IApplicantsRoot)
97    grok.view(ApplicationsPage)
98    text = 'Manage applicant containers'
99
100class ApplicantsRootEditPage(WAeUPPage):
101    grok.context(IApplicantsRoot)
102    grok.name('manage')
103    grok.template('applicantsrooteditpage')
104    title = 'Edit applicants containers'
105    pnav = 3
106
107    def update(self, entries=None, DELETE=None, CANCEL=None):
108        if CANCEL is not None:
109            self.redirect(self.url(self.context))
110            return
111        if DELETE is None:
112            return
113        if entries is None:
114            return
115        if not isinstance(entries, list):
116            entries = [entries]
117        for name in entries:
118            del self.context[name]
119            self.flash('Deleted "%s"' % name)
120        return
121
122    def getApplications(self):
123        """Get a list of all stored applicant containers.
124        """
125        for key, val in self.context.items():
126            url = self.url(val)
127            yield(dict(url=url, name=key))
128
129class AddApplicantsContainerActionButton(AddActionButton):
130    grok.context(IApplicantsRoot)
131    grok.view(ApplicantsRootEditPage)
132    text = 'Add applicants container'
133
134class AddApplicantsContainer(WAeUPPage):
135    grok.context(IApplicantsRoot)
136    grok.name('add')
137    grok.template('addcontainer')
138    title = 'Add applicants container'
139    pnav = 3
140
141    def update(self, providername=None, name=None, title=None,
142               description=None, ADD=None, CANCEL=None):
143        if CANCEL is not None:
144            self.redirect(self.url(self.context))
145            return
146        if ADD is None:
147            return
148        if not name:
149            self.flash('Error: you must give a name')
150            return
151        if name in self.context.keys():
152            self.flash('A container of the given name already exists')
153            return
154        # Add new applicants container...
155        provider = getUtility(IApplicantsContainerProvider,
156                              name=providername)
157        container = provider.factory()
158        container.name = name
159        if title:
160            container.title = title
161        if description:
162            container.description = description
163        self.context[name] = container
164        self.flash('Added "%s".' % name)
165        self.redirect(self.url(self.context))
166        return
167       
168    def getContainerProviders(self):
169        """Get a list of applicants container providers.
170
171        Applicants container providers are named utilities that help
172        to create applicants containers of different types
173        (JAMB-based, non-JAMB-based, etc.).
174
175        The list returned contains dicts::
176
177          {'name': <utility_name>,
178           'provider': <provider instance>}
179
180        where `utility_name` is the name under which the respective
181        provider utility is registered and `provider` is the real
182        provider instance.
183
184        The `utility_name` can be used to lookup the utility anew (for
185        instance after submitting a form) and the `provider` instance
186        can be used to create new instances of the respective
187        applicants container type.
188        """
189        providers = getAllUtilitiesRegisteredFor(IApplicantsContainerProvider)
190        result = [
191            {'name': getattr(x, 'grokcore.component.directive.name'),
192             'provider': x}
193             for x in providers
194            ]
195        return result
196
197class ApplicantsRootBreadcrumb(Breadcrumb):
198    """A breadcrumb for applicantsroot.
199    """
200    grok.context(IApplicantsRoot)
201    title = u'Applicants'
202   
203class ApplicantsContainerBreadcrumb(Breadcrumb):
204    """A breadcrumb for applicantscontainers.
205    """
206    grok.context(IApplicantsContainer)
207
208class ApplicantsTab(PrimaryNavTab):
209    """Faculties-tab in primary navigation.
210    """
211    grok.context(IWAeUPObject)
212    grok.order(3)
213    grok.require('waeup.View')
214    grok.template('primarynavtab')
215
216    pnav = 3
217    tab_title = u'Applicants'
218
219    @property
220    def link_target(self):
221        return self.view.application_url('applicants')
222
223class ApplicantsContainerPage(WAeUPPage):
224    """The standard view for regular applicant containers.
225    """
226    grok.context(IApplicantsContainer)
227    grok.name('index')
228    pnav = 3
229   
230    @property
231    def title(self):
232        return "Applicants Container: %s" % getattr(
233            self.context, '__name__', 'unnamed')
234
235    @property
236    def label(self):
237        return self.title
238
239    def descriptionToHTML(self):
240        return ReST2HTML(self.context.description)
241
242class ManageApplicantsContainerActionButton(ManageActionButton):
243    grok.context(IApplicantsContainer)
244    grok.view(ApplicantsContainerPage)
245    text = 'Manage'
246
247
248class ManageApplicantsContainer(WAeUPEditFormPage):
249    grok.context(IApplicantsContainer)
250    grok.name('manage')
251    form_fields = grok.AutoFields(IApplicantsContainer)
252    # Use friendlier date widget...
253    form_fields['startdate'].custom_widget = FriendlyDateWidget
254    form_fields['enddate'].custom_widget = FriendlyDateWidget
255
256    @property
257    def title(self):
258        return "Manage applicants container: %s" % getattr(
259            self.context, '__name__', 'unnamed')
260   
261    @property
262    def label(self):
263        return self.title
264
265    pnav = 3
266
267    def update(self):
268        datepicker.need() # Enable jQuery datepicker in date fields.
269        return super(ManageApplicantsContainer, self).update()
270
271    @grok.action('Save')
272    def apply(self, **data):
273        self.applyData(self.context, **data)
274        self.flash('Data saved.')
275        return
276       
277    @grok.action('Back')
278    def cancel(self, **data):
279        self.redirect(self.url(self.context))
280        return
281   
282#class AddApplicant(WAeUPAddFormPage):
283#    grok.context(IApplicantsContainer)
284#    grok.name('add')
285#    form_fields = grok.AutoFields(IApplicant)
286#    form_fields['fst_sit_results'].custom_widget = list_results_widget
287#    form_fields['passport'].custom_widget = EncodingImageFileWidget
288#    label = 'Add Applicant'
289#    title = 'Add Applicant'
290#    pnav = 1
291#
292#    @grok.action('Add applicant')
293#    def addApplicant(self, **data):
294#        from waeup.sirp.jambtables.applicants import Applicant
295#        applicant = Applicant()
296#        self.applyData(applicant, **data)
297#        # XXX: temporarily disabled.
298#        #self.context[applicant.reg_no] = applicant
299#        try:
300#            self.context[applicant.access_code] = applicant
301#        except KeyError:
302#            self.flash('The given access code is already in use!')
303#            return
304#        self.redirect(self.url(self.context))
305
306class DisplayApplicant(WAeUPDisplayFormPage):
307    grok.context(IApplicant)
308    grok.name('index')
309    form_fields = grok.AutoFields(IApplicant)
310    form_fields['fst_sit_results'].custom_widget = list_results_display_widget
311    #form_fields['passport'].custom_widget = PassportDisplayWidget
312    form_fields['passport'].custom_widget = ThumbnailWidget
313    label = 'Applicant'
314    title = 'Applicant'
315    pnav = 3
316
317class EditApplicant(WAeUPEditFormPage):
318    grok.context(IApplicant)
319    grok.name('edit')
320    form_fields = grok.AutoFields(IApplicantPDEEditData)
321    #form_fields['passport'].custom_widget = FileWidget
322    #form_fields['passport'].custom_widget = PassportWidget
323    form_fields['passport'].custom_widget = EncodingImageFileWidget
324    grok.template('form_edit_pde')
325
326    def update(self):
327        super(EditApplicant, self).update()
328        print self.request.form
329        return
330   
331    @property
332    def label(self):
333        # XXX: Use current/upcoming session
334        return 'Apply for Post UDE Screening Test (2009/2010)'
335    title = 'Edit Application'
336    pnav = 3
337
338    @grok.action('Save')
339    def save(self, **data):
340        self.applyData(self.context, **data)
341        self.context._p_changed = True
342        return
343
344    @grok.action('Final Submit')
345    def finalsubmit(self, **data):
346        self.applyData(self.context, **data)
347        self.context._p_changed = True
348        # XXX: Lock the form for editing...
349        return
Note: See TracBrowser for help on using the repository browser.