source: main/waeup.sirp/trunk/src/waeup/sirp/hostels/browser.py @ 7681

Last change on this file since 7681 was 7674, checked in by Henrik Bettermann, 13 years ago

Implement Language switch in the topbar and add some German translations for demonstration.

  • Property svn:keywords set to Id
File size: 10.7 KB
Line 
1## $Id: browser.py 7674 2012-02-22 08:27: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##
18"""UI components for hostels and related components.
19"""
20import grok
21import sys
22import zope.i18nmessageid
23from waeup.sirp.browser import (
24    SIRPEditFormPage, SIRPAddFormPage, SIRPDisplayFormPage,
25    NullValidator)
26from waeup.sirp.browser.breadcrumbs import Breadcrumb
27from waeup.sirp.browser.resources import datepicker, datatable, tabs, warning
28from waeup.sirp.browser.layout import default_primary_nav_template
29from waeup.sirp.browser.pages import delSubobjects
30from waeup.sirp.browser.viewlets import (
31    ManageActionButton, PrimaryNavTab)
32from waeup.sirp.browser.layout import jsaction, action
33from waeup.sirp.interfaces import ISIRPObject
34from waeup.sirp.hostels.vocabularies import NOT_OCCUPIED
35from waeup.sirp.hostels.hostel import Hostel
36from waeup.sirp.hostels.interfaces import (
37    IHostelsContainer, IHostel, IBed, IBedAllocateStudent)
38
39_ = zope.i18nmessageid.MessageFactory('waeup.sirp')
40
41def write_log_message(view, message):
42    ob_class = view.__implemented__.__name__.replace('waeup.sirp.','')
43    view.context.loggerInfo(ob_class, message)
44    return
45
46# Save function used for save methods in manager pages
47def msave(view, **data):
48    changed_fields = view.applyData(view.context, **data)
49    # Turn list of lists into single list
50    if changed_fields:
51        changed_fields = reduce(lambda x,y: x+y, changed_fields.values())
52    fields_string = ' + '.join(changed_fields)
53    view.context._p_changed = True
54    view.flash('Form has been saved.')
55    if fields_string:
56        write_log_message(view, 'saved: % s' % fields_string)
57    return
58
59class HostelsTab(PrimaryNavTab):
60    """Hostels tab in primary navigation.
61    """
62
63    grok.context(ISIRPObject)
64    grok.order(5)
65    grok.require('waeup.viewHostels')
66    template = default_primary_nav_template
67    pnav = 5
68    tab_title = _(u'Hostels')
69
70    @property
71    def link_target(self):
72        return self.view.application_url('hostels')
73
74class HostelsBreadcrumb(Breadcrumb):
75    """A breadcrumb for the hostels container.
76    """
77    grok.context(IHostelsContainer)
78    title = u'Hostels'
79
80class HostelBreadcrumb(Breadcrumb):
81    """A breadcrumb for the hostel container.
82    """
83    grok.context(IHostel)
84
85    def title(self):
86        return self.context.hostel_name
87
88class BedBreadcrumb(Breadcrumb):
89    """A breadcrumb for the hostel container.
90    """
91    grok.context(IBed)
92
93    def title(self):
94        co = self.context.getBedCoordinates()
95        return 'Block %s, Room %s, Bed %s' % (co[1], co[2], co[3])
96
97class HostelsContainerPage(SIRPDisplayFormPage):
98    """The standard view for hostels containers.
99    """
100    grok.context(IHostelsContainer)
101    grok.name('index')
102    grok.require('waeup.viewHostels')
103    grok.template('containerpage')
104    label = 'Accommodation Section'
105    pnav = 5
106
107class HostelsContainerManageActionButton(ManageActionButton):
108    grok.order(1)
109    grok.context(IHostelsContainer)
110    grok.view(HostelsContainerPage)
111    grok.require('waeup.manageHostels')
112    text = 'Manage accommodation section'
113
114class HostelsContainerManagePage(SIRPDisplayFormPage):
115    """The manage page for hostel containers.
116    """
117    grok.context(IHostelsContainer)
118    grok.name('manage')
119    grok.require('waeup.manageHostels')
120    grok.template('containermanagepage')
121    pnav = 5
122    label = 'Manage accommodation section'
123
124    def update(self):
125        warning.need()
126        return super(HostelsContainerManagePage, self).update()
127
128    # It's quite dangerous to remove entire hostels with its content (beds).
129    # Thus, this remove method should be combined with an archiving function.
130    @jsaction('Remove selected')
131    def delHostels(self, **data):
132        form = self.request.form
133        if form.has_key('val_id'):
134            deleted = []
135            child_id = form['val_id']
136            if not isinstance(child_id, list):
137                child_id = [child_id]
138            for id in child_id:
139                deleted.append(id)
140            write_log_message(self, 'deleted: % s' % ', '.join(deleted))
141        delSubobjects(self, redirect='@@manage', tab='2')
142        return
143
144    @action('Add hostel', validator=NullValidator)
145    def addSubunit(self, **data):
146        self.redirect(self.url(self.context, 'addhostel'))
147        return
148
149class HostelAddFormPage(SIRPAddFormPage):
150    """Add-form to add a hostel.
151    """
152    grok.context(IHostelsContainer)
153    grok.require('waeup.manageHostels')
154    grok.name('addhostel')
155    #grok.template('hosteladdpage')
156    form_fields = grok.AutoFields(IHostel)
157    label = 'Add hostel'
158    pnav = 5
159
160    @action('Create hostel')
161    def addHostel(self, **data):
162        hostel = Hostel()
163        self.applyData(hostel, **data)
164        hostel.hostel_id = data[
165            'hostel_name'].lower().replace(' ','-').replace('_','-')
166        try:
167            self.context.addHostel(hostel)
168        except KeyError:
169            self.flash('The hostel already exists.')
170            return
171        self.flash('Hostel created.')
172        write_log_message(self, 'added: % s' % data['hostel_name'])
173        self.redirect(self.url(self.context[hostel.hostel_id], 'index'))
174        return
175
176class HostelDisplayFormPage(SIRPDisplayFormPage):
177    """ Page to display hostel data
178    """
179    grok.context(IHostel)
180    grok.name('index')
181    grok.require('waeup.viewHostels')
182    #grok.template('hostelpage')
183    pnav = 5
184
185    @property
186    def label(self):
187        return self.context.hostel_name
188
189class HostelManageActionButton(ManageActionButton):
190    grok.order(1)
191    grok.context(IHostel)
192    grok.view(HostelDisplayFormPage)
193    grok.require('waeup.manageHostels')
194    text = 'Manage'
195    target = 'manage'
196
197class HostelManageFormPage(SIRPEditFormPage):
198    """ View to edit hostel data
199    """
200    grok.context(IHostel)
201    grok.name('manage')
202    grok.require('waeup.manageHostels')
203    form_fields = grok.AutoFields(IHostel).omit('hostel_id')
204    grok.template('hostelmanagepage')
205    label = 'Manage hostel'
206    pnav = 5
207    taboneactions = ['Save']
208    tabtwoactions = ['Update all beds',
209        'Switch reservation of selected beds',
210        'Release selected beds']
211    not_occupied = NOT_OCCUPIED
212
213    @property
214    def students_url(self):
215        return self.url(grok.getSite(),'students')
216
217    def update(self):
218        datepicker.need() # Enable jQuery datepicker in date fields.
219        tabs.need()
220        datatable.need()
221        self.tab1 = self.tab2 = ''
222        qs = self.request.get('QUERY_STRING', '')
223        if not qs:
224            qs = 'tab1'
225        setattr(self, qs, 'active')
226        super(HostelManageFormPage, self).update()
227        return
228
229    @action('Save')
230    def save(self, **data):
231        msave(self, **data)
232        return
233
234    @action('Update all beds')
235    def updateBeds(self, **data):
236        removed, added, modified, modified_beds = self.context.updateBeds()
237        message = '%d empty beds removed, %d beds added, %d occupied beds modified (%s)' % (
238            removed, added, modified, modified_beds)
239        self.flash(message)
240        write_log_message(self, message)
241        self.redirect(self.url(self.context, '@@manage')+'?tab2')
242        return
243
244    @action('Switch reservation of selected beds')
245    def switchReservations(self, **data):
246        form = self.request.form
247        if form.has_key('val_id'):
248            child_id = form['val_id']
249        else:
250            self.flash('No item selected.')
251            self.redirect(self.url(self.context, '@@manage')+'?tab2')
252            return
253        if not isinstance(child_id, list):
254            child_id = [child_id]
255        switched = []
256        for bed_id in child_id:
257            try:
258                message = self.context[bed_id].switchReservation()
259                switched.append('%s (%s)' % (bed_id,message))
260            except:
261                self.flash('Could not switch %s: %s: %s' % (
262                        id, sys.exc_info()[0], sys.exc_info()[1]))
263                self.redirect(self.url(self.context, '@@manage')+'?tab2')
264                return
265        if len(switched):
266            message = ', '.join(switched)
267            self.flash('Successfully switched beds: %s' % message)
268            write_log_message(self, 'switched: %s' % message)
269            self.redirect(self.url(self.context, '@@manage')+'?tab2')
270        return
271
272    @action('Release selected beds')
273    def releaseBeds(self, **data):
274        form = self.request.form
275        if form.has_key('val_id'):
276            child_id = form['val_id']
277        else:
278            self.flash('No item selected.')
279            self.redirect(self.url(self.context, '@@manage')+'?tab2')
280            return
281        if not isinstance(child_id, list):
282            child_id = [child_id]
283        released = []
284        for bed_id in child_id:
285            message = self.context[bed_id].releaseBed()
286            if message:
287                released.append('%s (%s)' % (bed_id,message))
288        if len(released):
289            message = ', '.join(released)
290            self.flash('Successfully released beds: %s' % message)
291            write_log_message(self, 'released: %s' % message)
292            self.redirect(self.url(self.context, '@@manage')+'?tab2')
293        else:
294            self.flash('No allocated bed selected.')
295            self.redirect(self.url(self.context, '@@manage')+'?tab2')
296        return
297
298class BedManageFormPage(SIRPEditFormPage):
299    """ View to edit bed data
300    """
301    grok.context(IBedAllocateStudent)
302    grok.name('index')
303    grok.require('waeup.manageHostels')
304    form_fields = grok.AutoFields(IBedAllocateStudent).omit(
305        'bed_id').omit('bed_number').omit('bed_type')
306    label = 'Allocate student'
307    pnav = 5
308
309    @action('Save')
310    def save(self, **data):
311        msave(self, **data)
312        self.redirect(self.url(self.context.__parent__, '@@manage')+'?tab2')
313        return
314
315    def update(self):
316        if self.context.owner != NOT_OCCUPIED:
317            # Don't use this form for exchanging students.
318            # Beds must be released first before they can be allocated to
319            # other students.
320            self.redirect(self.url(self.context.__parent__, '@@manage')+'?tab2')
321        return
Note: See TracBrowser for help on using the repository browser.