- fixed not copied constrains and milestones in PM templates

- fixed not creatable milestones in templates
- when deleting a project you can now choose to delete the datasources
  of the elements (eg. InfoLog entries) too
- new stati 'template', 'nonactive' and 'archive' for InfoLog, which get
  not displayed by any standard filter, but choosing them from the
  status column filter
- InfoLog tasks in PM templates get now automatic activated, there stati
  is set depending of the percentage to not-started, in-progress or done
- changing the status of a project you can now choose to change the
  stati of InfoLog tasks (or other types having the needed stati) too
--> these features have been sponsored by Arne Reith from Reith-IT
This commit is contained in:
Ralf Becker 2007-10-05 15:06:27 +00:00
parent c89a55fb10
commit 71149c972f
11 changed files with 196 additions and 54 deletions

View File

@ -20,6 +20,7 @@ define('EGW_ACL_UNDELETE',EGW_ACL_CUSTOM_1); // undelete right
class boinfolog
{
var $enums;
var $status;
/**
* Instance of our so class
*
@ -164,7 +165,10 @@ class boinfolog
'ongoing' => 'ongoing', // iCal IN-PROCESS
'done' => 'done', // iCal COMPLETED
'cancelled' => 'cancelled', // iCal CANCELLED
'billed' => 'billed' ), // --> DONE
'billed' => 'billed', // --> DONE
'template' => 'template', // --> cancelled
'nonactive' => 'nonactive', // --> cancelled
'archive' => 'archive' ), // --> cancelled
'phone' => array(
'not-started' => 'call', // iCal NEEDS-ACTION
'ongoing' => 'will-call', // iCal IN-PROCESS
@ -1419,5 +1423,84 @@ class boinfolog
$GLOBALS['egw_info']['user']['account_id'] = $save_account_id;
$GLOBALS['egw_info']['user']['preferences'] = $save_prefs;
}
/** conversion of infolog status to vtodo status
* @private
* @var array
*/
var $_status2vtodo = array(
'offer' => 'NEEDS-ACTION',
'not-started' => 'NEEDS-ACTION',
'ongoing' => 'IN-PROCESS',
'done' => 'COMPLETED',
'cancelled' => 'CANCELLED',
'billed' => 'COMPLETED',
'template' => 'CANCELLED',
'nonactive' => 'CANCELLED',
'archive' => 'CANCELLED',
);
/** conversion of vtodo status to infolog status
* @private
* @var array
*/
var $_vtodo2status = array(
'NEEDS-ACTION' => 'not-started',
'IN-PROCESS' => 'ongoing',
'COMPLETED' => 'done',
'CANCELLED' => 'cancelled',
);
/**
* Converts an infolog status into a vtodo status
*
* @param string $status see $this->status
* @return string {CANCELLED|NEEDS-ACTION|COMPLETED|IN-PROCESS}
*/
function status2vtodo($status)
{
return isset($this->_status2vtodo[$status]) ? $this->_status2vtodo[$status] : 'NEEDS-ACTION';
}
/**
* Converts a vtodo status into an infolog status using the optional X-INFOLOG-STATUS
*
* X-INFOLOG-STATUS is only used, if translated to the vtodo-status gives the identical vtodo status
* --> the user did not changed it
*
* @param string $vtodo_status {CANCELLED|NEEDS-ACTION|COMPLETED|IN-PROCESS}
* @param string $x_infolog_status preserved original infolog status
* @return string
*/
function vtodo2status($vtodo_status,$x_infolog_status=null)
{
$vtodo_status = strtoupper($vtodo_status);
if ($x_infolog_status && $this->status2vtodo($x_infolog_status) == $vtodo_status)
{
$status = $x_infolog_status;
}
else
{
$status = isset($this->_vtodo2status[$vtodo_status]) ? $this->_vtodo2status[$vtodo_status] : 'not-started';
}
return $status;
}
/**
* Activates an InfoLog entry (setting it's status from template or inactive depending on the completed percentage)
*
* @param array $info
* @return string new status
*/
function activate($info)
{
switch((int)$info['info_percent'])
{
case 0: return 'not-started';
case 100: return 'done';
}
return 'ongoing';
}
}

