patch #1624 from Regis Leroy: check resource availablity on search and config to deny resource reservation on private events, plus German translation

This commit is contained in:
Ralf Becker 2008-10-10 10:24:31 +00:00
parent 900ee97db1
commit 6ae2813e65
10 changed files with 211 additions and 12 deletions

View File

@ -1792,6 +1792,7 @@ class calendar_bo
'planner_start_with_group' => $planner_start_with_group,
'defaultfilter' => 'all',
'default_private' => '0',
'defaultresource_sel' => 'resources',
);
foreach($defaults as $var => $default)
{

View File

@ -232,6 +232,12 @@ class calendar_hooks
45 => '45',
60 => '60'
);
$defaultresource_sel = array(
'resources_conflict' => lang('resources with conflict detection'),
'resources_without_conflict' => lang('resources except conflicting ones'),
'resources' => lang('resources'),
'addressbook' => lang('addressbook')
);
$groups = $GLOBALS['egw']->accounts->membership($GLOBALS['egw_info']['user']['account_id']);
$options = array('0' => lang('none'));
if (is_array($groups))
@ -351,6 +357,15 @@ class calendar_hooks
'xmlrpc' => True,
'admin' => False
),
'defaultresource_sel' => array(
'type' => 'select',
'label' => 'default type of resources selection',
'name' => 'defaultresource_sel',
'values' => $defaultresource_sel,
'help' => 'Default type of resources application selected in the calendar particpants research form.',
'xmlrpc' => True,
'admin' => False,
),
'planner_start_with_group' => array(
'type' => 'select',
'label' => 'Preselected group for entering the planner',

View File

@ -260,7 +260,14 @@ class calendar_uiforms extends calendar_ui
break;
case 'resource':
list($app,$id) = explode(':',$data);
if (is_array($data) && isset($data['current']) )
{
list($app,$id) = explode(':',$data['current']);
}
else
{
list($app,$id) = explode(':',$data);
}
foreach($this->bo->resources as $type => $data) if ($data['app'] == $app) break;
$uid = $this->bo->resources[$type]['app'] == $app ? $type.$id : false;
// check if new entry is no contact or no account
@ -387,6 +394,19 @@ class calendar_uiforms extends calendar_ui
$button = '';
break;
}
// if private event with ressource reservation is forbidden
if (!$event['public'] && $GLOBALS['egw_info']['server']['no_ressources_private'])
{
foreach ($event['participants'] as $uid => $value)
{
if ($uid[0] == 'r') //ressource detection
{
$msg = lang('Error: ressources reservation in private events is not allowed!!!');
$button = '';
break 2; //break foreach and case
}
}
}
if ($content['edit_single']) // we edited a single event from a series
{
$event['reference'] = $event['id'];
@ -814,7 +834,23 @@ class calendar_uiforms extends calendar_ui
}
// resouces / apps we shedule, atm. resources and addressbook
$content['participants']['cal_resources'] = '';
foreach($this->bo->resources as $data) $content['participants']['cal_resources'] .= ','.$data['app'];
foreach($this->bo->resources as $data)
{
$content['participants']['cal_resources'] .= ','.$data['app'];
}
// adding extra content for the resource link-entry widget to
// * select resources or addressbook as a default selection on the app selectbox based on prefs
$content['participants']['resource']['default_sel'] = $this->cal_prefs['defaultresource_sel'];
// * get informations from the event on the ajax callback
if (in_array($content['participants']['resource']['default_sel'],array('resources_conflict','resources_without_conflict')))
{
// fix real app string
$content['participants']['resource']['default_sel'] = 'resources';
// this will be used to get reservation information on the resource select list
$content['participants']['resource']['extra'] = "values2url(this.form,'start,end,duration,participants,recur_type,whole_day')".
"+'&exec[event_id]=".$content['id']."'"."+'&exec[show_conflict]=".
(($this->cal_prefs['defaultresource_sel'] == 'resources_without_conflict')? '0':'1')."'";
}
}
$content['participants']['status_date'] = $preserv['actual_date'];
$content['participants']['hide_status_recurrence'] = $event['recur_type'] == MCAL_RECUR_NONE;
@ -1203,8 +1239,8 @@ class calendar_uiforms extends calendar_ui
{
echo "<p>ft_start=".date('D d.m.Y H:i',$ft_start)."<br>\n";
echo "event[title]=$event[title]<br>\n";
echo "event[start]=".date('D d.m.Y H:i',$event['start']['raw'])."<br>\n";
echo "event[end]=".date('D d.m.Y H:i',$event['end']['raw'])."<br>\n";
echo "event[start]=".date('D d.m.Y H:i',$event['start'])."<br>\n";
echo "event[end]=".date('D d.m.Y H:i',$event['end'])."<br>\n";
}
// $events ends before our actual position ==> ignore it
if ($event['end'] < $ft_start)

