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