View File

@ -25,6 +25,13 @@ include_once(EGW_INCLUDE_ROOT.'/projectmanager/inc/class.datasource.inc.php');
*/
class datasource_infolog extends datasource
{
/**
* Reference to boinfolog
*
* @var boinfolog
*/
var $boinfolog;
/**
* Constructor
*/
@ -33,6 +40,14 @@ class datasource_infolog extends datasource
$this->datasource('infolog');
$this->valid = PM_COMPLETION|PM_PLANNED_START|PM_PLANNED_END|PM_REAL_END|PM_PLANNED_TIME|PM_USED_TIME|PM_RESOURCES;
// we use $GLOBALS['boinfolog'] as an already running instance might be availible there
if (!is_object($GLOBALS['boinfolog']))
{
include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.boinfolog.inc.php');
$GLOBALS['boinfolog'] =& new boinfolog();
}
$this->boinfolog =& $GLOBALS['boinfolog'];
}
/**
@ -43,15 +58,9 @@ class datasource_infolog extends datasource
*/
function get($data_id)
{
// we use $GLOBALS['boinfolog'] as an already running instance might be availible there
if (!is_object($GLOBALS['boinfolog']))
{
include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.boinfolog.inc.php');
$GLOBALS['boinfolog'] =& new boinfolog();
}
if (!is_array($data_id))
{
$data =& $GLOBALS['boinfolog']->read((int) $data_id);
$data =& $this->boinfolog->read((int) $data_id);
if (!is_array($data)) return false;
}
@ -60,7 +69,7 @@ class datasource_infolog extends datasource
$data =& $data_id;
}
return array(
'pe_title' => $GLOBALS['boinfolog']->link_title($data),
'pe_title' => $this->boinfolog->link_title($data),
'pe_completion' => $data['info_percent'],
'pe_planned_start'=> $data['info_startdate'] ? $data['info_startdate'] : null,
'pe_planned_end' => $data['info_enddate'] ? $data['info_enddate'] : null,
@ -88,19 +97,14 @@ class datasource_infolog extends datasource
*/
function copy($element,$target,$extra=null)
{
if (!is_object($GLOBALS['boinfolog']))
{
include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.boinfolog.inc.php');
$GLOBALS['boinfolog'] =& new boinfolog();
}
$info =& $GLOBALS['boinfolog']->read((int) $element['pe_app_id']);
$info =& $this->boinfolog->read((int) $element['pe_app_id']);
if (!is_array($info)) return false;
// unsetting info_link_id and evtl. info_from
if ($info['info_link_id'])
{
$GLOBALS['boinfolog']->link_id2from($info); // unsets info_from and sets info_link_target
$this->boinfolog->link_id2from($info); // unsets info_from and sets info_link_target
unset($info['info_link_id']);
}
// we need to unset a view fields, to get a new entry
@ -108,26 +112,72 @@ class datasource_infolog extends datasource
{
unset($info[$key]);
}
if(!($info['info_id'] = $GLOBALS['boinfolog']->write($info))) return false;
if(!($info['info_id'] = $this->boinfolog->write($info))) return false;
// link the new infolog against the project and setting info_link_id and evtl. info_from
$info['info_link_id'] = $GLOBALS['boinfolog']->link->link('projectmanager',$target,'infolog',$info['info_id'],$element['pe_remark'],0,0,1);
$info['info_link_id'] = $this->boinfolog->link->link('projectmanager',$target,'infolog',$info['info_id'],$element['pe_remark'],0,0,1);
if (!$info['info_from'])
{
$info['info_from'] = $GLOBALS['boinfolog']->link->title('projectmanager',$target);
$info['info_from'] = $this->boinfolog->link->title('projectmanager',$target);
}
$GLOBALS['boinfolog']->write($info);
if ($info['info_status'] == 'template')
{
$info['info_status'] = $this->boinfolog->activate($info);
}
$this->boinfolog->write($info);
// creating again all links, beside the one to the source-project
foreach($GLOBALS['boinfolog']->link->get_links('infolog',$element['pe_app_id']) as $link)
foreach($this->boinfolog->link->get_links('infolog',$element['pe_app_id']) as $link)
{
if ($link['app'] == 'projectmanager' && $link['id'] == $element['pm_id'] || // ignoring the source project
$link['app'] == $GLOBALS['boinfolog']->link->vfs_appname) // ignoring files attachments for now
$link['app'] == $this->boinfolog->link->vfs_appname) // ignoring files attachments for now
{
continue;
}
$GLOBALS['boinfolog']->link->link('infolog',$info['info_id'],$link['app'],$link['id'],$link['remark']);
$this->boinfolog->link->link('infolog',$info['info_id'],$link['app'],$link['id'],$link['remark']);
}
return array($info['info_id'],$info['info_link_id']);
}
/**
* Delete the datasource of a project element
*
* @param int $id
* @return boolean true on success, false on error
*/
function delete($id)
{
if (!is_object($GLOBALS['boinfolog']))
{
include_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.boinfolog.inc.php');
$GLOBALS['boinfolog'] =& new boinfolog();
}
return $this->boinfolog->delete($id);
}
/**
* Change the status of an infolog entry according to the project status
*
* @param int $id
* @param string $status
* @return boolean true if status changed, false otherwise
*/
function change_status($id,$status)
{
//error_log("datasource_infolog::change_status($id,$status)");
if (($info = $this->boinfolog->read($id)) && $this->boinfolog->check_access($info,EGW_ACL_EDIT))
{
if ($status == 'active' && in_array($info['info_status'],array('template','nonactive','archive')))
{
$status = $this->boinfolog->activate($info);
}
if($info['info_status'] != $status && isset($this->boinfolog->status[$info['info_type']][$status]))
{
//error_log("datasource_infolog::change_status($id,$status) setting status from ".$info['info_status']);
$info['info_status'] = $status;
return $this->boinfolog->write($info) !== false;
}
}
return false;
}
}