View File

@ -47,6 +47,7 @@ calendar preferences calendar de Kalender Einstellungen
calendar settings admin de Kalender Einstellungen
calendar-fieldname calendar de Kalender Feldname
can't add alarms in the past !!! calendar de Kann keine Alarme in der Vergangenheit setzen !!!
can't aquire lock! calendar de Kann Termin nicht sperren!
canceled calendar de Abgesagt
charset of file calendar de Zeichensatz der Datei
close the window calendar de Schließt das Fenster
@ -72,12 +73,15 @@ default appointment length (in minutes) calendar de Standardlänge eines neuen K
default calendar filter calendar de Standard-Filter des Kalenders
default calendar view calendar de Standard-Ansicht des Kalenders
default length of newly created events. the length is in minutes, eg. 60 for 1 hour. calendar de Vorgabe für die Länge von neuen Kalendereinträgen. Die Länge ist in Minuten, zb. 60 für 1 Stunde.
default type of resources application selected in the calendar particpants research form. calendar de Vorgabe für die gewählte Anwendung bei der Ressourcensuche im Kartenreiter Teilnehmer
default type of resources selection calendar de Vorgabe für die Ressourcensuche
default week view calendar de Vorgabe Wochenansicht
delete series calendar de Serie löschen
delete this alarm calendar de Diesen Alarm löschen
delete this event calendar de Diesen Termin löschen
delete this exception calendar de Diese Ausnahme löschen
delete this series of recuring events calendar de Diese Serie von wiederholenden Terminen löschen
deny ressources reservation for private events calendar de Verbiete die Reservierung von Ressourcen für private Termine
disinvited calendar de Ausgeladen
display status of events calendar de Status von Terminen anzeigen
displayed view calendar de Ansicht
@ -104,6 +108,7 @@ ends calendar de endet
error adding the alarm calendar de Fehler beim Zufügen des Alarms
error: importing the ical calendar de Fehler: beim Importieren des iCal
error: no participants selected !!! calendar de Fehler: keine Teilnehmer ausgewählt !!!
error: ressources reservation in private events is not allowed!!! calendar de Fehler: die Reservierung von Ressourcen für private Termine ist nicht erlaubt !!!
error: saving the event !!! calendar de Fehler: beim Speichern des Termins !!!
error: starttime has to be before the endtime !!! calendar de Fehler: Startzeit muß vor Endzeit liegen !!!
error: the entry has been updated since you opened it for editing! calendar de Fehler: der Eintrag wurde geändert seit Sie ihn zum Bearbeiten geöffnet haben!
@ -247,6 +252,8 @@ repetition calendar de Wiederholung
repetitiondetails (or empty) calendar de Details der Wiederholung (oder leer)
reset calendar de Zurücksetzen
resources calendar de Ressourcen
resources except conflicting ones calendar de Ressourcen ausgenommen bereits gebuchte
resources with conflict detection calendar de Ressourcen mit bereits gebuchten
rule calendar de Regel
sat calendar de Sa
saves the changes made calendar de Speichert die Änderungen
@ -288,6 +295,7 @@ test import (show importable records <u>only</u> in browser) calendar de Test Im
this day is shown as first day in the week or month view. calendar de Dieser Tag wird als erster in der Wochen- oder Monatsansicht angezeigt
this defines the end of your dayview. events after this time, are shown below the dayview. calendar de Diese Zeit definiert das Ende des Arbeitstags in der Tagesansicht. Alle späteren Einträge werden darunter dargestellt.
this defines the start of your dayview. events before this time, are shown above the dayview.<br>this time is also used as a default starttime for new events. calendar de Diese Zeit definiert den Anfang des Arbeitstags in der Tagesansicht. Alle früheren Einträge werden darüber dargestellt.
this entry is currently opened by %1! calendar de Dieser Termin ist im Moment von %1 geöffnet!
this entry is opened by user: calendar de Dieser Eintrag ist von einem anderen Benutzer innerhalb des konfigurierten Zeitintervalls geöffnet worden:
this group that is preselected when you enter the planner. you can change it in the planner anytime you want. calendar de Diese Gruppe wird als vorauswahl ausgewählt wenn Sie den Planer öffnen. Sie können die Gruppe jederzeit wechseln wenn Sie möchten.
this message is sent for canceled or deleted events. calendar de Diese Benachrichtigung wird für stornierte oder gelöschte Termine versandt.

