Index: main/waeup.kofa/trunk/CHANGES.txt
===================================================================
--- main/waeup.kofa/trunk/CHANGES.txt	(revision 15246)
+++ main/waeup.kofa/trunk/CHANGES.txt	(revision 15250)
@@ -4,4 +4,7 @@
 1.6.1.dev0 (unreleased)
 =======================
+
+* Add ReleaseExpiredAllocationsActionButton which has previously
+  only been used by Uniben.
 
 * Fix get_student_payment_stats. Department codes are not
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py	(revision 15246)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/browser.py	(revision 15250)
@@ -124,4 +124,31 @@
     target = 'statistics'
 
+class ReleaseExpiredAllocationsActionButton(ManageActionButton):
+    grok.order(3)
+    grok.context(IHostelsContainer)
+    grok.view(HostelsContainerPage)
+    grok.require('waeup.manageHostels')
+    icon = 'actionicon_sweep.png'
+    target = 'releaseexpired'
+    text = _('Release all expired bed space allocations')
+
+    @property
+    def target_url(self):
+        if self.target and self.context.allocation_expiration:
+            return self.view.url(self.view.context, self.target)
+        return
+
+    @property
+    def onclick(self):
+        msg = "'All expired bed space allocations will be annulled. " + \
+              "Are you sure? \\n\\n" + \
+              "Bed space allocation expires ${a} days after accommodation " + \
+              "booking if maintenance fee is not " + \
+              "paid.'"
+        msg = _(msg, mapping={'a': self.context.allocation_expiration,})
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        return "return window.confirm(%s);" % translate(
+            msg, 'waeup.kofa', target_language=portal_language)
+
 class HostelsContainerManagePage(KofaEditFormPage):
     """The manage page for hostel containers.
@@ -190,5 +217,11 @@
     grok.require('waeup.manageHostels')
 
-    def update(self, n=7):
+    def update(self):
+        n = self.context.allocation_expiration
+        if not n:
+            self.flash(
+                _('Forbidden'), type='danger')
+            self.redirect(self.url(self.context))
+            return
         if not grok.getSite()['configuration'].maintmode_enabled_by:
             self.flash(
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py	(revision 15246)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py	(revision 15250)
@@ -73,4 +73,11 @@
         )
 
+    allocation_expiration = schema.Int(
+        title = _(u'Allocation Expiration Time (days)'),
+        description = _(
+            'Number of days after which allocation is being annulled'),
+        required = False,
+        )
+
     def clearAllHostels():
         """Clear all hostels.
Index: main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py	(revision 15246)
+++ main/waeup.kofa/trunk/src/waeup/kofa/hostels/tests.py	(revision 15250)
@@ -188,4 +188,5 @@
 
     def test_release_expired_allocations(self):
+        self.app['hostels'].allocation_expiration = 7
         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
         cat = queryUtility(ICatalog, name='beds_catalog')
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 15246)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 15250)
@@ -2406,8 +2406,23 @@
             self.request, self.omit_fields)
         students_utils = getUtility(IStudentsUtils)
+        note = None
+        n = grok.getSite()['hostels'].allocation_expiration
+        if n:
+            note = """
+<br /><br /><br /><br /><br /><font size="12">
+Please endeavour to pay your hostel maintenance charge within ${a} days
+ of being allocated a space or else you are deemed to have
+ voluntarily forfeited it and it goes back into circulation to be
+ available for booking afresh!</font>
+"""
+            note = _(note, mapping={'a': n})
+            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+            note = translate(
+                note, 'waeup.kofa', target_language=portal_language)
         return students_utils.renderPDF(
             self, 'bed_allocation_slip.pdf',
             self.context.student, studentview,
-            omit_fields=self.omit_fields)
+            omit_fields=self.omit_fields,
+            note=note)
 
 class BedTicketRelocationView(UtilityView, grok.View):
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 15246)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 15250)
@@ -3270,4 +3270,5 @@
         bed.bed_type = u'regular_female_fr'
         self.app['hostels'][hostel.hostel_id].addBed(bed)
+        self.app['hostels'].allocation_expiration = 7
 
         self.browser.open(self.login_path)
@@ -3373,4 +3374,7 @@
         self.assertEqual(self.browser.headers['Status'], '200 Ok')
         self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
+        path = os.path.join(samples_dir(), 'bed_allocation_slip.pdf')
+        open(path, 'wb').write(self.browser.contents)
+        print "Sample PDF bed_allocation_slip.pdf written to %s" % path
         # Students can't relocate themselves.
         self.assertFalse('Relocate' in self.browser.contents)
