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

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

Import message factory from interfaces

  • Property svn:keywords set to Id
File size: 10.7 KB
Line 
1## $Id: browser.py 7693 2012-02-23 17:28:45Z 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
39from waeup.sirp.interfaces import MessageFactory as _
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.