source: main/waeup.sirp/branches/henrik-bootstrap/src/waeup/sirp/hostels/browser.py @ 10009

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

Backup

  • Property svn:keywords set to Id
File size: 10.9 KB
RevLine 
[7195]1## $Id: browser.py 7447 2012-01-10 21:38:44Z henrik $
2##
[6953]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
[6973]21import sys
[6953]22from waeup.sirp.browser import (
[7321]23    SIRPEditFormPage, SIRPAddFormPage, SIRPDisplayFormPage,
[6959]24    NullValidator)
[6953]25from waeup.sirp.browser.breadcrumbs import Breadcrumb
[7332]26from waeup.sirp.browser.resources import datepicker, datatable, tabs, warning
[7243]27from waeup.sirp.browser.layout import default_primary_nav_template
28from waeup.sirp.browser.pages import delSubobjects
[6953]29from waeup.sirp.browser.viewlets import (
[7257]30    ManageActionButton, PrimaryNavTab)
[7447]31from waeup.sirp.browser.layout import jsaction, action
[7321]32from waeup.sirp.interfaces import ISIRPObject
[7068]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)
[6953]37
[6956]38def write_log_message(view, message):
39    ob_class = view.__implemented__.__name__.replace('waeup.sirp.','')
40    view.context.loggerInfo(ob_class, message)
41    return
[6953]42
[6956]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
[6953]56class HostelsTab(PrimaryNavTab):
57    """Hostels tab in primary navigation.
58    """
59
[7321]60    grok.context(ISIRPObject)
[6953]61    grok.order(5)
62    grok.require('waeup.viewHostels')
[7243]63    template = default_primary_nav_template
[6953]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
[6959]82    def title(self):
83        return self.context.hostel_name
84
[7068]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
[7321]94class HostelsContainerPage(SIRPDisplayFormPage):
[6953]95    """The standard view for hostels containers.
96    """
97    grok.context(IHostelsContainer)
98    grok.name('index')
99    grok.require('waeup.viewHostels')
[6959]100    grok.template('containerpage')
[6953]101    label = 'Accommodation Section'
[6959]102    title = 'Hostels'
[6953]103    pnav = 5
104
105class HostelsContainerManageActionButton(ManageActionButton):
106    grok.order(1)
107    grok.context(IHostelsContainer)
108    grok.view(HostelsContainerPage)
109    grok.require('waeup.manageHostels')
110    text = 'Manage accommodation section'
111
[7321]112class HostelsContainerManagePage(SIRPDisplayFormPage):
[6953]113    """The manage page for hostel containers.
114    """
115    grok.context(IHostelsContainer)
116    grok.name('manage')
117    grok.require('waeup.manageHostels')
[6959]118    grok.template('containermanagepage')
[6953]119    pnav = 5
[6959]120    title = 'Hostels'
[6953]121    label = 'Manage accommodation section'
122
[7332]123    def update(self):
124        warning.need()
125        return super(HostelsContainerManagePage, self).update()
126
[6959]127    # It's quite dangerous to remove entire hostels with its content (beds).
[6966]128    # Thus, this remove method should be combined with an archiving function.
[7332]129    @jsaction('Remove selected')
[6959]130    def delHostels(self, **data):
131        form = self.request.form
132        if form.has_key('val_id'):
133            deleted = []
134            child_id = form['val_id']
[6966]135            if not isinstance(child_id, list):
136                child_id = [child_id]
[6959]137            for id in child_id:
138                deleted.append(id)
139            write_log_message(self, 'deleted: % s' % ', '.join(deleted))
140        delSubobjects(self, redirect='@@manage', tab='2')
141        return
[6953]142
[7447]143    @action('Add hostel', validator=NullValidator)
[6959]144    def addSubunit(self, **data):
145        self.redirect(self.url(self.context, 'addhostel'))
146        return
147
[7321]148class HostelAddFormPage(SIRPAddFormPage):
[6953]149    """Add-form to add a hostel.
150    """
151    grok.context(IHostelsContainer)
152    grok.require('waeup.manageHostels')
153    grok.name('addhostel')
[6970]154    #grok.template('hosteladdpage')
[6953]155    form_fields = grok.AutoFields(IHostel)
[6959]156    title = 'Hostels'
[6953]157    label = 'Add hostel'
158    pnav = 5
159
[7447]160    @action('Create hostel')
[6953]161    def addHostel(self, **data):
[6954]162        hostel = Hostel()
163        self.applyData(hostel, **data)
[6973]164        hostel.hostel_id = data[
165            'hostel_name'].lower().replace(' ','-').replace('_','-')
[6966]166        try:
167            self.context.addHostel(hostel)
168        except KeyError:
169            self.flash('The hostel already exists.')
170            return
[6953]171        self.flash('Hostel created.')
[6959]172        write_log_message(self, 'added: % s' % data['hostel_name'])
[6953]173        self.redirect(self.url(self.context[hostel.hostel_id], 'index'))
174        return
175
[7321]176class HostelDisplayFormPage(SIRPDisplayFormPage):
[6953]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
[6956]185    @property
186    def label(self):
187        return self.context.hostel_name
[6953]188
[6956]189    @property
190    def title(self):
191        return self.context.hostel_name
[6953]192
193class HostelManageActionButton(ManageActionButton):
194    grok.order(1)
195    grok.context(IHostel)
196    grok.view(HostelDisplayFormPage)
197    grok.require('waeup.manageHostels')
198    text = 'Manage'
[6970]199    target = 'manage'
[6953]200
[7321]201class HostelManageFormPage(SIRPEditFormPage):
[6953]202    """ View to edit hostel data
203    """
204    grok.context(IHostel)
[6970]205    grok.name('manage')
[6953]206    grok.require('waeup.manageHostels')
207    form_fields = grok.AutoFields(IHostel).omit('hostel_id')
[6970]208    grok.template('hostelmanagepage')
[6959]209    label = 'Manage hostel'
[6953]210    pnav = 5
[6970]211    taboneactions = ['Save']
[6973]212    tabtwoactions = ['Update all beds',
213        'Switch reservation of selected beds',
214        'Release selected beds']
[6996]215    not_occupied = NOT_OCCUPIED
[6953]216
[6956]217    @property
218    def title(self):
219        return self.context.hostel_name
[6953]220
[6996]221    @property
222    def students_url(self):
223        return self.url(grok.getSite(),'students')
224
[6953]225    def update(self):
226        datepicker.need() # Enable jQuery datepicker in date fields.
[6970]227        tabs.need()
228        datatable.need()
[6953]229        super(HostelManageFormPage, self).update()
230        return
231
[7447]232    @action('Save')
[6953]233    def save(self, **data):
234        msave(self, **data)
235        return
[6970]236
[7447]237    @action('Update all beds')
[6970]238    def updateBeds(self, **data):
[6988]239        removed, added, modified, modified_beds = self.context.updateBeds()
240        message = '%d empty beds removed, %d beds added, %d occupied beds modified (%s)' % (
241            removed, added, modified, modified_beds)
242        self.flash(message)
243        write_log_message(self, message)
[6970]244        self.redirect(self.url(self.context, '@@manage')+'#tab-2')
245        return
[6973]246
[7447]247    @action('Switch reservation of selected beds')
[6974]248    def switchReservations(self, **data):
[6973]249        form = self.request.form
250        if form.has_key('val_id'):
251            child_id = form['val_id']
252        else:
253            self.flash('No item selected.')
254            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
255            return
256        if not isinstance(child_id, list):
257            child_id = [child_id]
258        switched = []
259        for bed_id in child_id:
260            try:
[6988]261                message = self.context[bed_id].switchReservation()
262                switched.append('%s (%s)' % (bed_id,message))
[6973]263            except:
264                self.flash('Could not switch %s: %s: %s' % (
265                        id, sys.exc_info()[0], sys.exc_info()[1]))
266                self.redirect(self.url(self.context, '@@manage')+'#tab-2')
267                return
268        if len(switched):
[6988]269            message = ', '.join(switched)
270            self.flash('Successfully switched beds: %s' % message)
[7042]271            write_log_message(self, 'switched: %s' % message)
[6973]272            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
273        return
274
[7447]275    @action('Release selected beds')
[7042]276    def releaseBeds(self, **data):
277        form = self.request.form
278        if form.has_key('val_id'):
279            child_id = form['val_id']
280        else:
281            self.flash('No item selected.')
282            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
283            return
284        if not isinstance(child_id, list):
285            child_id = [child_id]
286        released = []
287        for bed_id in child_id:
[7068]288            message = self.context[bed_id].releaseBed()
[7070]289            if message:
290                released.append('%s (%s)' % (bed_id,message))
[7042]291        if len(released):
292            message = ', '.join(released)
293            self.flash('Successfully released beds: %s' % message)
294            write_log_message(self, 'released: %s' % message)
295            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
[7070]296        else:
297            self.flash('No allocated bed selected.')
298            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
[7042]299        return
[7068]300
[7321]301class BedManageFormPage(SIRPEditFormPage):
[7068]302    """ View to edit bed data
303    """
304    grok.context(IBedAllocateStudent)
305    grok.name('index')
306    grok.require('waeup.manageHostels')
307    form_fields = grok.AutoFields(IBedAllocateStudent).omit(
308        'bed_id').omit('bed_number').omit('bed_type')
309    label = 'Allocate student'
310    pnav = 5
311
312    @property
313    def title(self):
314        co = self.context.getBedCoordinates()
315        return '%s, Block %s, Room %s, Bed %s' % (
316            self.context.__parent__.hostel_name, co[1], co[2], co[3])
317
[7447]318    @action('Save')
[7068]319    def save(self, **data):
320        msave(self, **data)
321        self.redirect(self.url(self.context.__parent__, '@@manage')+'#tab-2')
322        return
323
324    def update(self):
325        if self.context.owner != NOT_OCCUPIED:
326            # Don't use this form for exchanging students.
327            # Beds must be released first before they can be allocated to
328            # other students.
329            self.redirect(self.url(self.context.__parent__, '@@manage')+'#tab-2')
330        return
Note: See TracBrowser for help on using the repository browser.