View File

@ -73,12 +73,15 @@ default appointment length (in minutes) calendar en default appointment length (
default calendar filter calendar en Default calendar filter
default calendar view calendar en default calendar view
default length of newly created events. the length is in minutes, eg. 60 for 1 hour. calendar en Default length of newly created events. The length is in minutes, eg. 60 for 1 hour.
default type of resources application selected in the calendar particpants research form. calendar en Default type of resources application selected in the calendar particpants research form.
default type of resources selection calendar en Default type of resources selection
default week view calendar en default week view
delete series calendar en Delete series
delete this alarm calendar en Delete this alarm
delete this event calendar en Delete this event
delete this exception calendar en Delete this exception
delete this series of recuring events calendar en Delete this series of recuring events
deny ressources reservation for private events calendar en Deny Resources reservation for private events
disinvited calendar en Disinvited
display status of events calendar en Display status of events
displayed view calendar en displayed view
@ -105,6 +108,7 @@ ends calendar en ends
error adding the alarm calendar en Error adding the alarm
error: importing the ical calendar en Error: importing the iCal
error: no participants selected !!! calendar en Error: no participants selected !!!
error: ressources reservation in private events is not allowed!!! calendar en Error: ressources reservation in private events is not allowed !!!
error: saving the event !!! calendar en Error: saving the event !!!
error: starttime has to be before the endtime !!! calendar en Error: Starttime has to be before the endtime !!!
error: the entry has been updated since you opened it for editing! calendar en Error: the entry has been updated since you opened it for editing!
@ -248,6 +252,8 @@ repetition calendar en Repetition
repetitiondetails (or empty) calendar en Repetitiondetails (or empty)
reset calendar en Reset
resources calendar en Resources
resources except conflicting ones calendar en Resources except conflicting ones
resources with conflict detection calendar en Resources with conflict detection
rule calendar en Rule
sat calendar en Sat
saves the changes made calendar en saves the changes made

View File

@ -46,6 +46,7 @@ canceled calendar fr Annulé
charset of file calendar fr Jeu de charactères du fichier
close the window calendar fr Fermer la fenêtre
compose a mail to all participants after the event is saved calendar fr écrire un email à tous les participants après l'enregistrement de l'événement
conflict calendar fr Conflit
copy of: calendar fr Copie de :
copy this event calendar fr Copier cet événement
countries calendar fr Pays
@ -65,12 +66,15 @@ default appointment length (in minutes) calendar fr Durée du rendez-vous par d
default calendar filter calendar fr Filtre de calendrier par défaut
default calendar view calendar fr vue du calendrier par défaut
default length of newly created events. the length is in minutes, eg. 60 for 1 hour. calendar fr Durée par défaut des nouveaux événements. La durée est en minutes, c'est-à-dire 60 vaut 1 heure.
default type of resources application selected in the calendar particpants research form. calendar fr Type d'application de ressource sélectionnée par défaut dans le formulaire de recherche des participants.
default type of resources selection calendar fr Type de sélection de ressource par défaut
default week view calendar fr vue par défaut
delete series calendar fr Supprimer des occurences
delete this alarm calendar fr Supprimer cette alarme
delete this event calendar fr Supprimer cet événement
delete this exception calendar fr Supprimer cet exception
delete this series of recuring events calendar fr Supprimer ces occurences d'événements récurrents
deny ressources reservation for private events calendar fr Interdire la réservation de ressources pour les rendez-vous privés
disinvited calendar fr Invitation annulée
display status of events calendar fr Afficher le statut des événements
displayed view calendar fr vue affichée
@ -96,6 +100,7 @@ ends calendar fr finit
error adding the alarm calendar fr Erreur lors de l'ajout de l'alarme
error: importing the ical calendar fr Erreur: lors de l'importation de l'iCal
error: no participants selected !!! calendar fr Erreur: aucun participant sélectionné
error: ressources reservation in private events is not allowed!!! calendar fr Erreur: la réservation de ressources sur les rendez-vous privés n'est pas autorisée !!!
error: saving the event !!! calendar fr Erreur: lors de l'enregistrement de l'événement !!!
error: starttime has to be before the endtime !!! calendar fr Erreur : le début doit être antérieur à la fin !!!
event copied - the copy can now be edited calendar fr Evénement copié - la copie peut maintenant être éditée
@ -235,6 +240,8 @@ repetition calendar fr Répétition
repetitiondetails (or empty) calendar fr Détails de répétition (ou vide)
reset calendar fr Réinitialiser
resources calendar fr Ressources
resources except conflicting ones calendar fr Ressources à l'exception de celles en conflit
resources with conflict detection calendar fr Ressources avec détection de conflits
rule calendar fr Règle
sat calendar fr Sam
saves the changes made calendar fr enregistre les modifications

View File

@ -12,7 +12,7 @@
</tr>
<tr class="row_off">
<td colspan="2"><b>{lang_Calendar_settings}</b></td>
<td colspan="2"><b>{lang_Calendar} {lang_site_configuration}</b></td>
</tr>
<tr class="row_on">
<td>{lang_Do_you_wish_to_autoload_calendar_holidays_files_dynamically?}</td>
@ -38,9 +38,18 @@
<td><input name="newsettings[Lock_Time_Calender]" value="{value_Lock_Time_Calender}" size="40"></td>
</tr>
<tr class="row_off">
<td colspan="2"><b>{lang_Birthdays}</b></td>
<td>{lang_Deny_Ressources_reservation_for_private_events}:</td>
<td>
<select name="newsettings[no_ressources_private]">
<option value="">{lang_No}</option>
<option value="yes"{selected_no_ressources_private_yes}>{lang_Yes}</option>
</select>
</td>
</tr>
<tr class="row_on">
<td colspan="2"><b>{lang_Birthdays}</b></td>
</tr>
<tr class="row_off">
<td>{lang_Show_birthdays_from_addressbook}:</td>
<td>
<select name="newsettings[hide_birthdays]">

View File

@ -200,7 +200,7 @@ class bo_acl
$rights = in_array($account_id,$calbookcat) ? ($rights | EGW_ACL_DIRECT_BOOKING | EGW_ACL_CALREAD) : $rights;
$rights = in_array($account_id,$admincat) ? ($rights = 511) : $rights;
if ($rights)
{
{
$GLOBALS['egw']->acl->add_repository('resources','L'.$cat_id,$account_id,$rights);
}
}

View File

@ -323,24 +323,140 @@ class bo_resources
/**
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
* query infolog for entries matching $pattern
* @param string|array $pattern if it's a string it is the string we will search for as a criteria, if it's an array we
* will seach for 'search' key in this array to get the string criteria. others keys handled are actually used
* for calendar disponibility.
*
*/
function link_query( $pattern )
{
$criteria = array('name' => $pattern, 'short_description' => $pattern);
$only_keys = 'res_id,name,short_description';
if (is_array($pattern))
{
$criteria =array('name' => $pattern['search']
,'short_description' => $pattern['search']);
}
else
{
$criteria = array('name' => $pattern
, 'short_description' => $pattern);
}
$only_keys = 'res_id,name,short_description,bookable,useable';
$filter = array(
'cat_id' => array_flip((array)$this->acl->get_cats(EGW_ACL_READ)),
//'accessory_of' => '-1'
);
$data = $this->so->search($criteria,$only_keys,$order_by='',$extra_cols='',$wildcard='%',$empty,$op='OR',false,$filter);
foreach($data as $num => $resource)
// maybe we need to check disponibility of the searched resources in the calendar if $pattern ['exec'] contains some extra args
$show_conflict=False;
if (is_array($pattern) && isset($pattern['exec']) )
{
$list[$resource['res_id']] = $resource['name']. ($resource['short_description'] ? ', ['.$resource['short_description'].']':'');
// we'll use a cache for resources info taken from database
static $res_info_cache = array();
$cal_info=$pattern['exec'];
if ( isset($cal_info['start']) && isset($cal_info['duration']))
{
//get a calendar objet for reservations
if ( (!isset($this->bocal)) || !(is_object($this->bocal)))
{
require_once(EGW_INCLUDE_ROOT.'/calendar/inc/class.calendar_bo.inc.php');
$this->bocal =& CreateObject('calendar.calendar_bo');
}
//get the real timestamps from infos we have on the event
//use etemplate date widget to handle date values
require_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.jscalendar.inc.php');
$jscal=& CreateObject('phpgwapi.jscalendar');
$startarr= $jscal->input2date($cal_info['start']['str'],$raw='raw',$day='day',$month='month',$year='year');
if (isset($cal_info['whole_day'])) {
$startarr['hour'] = $startarr['minute'] = 0;
unset($startarr['raw']);
$start = $this->bocal->date2ts($startarr);
$end = $start + 86399;
} else {
$startarr['hour'] = $cal_info['start']['H'];
$startarr['minute'] = $cal_info['start']['i'];
unset($startarr['raw']);
$start = $this->bocal->date2ts($startarr);
$end = $start + ($cal_info['duration']);
}
// search events matching our timestamps
$resource_list=array();
foreach($data as $num => $resource)
{
// we only need resources id for the search, but with a 'r' prefix
// now we take this loop to store a new resource array indexed with resource id
// and as we work for calendar we use only bookable resources
if ((isset($resource['bookable'])) && ($resource['bookable'])){
$res_info_cache[$resource['res_id']]=$resource;
$resource_list[]='r'.$resource['res_id'];
}
}
$overlapping_events =& $this->bocal->search(array(
'start' => $start,
'end' => $end,
'users' => $resource_list,
'ignore_acl' => true, // otherwise we get only events readable by the user
'enum_groups' => false, // otherwise group-events would not block time
));
// parse theses overlapping events
foreach($overlapping_events as $event)
{
if ($event['non_blocking']) continue; // ignore non_blocking events
if (isset($cal_info['event_id']) && $event['id']==$cal_info['event_id']) {
continue; //ignore this event, it's the current edited event, no conflict by def
}
// now we are interested only on resources booked by theses events
if (isset($event['participants']) && is_array($event['participants'])){
foreach($event['participants'] as $part_key => $part_detail){
if ($part_key{0}=='r')
{ //now we gatta resource here
//need to check the quantity of this resource
$resource_id=substr($part_key,1);
// if we do not find this resource in our indexed array it's certainly
// because it was unset, non bookable maybe
if (!isset($res_info_cache[$resource_id])) continue;
// to detect ressources with default to 1 quantity
if (!isset($res_info_cache[$resource_id]['useable'])) {
$res_info_cache[$resource_id]['useable'] = 1;
}
// now decrement this quantity usable
// TODO : decrement with real event quantity, not 1
// but this quantity is not given by calendar search, we should re-use a cal object
// to load specific cal infos, like quantity... lot of requests
$res_info_cache[$resource_id]['useable']--;
}
}
}
}
}
}
if (isset($res_info_cache)) {
$show_conflict= (isset($pattern['exec']['show_conflict'])&& ($pattern['exec']['show_conflict']=='0'))? False:True;
// if we have this array indexed on resource id it means non-bookable resource are removed and we are working for calendar
// so we'll loop on this one and not $data
foreach($res_info_cache as $id => $resource) {
//maybe this resource is reserved
if ( ($resource['useable'] < 1) )
{
if($show_conflict) {
$list[$id] = ' ('.lang('conflict').') '.$resource['name']. ($resource['short_description'] ? ', ['.$resource['short_description'].']':'');
}
} else {
$list[$id] = $resource['name']. ($resource['short_description'] ? ', ['.$resource['short_description'].']':'');
}
}
} else {
// we are not working for the calendar, we loop on the initial $data
foreach($data as $num => $resource)
{
$id=$resource['res_id'];
$list[$id] = $resource['name']. ($resource['short_description'] ? ', ['.$resource['short_description'].']':'');
}
}
return $list;
}
/**
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
* get title for an infolog entry identified by $res_id

View File

@ -116,6 +116,7 @@ class ui_acl
{
switch($GLOBALS['egw_info']['user']['preferences']['common']['account_display'])
{
if(!($users_only && $account['account_type'] == 'g'))
case 'firstname':
case 'firstall':
$order = 'n_given,n_family';