Revision: 2294
          http://mrbs.svn.sourceforge.net/mrbs/?rev=2294&view=rev
Author:   cimorrison
Date:     2012-04-17 18:34:36 +0000 (Tue, 17 Apr 2012)
Log Message:
-----------
Added support for setting limits on the maximum number of bookings that can be 
made per week, month, year and for any time in the future (day is already 
there).   These are global settings, ie they count the total number of bookings 
over the whole system.   Coming soon (?) the ability to set these limits on a 
per-area basis, as well as globally.

Modified Paths:
--------------
    mrbs/trunk/web/functions.inc
    mrbs/trunk/web/functions_table.inc
    mrbs/trunk/web/lang.en
    mrbs/trunk/web/mrbs_sql.inc
    mrbs/trunk/web/systemdefaults.inc.php

Modified: mrbs/trunk/web/functions.inc
===================================================================
--- mrbs/trunk/web/functions.inc        2012-04-17 12:11:35 UTC (rev 2293)
+++ mrbs/trunk/web/functions.inc        2012-04-17 18:34:36 UTC (rev 2294)
@@ -1198,6 +1198,17 @@
 } // end make_room_select_html
 
 
+// returns the numeric day of the week (0-6) in terms of the MRBS week as 
defined by 
+// $weekstarts.   For example if $weekstarts is set to 2 (Tuesday) and a $time 
for
+// a Wednesday is given, then 1 is returned.
+function day_of_MRBS_week($time)
+{
+  global $weekstarts;
+  
+  return (date('w', $time) - $weekstarts + 7) % 7;
+}
+
+
 // This will return the appropriate value for isdst for mktime().
 // The order of the arguments was chosen to match those of mktime.
 // hour is added so that this function can when necessary only be

Modified: mrbs/trunk/web/functions_table.inc
===================================================================
--- mrbs/trunk/web/functions_table.inc  2012-04-17 12:11:35 UTC (rev 2293)
+++ mrbs/trunk/web/functions_table.inc  2012-04-17 18:34:36 UTC (rev 2294)
@@ -983,7 +983,7 @@
   
   // Calculate how many days to skip back to get to the start of the week
   $time = mktime(12, 0, 0, $month, $day, $year);
-  $skipback = (date("w", $time) - $weekstarts + 7) % 7;
+  $skipback = day_of_MRBS_week($time);
   $day_start_week = $day - $skipback;
   // We will use $day for links and $day_start_week for anything to do with 
showing the bookings,
   // because we want the booking display to start on the first day of the week 
(eg Sunday if $weekstarts is 0)

Modified: mrbs/trunk/web/lang.en
===================================================================
--- mrbs/trunk/web/lang.en      2012-04-17 12:11:35 UTC (rev 2293)
+++ mrbs/trunk/web/lang.en      2012-04-17 18:34:36 UTC (rev 2294)
@@ -179,7 +179,11 @@
 $vocab["min_time_before"]         = "The minimum interval between now and the 
start of a booking is";
 $vocab["max_time_before"]         = "The maximum interval between now and the 
end of a booking is";
 $vocab["max_booking_duration"]    = "The maximum duration of a booking is";
-$vocab["max_n_per_day_global"]    = "The maximum number of bookings per day 
per user across the whole system is";
+$vocab["max_per_day_global"]      = "The maximum number of bookings per day 
per user across the whole system is";
+$vocab["max_per_week_global"]     = "The maximum number of bookings per week 
per user across the whole system is";
+$vocab["max_per_month_global"]    = "The maximum number of bookings per month 
per user across the whole system is";
+$vocab["max_per_year_global"]     = "The maximum number of bookings per year 
per user across the whole system is";
+$vocab["max_per_future_global"]   = "The maximum number of outstanding 
bookings per user across the whole system is";
 $vocab["skip_and_book"]           = "Skip and book";
 $vocab["skip_and_book_note"]      = "Carry on with the booking, skipping past 
the conflicting entries";
 

Modified: mrbs/trunk/web/mrbs_sql.inc
===================================================================
--- mrbs/trunk/web/mrbs_sql.inc 2012-04-17 12:11:35 UTC (rev 2293)
+++ mrbs/trunk/web/mrbs_sql.inc 2012-04-17 18:34:36 UTC (rev 2294)
@@ -1,6 +1,8 @@
 <?php
 // $Id$
 