View File

@ -274,10 +274,10 @@ class soinfolog // DB-Layer
switch ($filter)
{
case 'done': $filter = "info_status IN ('done','billed','cancelled')"; break;
case 'open': $filter = "NOT (info_status IN ('done','billed','cancelled','deleted'))"; break;
case 'open': $filter = "NOT (info_status IN ('done','billed','cancelled','deleted','template','nonactive','archive'))"; break;
case 'offer': $filter = "info_status = 'offer'"; break;
case 'deleted': $filter = "info_status = 'deleted'"; break;
default: $filter = "info_status <> 'deleted'"; break;
default: $filter = "NOT (info_status IN ('deleted','template','nonactive','archive'))"; break;
}
return ($prefix_and ? ' AND ' : '').$filter;
}
@ -655,7 +655,7 @@ class soinfolog // DB-Layer
$ordermethod = 'ORDER BY info_datemodified DESC'; // newest first
}
$acl_filter = $filtermethod = $this->aclFilter($query['filter']);
$filtermethod .= $this->statusFilter($query['filter']);
if (!$query['col_filter']['info_status']) $filtermethod .= $this->statusFilter($query['filter']);
$filtermethod .= $this->dateFilter($query['filter']);
if (is_array($query['col_filter']))

View File

@ -142,10 +142,6 @@ class uiinfolog
$this->duration_format = str_replace(',','',$pm_config->config_data['duration_units']).','.$pm_config->config_data['hours_per_workday'];
unset($pm_config);
}
if ($this->bo->history)
{
$this->filters['deleted'] = 'deleted';
}
/* these are just for testing of the notifications
for($i = -1; $i <= 3; ++$i)
{
@ -596,6 +592,10 @@ class uiinfolog
{
if ($typ != 'defaults') $all_stati += $stati;
}
if ($this->bo->history)
{
$all_stati['deleted'] = 'deleted';
}
if (!$called_as)
{
$GLOBALS['egw_info']['flags']['params']['manual'] = array('page' => 'ManualInfologIndex');

View File

@ -15,30 +15,11 @@
class vcalinfolog extends boinfolog
{
var $status2vtodo = array(
'offer' => 'NEEDS-ACTION',
'not-started' => 'NEEDS-ACTION',
'ongoing' => 'IN-PROCESS',
'done' => 'COMPLETED',
'cancelled' => 'CANCELLED',
'billed' => 'DONE',
'call' => 'NEEDS-ACTION',
'will-call' => 'IN-PROCESS',
);
var $vtodo2status = array(
'NEEDS-ACTION' => 'not-started',
'IN-PROCESS' => 'ongoing',
'COMPLETED' => 'done',
'CANCELLED' => 'cancelled',
);
var $egw_priority2vcal_priority = array(
0 => 3,
1 => 2,
2 => 1,
3 => 1,
);
var $vcal_priority2egw_priority = array(
@ -82,8 +63,9 @@
$vevent->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction($eventGUID,'modify'));
$vevent->setAttribute('UID',$taskGUID);
$vevent->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
$vevent->setAttribute('STATUS',isset($this->status2vtodo[$taskData['info_status']]) ?
$this->status2vtodo[$taskData['info_status']] : 'NEEDS-ACTION');
$vevent->setAttribute('STATUS',$this->status2vtodo($taskData['info_status']));
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
$vevent->setAttribute('X-INFOLOG-STATUS',$taskData['info_status']);
$vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
if (!empty($taskData['info_cat']))
@ -198,8 +180,13 @@
}
break;
case 'STATUS':
$taskData['info_status'] = isset($this->vtodo2status[strtoupper($attributes['value'])]) ?
$this->vtodo2status[strtoupper($attributes['value'])] : 'ongoing';
// check if we (still) have X-INFOLOG-STATUS set AND it would give an unchanged status (no change by the user)
foreach($component->_attributes as $attr)
{
if ($attr['name'] == 'X-INFOLOG-STATUS') break;
}
$taskData['info_status'] = $this->vtodo2status($attributes['value'],
$attr['name'] == 'X-INFOLOG-STATUS' ? $attr['value'] : null);
break;
case 'SUMMARY':
$taskData['info_subject'] = $attributes['value'];

View File

@ -42,6 +42,7 @@ all infolog de alle
all links and attachments infolog de alle Verknüpfungen und Anhänge
allows to set the status of an entry, eg. set a todo to done if it's finished (values depend on entry-typ) infolog de erlaubt den Status eines Eintrags zu setzen, zB. eine Aufgabe auf erledigt wenn sie beendet ist (Werte hängen vom Type des Eintrags ab)
apply the changes infolog de Übernimmt die Änderungen
archive infolog de Archiviert
are you shure you want to delete this entry ? infolog de Sind Sie sicher, dass Sie diesen Eintrag löschen wollen?
attach a file infolog de Datei anhängen
attach file infolog de Datei anhängen
@ -51,7 +52,7 @@ billed infolog de abgerechnet
both infolog de Annahme+erledigt
call infolog de anrufen
cancel infolog de Abbruch
cancelled infolog de Abgesagt
cancelled infolog de abgesagt
categories infolog de Kategorien
category infolog de Kategorie
change the status of an entry, eg. close it infolog de Status eines Eintrags ändern, zB. ihn als erledigt markieren
@ -197,6 +198,7 @@ no details infolog de Keine Details
no entries found, try again ... infolog de Kein Einträge gefunden, nochmal versuchen ...
no filter infolog de kein Filter
no links or attachments infolog de keine Verknüpfungen oder Anhänge
nonactive infolog de Nicht aktiv
none infolog de keine
normal infolog de normal
not infolog de nicht
@ -304,6 +306,7 @@ sub infolog de Unter-<br />eintr
sub-entries become subs of the parent or main entries, if there's no parent infolog de Untereinträge gehören dann zum übergeordneten Eintrag oder werden Haupteinträge wenn es keinen übergeordneten gibt.
subject infolog de Titel
task infolog de Aufgabe
template infolog de Vorlage
test import (show importable records <u>only</u> in browser) infolog de Test Import (zeige importierbare Datensätze <u>nur</u> im Browser)
the name used internaly (<= 10 chars), changeing it makes existing data unavailible infolog de der Name wird intern benutzt (<= 10 Zeichen), wenn er geändert wird, werden existierende Daten unzugänglich
the name used internaly (<= 20 chars), changeing it makes existing data unavailible infolog de der Name wird intern benutzt (<= 20 Zeichen), wenn er geändert wird, werden existierende Daten unzugänglich
@ -330,6 +333,7 @@ urgent infolog de Dringend
used time infolog de benötigte Zeit
valid path on clientside<br>eg. \\server\share or e:\ infolog de gültiger Pfad clientseitig<br>zB. \\Server\Share oder e:\
valid path on clientside<br>eg. \servershare or e: infolog de gültiger Pfad clientseitig<br>zB. \\Server\Share oder e:\
valid path on clientside<br>eg. servershare or e: infolog de gültiger Pfad clientseitig<br>zB. \\Server\Share oder e:\
values for selectbox infolog de Werte für die Auswahlbox
view all subs of this entry infolog de alle Untereinträge dieses Eintrag anzeigen
view other subs infolog de andere Untereinträge anzeigen

View File

@ -42,6 +42,7 @@ all infolog en All
all links and attachments infolog en all links and attachments
allows to set the status of an entry, eg. set a todo to done if it's finished (values depend on entry-typ) infolog en allows to set the status of an entry, eg. set a ToDo to done if it's finished (values depend on entry-type)
apply the changes infolog en Apply the changes
archive infolog en archive
are you shure you want to delete this entry ? infolog en Are you sure you want to delete this entry ?
attach a file infolog en Attach a file
attach file infolog en Attach file
@ -197,6 +198,7 @@ no details infolog en no details
no entries found, try again ... infolog en no entries found, try again ...
no filter infolog en no Filter
no links or attachments infolog en no links or attachments
nonactive infolog en nonactive
none infolog en None
normal infolog en normal
not infolog en not
@ -303,6 +305,7 @@ sub infolog en Sub
sub-entries become subs of the parent or main entries, if there's no parent infolog en Sub-entries become subs of the parent or main entries, if there's no parent
subject infolog en Subject
task infolog en ToDo
template infolog en Template
test import (show importable records <u>only</u> in browser) infolog en Test Import (show importable records <u>only</u> in browser)
the name used internaly (<= 10 chars), changeing it makes existing data unavailible infolog en the name used internaly (<= 10 chars), changeing it makes existing data unavailible
the name used internaly (<= 20 chars), changeing it makes existing data unavailible infolog en the name used internaly (<= 20 chars), changeing it makes existing data unavailible

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

View File

@ -89,4 +89,19 @@ class datasource_timesheet extends datasource
{
return false;
}
/**
* Delete the datasource of a project element
*
* @param int $id
* @return boolean true on success, false on error
*/
function delete($id)
{
if (!is_object($GLOBALS['botimesheet']))
{
$GLOBALS['botimesheet'] =& new botimesheet();
}
return $GLOBALS['botimesheet']->delete($id);
}
}