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

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

Implement logging for reservation switch.

Fix switchReservation.

Improve testing.

  • Property svn:keywords set to Id
File size: 8.8 KB
RevLine 
[6953]1## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
2## This program is free software; you can redistribute it and/or modify
3## it under the terms of the GNU General Public License as published by
4## the Free Software Foundation; either version 2 of the License, or
5## (at your option) any later version.
6##
7## This program is distributed in the hope that it will be useful,
8## but WITHOUT ANY WARRANTY; without even the implied warranty of
9## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10## GNU General Public License for more details.
11##
12## You should have received a copy of the GNU General Public License
13## along with this program; if not, write to the Free Software
14## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15##
16"""UI components for hostels and related components.
17"""
18import grok
[6973]19import sys
[6953]20from time import time
21from datetime import date, datetime
22from zope.component import createObject
23from waeup.sirp.browser import (
[6959]24    WAeUPPage, WAeUPEditFormPage, WAeUPAddFormPage, WAeUPDisplayFormPage,
25    NullValidator)
[6953]26from waeup.sirp.browser.breadcrumbs import Breadcrumb
[6959]27from waeup.sirp.browser.resources import datepicker, datatable, tabs, toggleall
[6953]28from waeup.sirp.browser.viewlets import (
29    ManageActionButton, PrimaryNavTab, AddActionButton)
30from waeup.sirp.interfaces import IWAeUPObject, IUserAccount
31from waeup.sirp.widgets.datewidget import (
32    FriendlyDateWidget, FriendlyDateDisplayWidget,
33    FriendlyDatetimeDisplayWidget)
[6959]34from waeup.sirp.browser.pages import delSubobjects
[6953]35from waeup.sirp.authentication import get_principal_role_manager
36from waeup.sirp.hostels.container import HostelsContainer
37from waeup.sirp.hostels.hostel import Hostel
38from waeup.sirp.hostels.interfaces import IHostelsContainer, IHostel
39
[6956]40def write_log_message(view, message):
41    ob_class = view.__implemented__.__name__.replace('waeup.sirp.','')
42    view.context.loggerInfo(ob_class, message)
43    return
[6953]44
[6956]45# Save function used for save methods in manager pages
46def msave(view, **data):
47    form = view.request.form
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
[6953]59class HostelsTab(PrimaryNavTab):
60    """Hostels tab in primary navigation.
61    """
62
63    grok.context(IWAeUPObject)
64    grok.order(5)
65    grok.require('waeup.viewHostels')
66    grok.template('primarynavtab')
67
68    pnav = 5
69    tab_title = u'Hostels'
70
71    @property
72    def link_target(self):
73        return self.view.application_url('hostels')
74
75class HostelsBreadcrumb(Breadcrumb):
76    """A breadcrumb for the hostels container.
77    """
78    grok.context(IHostelsContainer)
79    title = u'Hostels'
80
81class HostelBreadcrumb(Breadcrumb):
82    """A breadcrumb for the hostel container.
83    """
84    grok.context(IHostel)
85
[6959]86    def title(self):
87        return self.context.hostel_name
88
[6953]89class HostelsContainerPage(WAeUPDisplayFormPage):
90    """The standard view for hostels containers.
91    """
92    grok.context(IHostelsContainer)
93    grok.name('index')
94    grok.require('waeup.viewHostels')
[6959]95    grok.template('containerpage')
[6953]96    label = 'Accommodation Section'
[6959]97    title = 'Hostels'
[6953]98    pnav = 5
99
100class HostelsContainerManageActionButton(ManageActionButton):
101    grok.order(1)
102    grok.context(IHostelsContainer)
103    grok.view(HostelsContainerPage)
104    grok.require('waeup.manageHostels')
105    text = 'Manage accommodation section'
106
107class HostelsContainerManagePage(WAeUPDisplayFormPage):
108    """The manage page for hostel containers.
109    """
110    grok.context(IHostelsContainer)
111    grok.name('manage')
112    grok.require('waeup.manageHostels')
[6959]113    grok.template('containermanagepage')
[6953]114    pnav = 5
[6959]115    title = 'Hostels'
[6953]116    label = 'Manage accommodation section'
117
[6959]118    # It's quite dangerous to remove entire hostels with its content (beds).
[6966]119    # Thus, this remove method should be combined with an archiving function.
[6959]120    @grok.action('Remove selected')
121    def delHostels(self, **data):
122        form = self.request.form
123        if form.has_key('val_id'):
124            deleted = []
125            child_id = form['val_id']
[6966]126            if not isinstance(child_id, list):
127                child_id = [child_id]
[6959]128            for id in child_id:
129                deleted.append(id)
130            write_log_message(self, 'deleted: % s' % ', '.join(deleted))
131        delSubobjects(self, redirect='@@manage', tab='2')
132        return
[6953]133
[6959]134    @grok.action('Add hostel', validator=NullValidator)
135    def addSubunit(self, **data):
136        self.redirect(self.url(self.context, 'addhostel'))
137        return
138
[6953]139class HostelAddFormPage(WAeUPAddFormPage):
140    """Add-form to add a hostel.
141    """
142    grok.context(IHostelsContainer)
143    grok.require('waeup.manageHostels')
144    grok.name('addhostel')
[6970]145    #grok.template('hosteladdpage')
[6953]146    form_fields = grok.AutoFields(IHostel)
[6959]147    title = 'Hostels'
[6953]148    label = 'Add hostel'
149    pnav = 5
150
151    @grok.action('Create hostel')
152    def addHostel(self, **data):
[6954]153        hostel = Hostel()
154        self.applyData(hostel, **data)
[6973]155        hostel.hostel_id = data[
156            'hostel_name'].lower().replace(' ','-').replace('_','-')
[6966]157        try:
158            self.context.addHostel(hostel)
159        except KeyError:
160            self.flash('The hostel already exists.')
161            return
[6953]162        self.flash('Hostel created.')
[6959]163        write_log_message(self, 'added: % s' % data['hostel_name'])
[6953]164        self.redirect(self.url(self.context[hostel.hostel_id], 'index'))
165        return
166
167class HostelDisplayFormPage(WAeUPDisplayFormPage):
168    """ Page to display hostel data
169    """
170    grok.context(IHostel)
171    grok.name('index')
172    grok.require('waeup.viewHostels')
173    #grok.template('hostelpage')
174    pnav = 5
175
[6956]176    @property
177    def label(self):
178        return self.context.hostel_name
[6953]179
[6956]180    @property
181    def title(self):
182        return self.context.hostel_name
[6953]183
184class HostelManageActionButton(ManageActionButton):
185    grok.order(1)
186    grok.context(IHostel)
187    grok.view(HostelDisplayFormPage)
188    grok.require('waeup.manageHostels')
189    text = 'Manage'
[6970]190    target = 'manage'
[6953]191
192class HostelManageFormPage(WAeUPEditFormPage):
193    """ View to edit hostel data
194    """
195    grok.context(IHostel)
[6970]196    grok.name('manage')
[6953]197    grok.require('waeup.manageHostels')
198    form_fields = grok.AutoFields(IHostel).omit('hostel_id')
[6970]199    grok.template('hostelmanagepage')
[6959]200    label = 'Manage hostel'
[6953]201    pnav = 5
[6970]202    taboneactions = ['Save']
[6973]203    tabtwoactions = ['Update all beds',
204        'Switch reservation of selected beds',
205        'Release selected beds']
[6953]206
[6956]207    @property
208    def title(self):
209        return self.context.hostel_name
[6953]210
211    def update(self):
212        datepicker.need() # Enable jQuery datepicker in date fields.
[6970]213        tabs.need()
214        datatable.need()
[6953]215        super(HostelManageFormPage, self).update()
216        return
217
218    @grok.action('Save')
219    def save(self, **data):
220        msave(self, **data)
221        return
[6970]222
[6973]223    @grok.action('Update all beds')
[6970]224    def updateBeds(self, **data):
[6988]225        removed, added, modified, modified_beds = self.context.updateBeds()
226        message = '%d empty beds removed, %d beds added, %d occupied beds modified (%s)' % (
227            removed, added, modified, modified_beds)
228        self.flash(message)
229        write_log_message(self, message)
[6970]230        self.redirect(self.url(self.context, '@@manage')+'#tab-2')
231        return
[6973]232
233    @grok.action('Switch reservation of selected beds')
[6974]234    def switchReservations(self, **data):
[6973]235        form = self.request.form
236        if form.has_key('val_id'):
237            child_id = form['val_id']
238        else:
239            self.flash('No item selected.')
240            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
241            return
242        if not isinstance(child_id, list):
243            child_id = [child_id]
244        switched = []
245        for bed_id in child_id:
246            try:
[6988]247                message = self.context[bed_id].switchReservation()
248                switched.append('%s (%s)' % (bed_id,message))
[6973]249            except:
250                self.flash('Could not switch %s: %s: %s' % (
251                        id, sys.exc_info()[0], sys.exc_info()[1]))
252                self.redirect(self.url(self.context, '@@manage')+'#tab-2')
253                return
254        if len(switched):
[6988]255            message = ', '.join(switched)
256            self.flash('Successfully switched beds: %s' % message)
257            write_log_message(self, 'switched: % s' % message)
[6973]258            self.redirect(self.url(self.context, '@@manage')+'#tab-2')
259        return
260
[6988]261    # Needed for removing students from beds
262    #@grok.action('Release selected beds')
263    #def releaseBeds(self, **data):
264    #    #self.flash('%d released' % released)
265    #    self.redirect(self.url(self.context, '@@manage')+'#tab-2')
266    #    return
Note: See TracBrowser for help on using the repository browser.