## $Id: browser.py 7257 2011-12-03 05:56:47Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## """UI components for hostels and related components. """ import grok import sys from waeup.sirp.browser import ( WAeUPEditFormPage, WAeUPAddFormPage, WAeUPDisplayFormPage, NullValidator) from waeup.sirp.browser.breadcrumbs import Breadcrumb from waeup.sirp.browser.resources import datepicker, datatable, tabs from waeup.sirp.browser.layout import default_primary_nav_template from waeup.sirp.browser.pages import delSubobjects from waeup.sirp.browser.viewlets import ( ManageActionButton, PrimaryNavTab) from waeup.sirp.interfaces import IWAeUPObject from waeup.sirp.hostels.vocabularies import NOT_OCCUPIED from waeup.sirp.hostels.hostel import Hostel from waeup.sirp.hostels.interfaces import ( IHostelsContainer, IHostel, IBed, IBedAllocateStudent) def write_log_message(view, message): ob_class = view.__implemented__.__name__.replace('waeup.sirp.','') view.context.loggerInfo(ob_class, message) return # Save function used for save methods in manager pages def msave(view, **data): changed_fields = view.applyData(view.context, **data) # Turn list of lists into single list if changed_fields: changed_fields = reduce(lambda x,y: x+y, changed_fields.values()) fields_string = ' + '.join(changed_fields) view.context._p_changed = True view.flash('Form has been saved.') if fields_string: write_log_message(view, 'saved: % s' % fields_string) return class HostelsTab(PrimaryNavTab): """Hostels tab in primary navigation. """ grok.context(IWAeUPObject) grok.order(5) grok.require('waeup.viewHostels') template = default_primary_nav_template pnav = 5 tab_title = u'Hostels' @property def link_target(self): return self.view.application_url('hostels') class HostelsBreadcrumb(Breadcrumb): """A breadcrumb for the hostels container. """ grok.context(IHostelsContainer) title = u'Hostels' class HostelBreadcrumb(Breadcrumb): """A breadcrumb for the hostel container. """ grok.context(IHostel) def title(self): return self.context.hostel_name class BedBreadcrumb(Breadcrumb): """A breadcrumb for the hostel container. """ grok.context(IBed) def title(self): co = self.context.getBedCoordinates() return 'Block %s, Room %s, Bed %s' % (co[1], co[2], co[3]) class HostelsContainerPage(WAeUPDisplayFormPage): """The standard view for hostels containers. """ grok.context(IHostelsContainer) grok.name('index') grok.require('waeup.viewHostels') grok.template('containerpage') label = 'Accommodation Section' title = 'Hostels' pnav = 5 class HostelsContainerManageActionButton(ManageActionButton): grok.order(1) grok.context(IHostelsContainer) grok.view(HostelsContainerPage) grok.require('waeup.manageHostels') text = 'Manage accommodation section' class HostelsContainerManagePage(WAeUPDisplayFormPage): """The manage page for hostel containers. """ grok.context(IHostelsContainer) grok.name('manage') grok.require('waeup.manageHostels') grok.template('containermanagepage') pnav = 5 title = 'Hostels' label = 'Manage accommodation section' # It's quite dangerous to remove entire hostels with its content (beds). # Thus, this remove method should be combined with an archiving function. @grok.action('Remove selected') def delHostels(self, **data): form = self.request.form if form.has_key('val_id'): deleted = [] child_id = form['val_id'] if not isinstance(child_id, list): child_id = [child_id] for id in child_id: deleted.append(id) write_log_message(self, 'deleted: % s' % ', '.join(deleted)) delSubobjects(self, redirect='@@manage', tab='2') return @grok.action('Add hostel', validator=NullValidator) def addSubunit(self, **data): self.redirect(self.url(self.context, 'addhostel')) return class HostelAddFormPage(WAeUPAddFormPage): """Add-form to add a hostel. """ grok.context(IHostelsContainer) grok.require('waeup.manageHostels') grok.name('addhostel') #grok.template('hosteladdpage') form_fields = grok.AutoFields(IHostel) title = 'Hostels' label = 'Add hostel' pnav = 5 @grok.action('Create hostel') def addHostel(self, **data): hostel = Hostel() self.applyData(hostel, **data) hostel.hostel_id = data[ 'hostel_name'].lower().replace(' ','-').replace('_','-') try: self.context.addHostel(hostel) except KeyError: self.flash('The hostel already exists.') return self.flash('Hostel created.') write_log_message(self, 'added: % s' % data['hostel_name']) self.redirect(self.url(self.context[hostel.hostel_id], 'index')) return class HostelDisplayFormPage(WAeUPDisplayFormPage): """ Page to display hostel data """ grok.context(IHostel) grok.name('index') grok.require('waeup.viewHostels') #grok.template('hostelpage') pnav = 5 @property def label(self): return self.context.hostel_name @property def title(self): return self.context.hostel_name class HostelManageActionButton(ManageActionButton): grok.order(1) grok.context(IHostel) grok.view(HostelDisplayFormPage) grok.require('waeup.manageHostels') text = 'Manage' target = 'manage' class HostelManageFormPage(WAeUPEditFormPage): """ View to edit hostel data """ grok.context(IHostel) grok.name('manage') grok.require('waeup.manageHostels') form_fields = grok.AutoFields(IHostel).omit('hostel_id') grok.template('hostelmanagepage') label = 'Manage hostel' pnav = 5 taboneactions = ['Save'] tabtwoactions = ['Update all beds', 'Switch reservation of selected beds', 'Release selected beds'] not_occupied = NOT_OCCUPIED @property def title(self): return self.context.hostel_name @property def students_url(self): return self.url(grok.getSite(),'students') def update(self): datepicker.need() # Enable jQuery datepicker in date fields. tabs.need() datatable.need() super(HostelManageFormPage, self).update() return @grok.action('Save') def save(self, **data): msave(self, **data) return @grok.action('Update all beds') def updateBeds(self, **data): removed, added, modified, modified_beds = self.context.updateBeds() message = '%d empty beds removed, %d beds added, %d occupied beds modified (%s)' % ( removed, added, modified, modified_beds) self.flash(message) write_log_message(self, message) self.redirect(self.url(self.context, '@@manage')+'#tab-2') return @grok.action('Switch reservation of selected beds') def switchReservations(self, **data): form = self.request.form if form.has_key('val_id'): child_id = form['val_id'] else: self.flash('No item selected.') self.redirect(self.url(self.context, '@@manage')+'#tab-2') return if not isinstance(child_id, list): child_id = [child_id] switched = [] for bed_id in child_id: try: message = self.context[bed_id].switchReservation() switched.append('%s (%s)' % (bed_id,message)) except: self.flash('Could not switch %s: %s: %s' % ( id, sys.exc_info()[0], sys.exc_info()[1])) self.redirect(self.url(self.context, '@@manage')+'#tab-2') return if len(switched): message = ', '.join(switched) self.flash('Successfully switched beds: %s' % message) write_log_message(self, 'switched: %s' % message) self.redirect(self.url(self.context, '@@manage')+'#tab-2') return @grok.action('Release selected beds') def releaseBeds(self, **data): form = self.request.form if form.has_key('val_id'): child_id = form['val_id'] else: self.flash('No item selected.') self.redirect(self.url(self.context, '@@manage')+'#tab-2') return if not isinstance(child_id, list): child_id = [child_id] released = [] for bed_id in child_id: message = self.context[bed_id].releaseBed() if message: released.append('%s (%s)' % (bed_id,message)) if len(released): message = ', '.join(released) self.flash('Successfully released beds: %s' % message) write_log_message(self, 'released: %s' % message) self.redirect(self.url(self.context, '@@manage')+'#tab-2') else: self.flash('No allocated bed selected.') self.redirect(self.url(self.context, '@@manage')+'#tab-2') return class BedManageFormPage(WAeUPEditFormPage): """ View to edit bed data """ grok.context(IBedAllocateStudent) grok.name('index') grok.require('waeup.manageHostels') form_fields = grok.AutoFields(IBedAllocateStudent).omit( 'bed_id').omit('bed_number').omit('bed_type') label = 'Allocate student' pnav = 5 @property def title(self): co = self.context.getBedCoordinates() return '%s, Block %s, Room %s, Bed %s' % ( self.context.__parent__.hostel_name, co[1], co[2], co[3]) @grok.action('Save') def save(self, **data): msave(self, **data) self.redirect(self.url(self.context.__parent__, '@@manage')+'#tab-2') return def update(self): if self.context.owner != NOT_OCCUPIED: # Don't use this form for exchanging students. # Beds must be released first before they can be allocated to # other students. self.redirect(self.url(self.context.__parent__, '@@manage')+'#tab-2') return