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

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

pyflakes

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