+define('INTERVAL_DAY', 0);
+
 /** mrbsCheckFree()
  * 
  * Check to see if the time period specified is free
@@ -93,6 +95,101 @@
   return $err;
 }
 
+
+// Checks whether the proposed booking $booking would exceed the maximum 
number of
+// bookings in the interval of type $interval_type (can be 'day', 'week', 
'month' or
+// 'year').   Returns NULL if OK, otherwise an error string.
+function checkInterval(&$booking, $interval_type='day')
+{
+  global $max_per_interval_global;
+  global $tbl_entry;
+  
+  // Set up arrays recording the number of existing and proposed bookings for 
the interval,
+  // indexed by the interval type and the Unix time at the start of that 
interval.  These 
+  // are static variables because we test all the proposed bookings, which 
could be for
+  // multiple rooms and/or for repeat bookings, before making the booking. 
+  static $existing = array();
+  static $proposed = array();
+  
+  // Loop through all the intervals in the proposed booking, counting how many 
bookings
+  // already exist for that interval, and incrementing the number of proposed 
bookings
+  // by one
+  $start_date = getdate($booking['start_time']);
+  $i = 1;
+  switch ($interval_type)
+  {
+    case 'day':
+      $interval_start = mktime(0, 0, 0, $start_date['mon'], 
$start_date['mday'], $start_date['year']);
+      break;
+    case 'week':
+      $skipback = day_of_MRBS_week($booking['start_time']);
+      $interval_start = mktime(0, 0, 0, $start_date['mon'], 
$start_date['mday'] - $skipback, $start_date['year']);
+      break;
+    case 'month':
+      $interval_start = mktime(0, 0, 0, $start_date['mon'], 1, 
$start_date['year']);
+      break;
+    case 'year':
+      $interval_start = mktime(0, 0, 0, 1, 1, $start_date['year']);
+      break;
+    case 'future':
+      $interval_start = time();
+      break;
+  }
+  while ($interval_start < $booking['end_time'])
+  {
+    switch ($interval_type)
+    {
+      case 'day':
+        $interval_end = mktime(0, 0, 0, $start_date['mon'], 
$start_date['mday'] + $i, $start_date['year']);
+        break;
+      case 'week':
+        $interval_end = mktime(0, 0, 0, $start_date['mon'], 
$start_date['mday'] + ($i * 7) - $skipback, $start_date['year']);
+        break;
+      case 'month':
+        $interval_end = mktime(0, 0, 0, $start_date['mon'] + $i, 1, 
$start_date['year']);
+        break;
+      case 'year':
+        $interval_end = mktime(0, 0, 0, 1, 1, $start_date['year'] + $i);
+        break;
+      case 'future':
+        $interval_end = PHP_INT_MAX;
+        break;
+    }
+      
+    if (!isset($existing[$interval_type][$interval_start]))
+    {
+      $sql = "SELECT COUNT(*)
+                FROM $tbl_entry
+               WHERE start_time<$interval_end
+                 AND end_time>$interval_start
+                 AND create_by='" . sql_escape($booking['create_by']) . "'";
+      $existing[$interval_type][$interval_start] = sql_query1($sql);
+      if ($existing[$interval_type][$interval_start] < 0)
+      {
+        trigger_error(sql_error(), E_USER_WARNING);
+        fatal_error(FALSE, get_vocab("fatal_db_error"));
+      }
+      $proposed[$interval_type][$interval_start] = 1;
+    }
+    else
+    {
+      $proposed[$interval_type][$interval_start]++;
+    }
+      
+    if (($existing[$interval_type][$interval_start] + 
$proposed[$interval_type][$interval_start]) >
+         $max_per_interval_global[$interval_type])
+    {
+      return get_vocab("max_per_${interval_type}_global") . " 
$max_per_interval_global[$interval_type]";
+    }
+      
+    $interval_start = $interval_end;
+    $i++;
+  }
+  
+  return NULL;
+}
+
+
 /** mrbsCheckPolicy()
  * 
  * Check to see if a proposed booking conforms to any booking policies in 
force.,
@@ -114,8 +211,7 @@
   global $min_book_ahead_enabled, $min_book_ahead_secs;
   global $max_book_ahead_enabled, $max_book_ahead_secs;
   global $max_duration_enabled, $max_duration_secs, $max_duration_periods;
-  global $max_n_per_day_global_enabled, $max_n_per_day_global;
-  global $tbl_entry;
+  global $max_per_interval_global_enabled;
 
   $errors = array();
   $secs_in_day = 60*60*24;
@@ -193,56 +289,18 @@
     }
   }
   
-  // Check max number of bookings allowed per day for this user
-  if ($max_n_per_day_global_enabled)
+  // Check max number of bookings allowed per interval for this user for each 
of
+  // the interval types
+  foreach (array('day', 'week', 'month', 'year', 'future') as $interval_type)
   {
-    // Set up arrays recording the number of existing and proposed bookings 
for a day,
-    // indexed by the Unix time at the start of that day.  These are static 
variables
-    // because we test all the proposed bookings, which could be for multiple 
rooms,
-    // before making the booking.   (In theory, if MRBS ever supports repeats 
with a granularity
-    // of less than a day, eg repeating every hour, then there could also be 
multiple
-    // bookings on the same day).
-    static $existing = array();
-    static $proposed = array();
-    // Loop through all the days in the proposed booking, counting how many 
bookings
-    // already exist for that day, and incrementing the number of proposed 
bookings
-    // by one
-    $start_date = getdate($booking['start_time']);
-    $i = 0;
-    $day_start = mktime(0, 0, 0, $start_date['mon'], $start_date['mday'], 
$start_date['year']);
-    while ($day_start < $booking['end_time'])
+    if (!empty($max_per_interval_global_enabled[$interval_type]) && !$delete)
     {
-      $day_end = mktime(0, 0, 0, $start_date['mon'], $start_date['mday'] + $i 
+ 1, $start_date['year']);
-      
-      if (!isset($existing[$day_start]))
+      $tmp = checkInterval($booking, $interval_type);
+      if (isset($tmp))
       {
-        $sql = "SELECT COUNT(*)
-                  FROM $tbl_entry
-                 WHERE start_time<$day_end
-                   AND end_time>$day_start
-                   AND create_by='" . sql_escape($booking['create_by']) . "'";
-        $existing[$day_start] = sql_query1($sql);
-        if ($existing[$day_start] < 0)
-        {
-          trigger_error(sql_error(), E_USER_WARNING);
-          fatal_error(FALSE, get_vocab("fatal_db_error"));
-        }
-        $proposed[$day_start] = 1;
+        $errors[] = $tmp;
       }
-      else
-      {
-        $proposed[$day_start]++;
-      }
-      
-      if (($existing[$day_start] + $proposed[$day_start]) > 
$max_n_per_day_global)
-      {
-        $errors[] = get_vocab("max_n_per_day_global") . " 
$max_n_per_day_global";
-      }
-      
-      $day_start = $day_end;
-      $i++;
     }
-
   }
   
   return $errors;

Modified: mrbs/trunk/web/systemdefaults.inc.php
===================================================================
--- mrbs/trunk/web/systemdefaults.inc.php       2012-04-17 12:11:35 UTC (rev 
2293)
+++ mrbs/trunk/web/systemdefaults.inc.php       2012-04-17 18:34:36 UTC (rev 
2294)
@@ -238,13 +238,27 @@
 $max_duration_secs = 60*60*2;  // (seconds) - when using "times"
 $max_duration_periods = 2;     // (periods) - when using "periods"
 
-// Set the maximum number of bookings that can be made by any one user.   
These are 
-// global settings, but you can additionally configure per area settings.   
This would
-// allow you to set policies such as allowing a maximum of 2 bookings per day 
in total
-// with a maximum of 1 in Area A.
-$max_n_per_day_global_enabled = FALSE;
-$max_n_per_day_global = 2;  // max 2 bookings per day in total
+// Set the maximum number of bookings that can be made by any one user, in an 
interval,
+// which can be a day, week, month or year, or else in the future.  (A week is 
defined
+// by the $weekstarts setting).   These are global settings, but you can 
additionally
+// configure per area settings.   This would allow you to set policies such as 
allowing
+// a maximum of 10 bookings per month in total with a maximum of 1 per day in 
Area A.
+$max_per_interval_global_enabled['day']    = FALSE;
+$max_per_interval_global['day'] = 1;      // max 1 bookings per day in total
 
+$max_per_interval_global_enabled['week']   = FALSE;
+$max_per_interval_global['week'] = 5;     // max 5 bookings per week in total
+
+$max_per_interval_global_enabled['month']  = FALSE;
+$max_per_interval_global['month'] = 10;   // max 10 bookings per month in total
+
+$max_per_interval_global_enabled['year']   = FALSE;
+$max_per_interval_global['year'] = 50;    // max 50 bookings per year in total
+
+$max_per_interval_global_enabled['future'] = FALSE;
+$max_per_interval_global['future'] = 100; // max 100 bookings in the future in 
total
+
+
 /******************
  * Display settings
  ******************/

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits

Reply via email to