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

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

Redirect to specified tabs using the request's QUERY_STRING value. This suboptimal solution will be replaced later by a pure Javascript solution.

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