* fixed conflict check of resource quantity and storage of changed quantity in existing events

(changed quantity was used for conflict check, but not stored!)
There is still a bug with multiple non-overlapping events overlapping the checked event: check is against quantity sum, not the maximum
This commit is contained in:
Ralf Becker 2010-11-11 08:51:13 +00:00
parent c1fea35c29
commit b19c4b3030
2 changed files with 48 additions and 26 deletions

View File

@ -99,10 +99,22 @@ class calendar_boupdate extends calendar_bo
* @param array &$messages=null messages about because of missing ACL removed participants or categories
* @return mixed on success: int $cal_id > 0, on error false or array with conflicting events (only if $check_conflicts)
* Please note: the events are not garantied to be readable by the user (no read grant or private)!
*
* @ToDo current conflict checking code does NOT cope quantity-wise correct with multiple non-overlapping
* events overlapping the event to store: the quantity sum is used, even as the events dont overlap!
*
* ++++++++ ++++++++
* + + + B + If A get checked for conflicts, the check used for resource quantity is
* + + ++++++++
* + A + quantity(A,resource)+quantity(B,resource)+quantity(C,resource) > maxBookable(resource)
* + + ++++++++
* + + + C + which is clearly wrong for everything with a maximum quantity > 1
* ++++++++ ++++++++
*/
function update(&$event,$ignore_conflicts=false,$touch_modified=true,$ignore_acl=false,$updateTS=true,&$messages=null)
{
//error_log(__METHOD__."(".array2string($event).",$ignore_conflicts,$touch_modified,$ignore_acl)");
if ($this->debug > 1 || $this->debug == 'update')
{
$this->debug_message('calendar_boupdate::update(%1,ignore_conflict=%2,touch_modified=%3,ignore_acl=%4)',
@ -265,7 +277,9 @@ class calendar_boupdate extends calendar_bo
$common_parts = array_intersect($users,array_keys($overlap['participants']));
foreach($common_parts as $n => $uid)
{
if ($overlap['participants'][$uid][0] == 'R')
$status = $overlap['participants'][$uid];
calendar_so::split_status($status, $q, $r);
if ($status == 'R')
{
unset($common_parts[$n]);
continue;
@ -279,7 +293,7 @@ class calendar_boupdate extends calendar_bo
$res_info = $this->resource_info($uid);
$max_quantity[$uid] = $res_info[$this->resources[$uid[0]]['max_quantity']];
}
$quantity[$uid] += max(1,(int) substr($overlap['participants'][$uid],2));
$quantity[$uid] += $q;
if ($quantity[$uid] <= $max_quantity[$uid])
{
$possible_quantity_conflicts[$uid][] =& $overlapping_events[$k]; // an other event can give the conflict
@ -857,8 +871,8 @@ class calendar_boupdate extends calendar_bo
*/
function save($event,$ignore_acl=false,$updateTS=true)
{
//echo '<p>'.__METHOD__.'('.array2string($event).",$ignore_acl)</p>\n";
//error_log(__METHOD__.'('.array2string($event).",$etag)");
// check if user has the permission to update / create the event
if (!$ignore_acl && ($event['id'] && !$this->check_perms(EGW_ACL_EDIT,$event['id']) ||
!$event['id'] && !$this->check_perms(EGW_ACL_EDIT,0,$event['owner']) &&

View File

@ -830,7 +830,6 @@ ORDER BY cal_user_type, cal_usre_id
$old_min = $old_duration = 0;
//echo '<p>'.__METHOD__.'('.array2string($event).",$change_since) event="; _debug_array($event);
//error_log(__METHOD__.'('.array2string($event).",$set_recurrences,$change_since,$etag)");
$cal_id = (int) $event['id'];
@ -1262,6 +1261,8 @@ ORDER BY cal_user_type, cal_usre_id
*/
function participants($cal_id,$participants,$change_since=0,$add_only=false)
{
//error_log(__METHOD__."($cal_id,".array2string($participants).",$change_since,$add_only");
$recurrences = array();
// remove group-invitations, they are NOT stored in the db
@ -1312,8 +1313,15 @@ ORDER BY cal_user_type, cal_usre_id
}
}
// only keep added participants for further steps - we do not touch existing ones
$participants = array_diff_key($participants,$old_participants);
// only keep added OR status (incl. quantity!) changed participants for further steps
// we do not touch unchanged (!) existing ones
foreach($participants as $uid => $status)
{
if ($old_participants[$uid] === $status)
{
unset($participants[$uid]);
}
}
// delete participants tagged for delete
if ($add_only === false && count($deleted))