You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
655 lines
19 KiB
655 lines
19 KiB
<?php
|
|
/**
|
|
* Copyright 1999 - 2004 by Gero Kohnert
|
|
*
|
|
* CVS Info: $Id: timetrack.pinc,v 1.12 2005/01/17 05:11:26 saraj Exp $
|
|
* $Author: saraj $
|
|
*
|
|
* @modulegroup timetrack
|
|
* @package timetrack
|
|
*/
|
|
|
|
define ('TT_STATE_CHECKED',1);
|
|
define ('TT_STATE_BILLED',2);
|
|
define ('TT_STATE_PAYED',3);
|
|
define ('TT_STATE_NOBILL',4);
|
|
|
|
/**
|
|
* Read a summary of times for given object
|
|
*/
|
|
function readTimetrackSum (&$obj) {
|
|
global $table;
|
|
|
|
$obj->timetracksum = 0;
|
|
$q = "SELECT SUM(volume) as XX FROM ". $obj->dbconn->prefix .$table['timetrack'][name];
|
|
$pre = " WHERE ";
|
|
if ( $obj->getType() == "address" ) {
|
|
$q .= $pre . " adr_id =". $obj->id ;
|
|
} else if ( $obj->getType() == "user" ) {
|
|
$q .= $pre . " adr_id =". $obj->id ;
|
|
} else if ( $obj->getType() == "team" ) {
|
|
$q .= $pre . " adr_id =". $obj->id ;
|
|
} else {
|
|
$q .= $pre . " link_id =". $obj->id ;
|
|
}
|
|
$r = $obj->dbconn->Exec($q);
|
|
$n = $r->numrows();
|
|
if ( $n == 0 ) {
|
|
return;
|
|
}
|
|
$obj->timetracksum = $r->get(0,"XX");
|
|
$r->free();
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Compute the amount of work done by $address on $task
|
|
*
|
|
* FIXME : add some time schedule restriction
|
|
*/
|
|
function computeWorkedHours(&$address, &$task) {
|
|
global $table;
|
|
|
|
$sum = 0;
|
|
|
|
$q =
|
|
"SELECT SUM(volume) as XX FROM ". $task->dbconn->prefix .$table['timetrack'][name].
|
|
" WHERE adr_id = ". $address->id. " AND link_id = ". $task->id;
|
|
|
|
$r = $task->dbconn->Exec($q);
|
|
$n = $r->numrows();
|
|
if ( $n == 0 ) {
|
|
return $sum;
|
|
}
|
|
$sum = $r->get(0,"XX");
|
|
$r->free();
|
|
|
|
return $sum == "" ? 0 : $sum;
|
|
}
|
|
|
|
/**
|
|
* A fraction of a timetrack
|
|
* @package timetrack
|
|
*/
|
|
class timetrack extends tutos_base {
|
|
/* ---------------------------------------------------------------------------
|
|
*/
|
|
function timetrack(&$dbconn) {
|
|
global $tutos,$current_user,$table;
|
|
|
|
$this->init($dbconn);
|
|
|
|
$this->wid = $current_user->id;
|
|
$this->worker = $current_user;
|
|
$this->link_id = -1;
|
|
$this->ref = -1;
|
|
$this->desc = "";
|
|
$this->volume = 0.0;
|
|
$this->volume_todo = -1;
|
|
$this->wday = new DateTime();
|
|
$this->creation = new DateTime();
|
|
$this->t_start = new DateTime(0);
|
|
$this->t_end = new DateTime(0);
|
|
# number of invoice
|
|
$this->invoice = -1;
|
|
$this->currency = $tutos[currencies][0];
|
|
# Costs per hour ("" == default)
|
|
$this->cph = 0.0;
|
|
# State (-1 == unknown , 1 == checke 2 == billed)
|
|
$this->state = -1;
|
|
$this->inv_id = -1;
|
|
|
|
$this->tablename = $this->dbconn->prefix .$table['timetrack'][name];
|
|
}
|
|
/**
|
|
* read a resultset
|
|
*/
|
|
function read_result (&$r, $pos ) {
|
|
global $g_hash;
|
|
|
|
$this->id = $r->get($pos, "id");
|
|
$this->wid = $r->get($pos, "adr_id");
|
|
$this->worker = getObject($this->dbconn,$this->wid);
|
|
$this->link_id = $r->get($pos, "link_id");
|
|
$this->ref = getObject($this->dbconn,$this->link_id);
|
|
$this->desc = $r->get($pos, "description");
|
|
$this->volume = $r->get($pos, "volume");
|
|
$this->volume_todo = $r->get($pos, "volume_todo");
|
|
$this->state = (integer)$r->get($pos, "state");
|
|
$this->cph = $r->get($pos, "cph");
|
|
$this->currency = $r->get($pos, "currency");
|
|
$this->inv_id = $r->get($pos, "invoice");
|
|
$this->creation->setDateTime($r->get($pos, "creation"));
|
|
$this->wday->setDateTime($r->get($pos, "vtime"));
|
|
$this->t_start->setDateTime($r->get($pos, "t_start"));
|
|
$this->t_end->setDateTime($r->get($pos, "t_end"));
|
|
|
|
if ( $this->inv_id == "" ) {
|
|
$this->inv_id = -1;
|
|
$this->invoice = -1;
|
|
}
|
|
if ( $this->state == "" ) {
|
|
$this->state = -1;
|
|
}
|
|
if ( $this->cph == "" ) {
|
|
$this->cph = 0.00;
|
|
}
|
|
|
|
$this->creator = getObject($this->dbconn,$r->get($pos, "creator"));
|
|
|
|
parent::read_result($r,$pos);
|
|
return;
|
|
}
|
|
/**
|
|
* get a list of possible new parents
|
|
*/
|
|
function read_relations ( ) {
|
|
global $lang,$current_user;
|
|
|
|
$this->plist = array();
|
|
if ($this->ref != -1) {
|
|
# Read possible new parents
|
|
$this->plist = $this->ref->getNeighbours();
|
|
}
|
|
# a timetrack object could be attached to all projects and tasks where we play a role
|
|
if ( $current_user->feature_ok(useprojects,PERM_SEE) ) {
|
|
$q = "SELECT p.* from ". $this->dbconn->prefix."products p,". $this->dbconn->prefix ."projectroles r ";
|
|
$pre = " WHERE ";
|
|
if ($this->worker->id > 0) {
|
|
$q .= $pre ." r.adr_id in(". $this->worker->id;
|
|
$q .= " ) ";
|
|
$pre = " AND ";
|
|
}
|
|
$q .= $pre ." r.pro_id = p.id";
|
|
$q .= " AND p.state != ".PROD_STATE_CANCEL;
|
|
$q .= " AND p.state != ".PROD_STATE_QCANCEL;
|
|
$q .= " order by p.name";
|
|
$result = $this->dbconn->Exec($q);
|
|
$n = $result->numrows();
|
|
$a = 0;
|
|
# echo $n." ".$q;
|
|
while ( $a < $n ) {
|
|
$p = new product($this->dbconn);
|
|
$p->read_result($result,$a);
|
|
$a++;
|
|
if ( $p->use_ok()) {
|
|
$this->plist[$p->id] = &$p;
|
|
}
|
|
unset($p);
|
|
}
|
|
$result->free();
|
|
}
|
|
if ( $current_user->feature_ok(usetaskmanagement,PERM_SEE) ) {
|
|
$q = "SELECT t.* from ". $this->dbconn->prefix."tasks t,". $this->dbconn->prefix ."taskworker w ";
|
|
$pre = " WHERE ";
|
|
if ($this->worker->id > 0) {
|
|
$q .= $pre ." w.w_id in(". $this->worker->id;
|
|
$q .= " ) ";
|
|
$pre = " AND ";
|
|
}
|
|
$q .= $pre ." w.t_id = t.id";
|
|
$q .= " AND t.status != ".TASK_FINISH;
|
|
$q .= " order by t.name";
|
|
$result = $this->dbconn->Exec($q);
|
|
$n = $result->numrows();
|
|
$a = 0;
|
|
# echo $n." ".$q;
|
|
while ( $a < $n ) {
|
|
$p = new task($this->dbconn);
|
|
$p->read_result($result,$a);
|
|
$a++;
|
|
if ( $p->use_ok()) {
|
|
$this->plist[$p->id] = &$p;
|
|
}
|
|
unset($p);
|
|
}
|
|
$result->free();
|
|
}
|
|
}
|
|
/**
|
|
* set the Description
|
|
*/
|
|
function setDescription($value) {
|
|
$this->setStrField("desc",$value,"Description");
|
|
return;
|
|
}
|
|
/**
|
|
* set the Worker
|
|
*/
|
|
function setWorker($name) {
|
|
$i = new tutos_address($this->dbconn);
|
|
$i = $i->read($name,$i);
|
|
|
|
if ( ($this->worker->id != $name) && ($i->id != -1) ) {
|
|
$this->modified[] = array ( "field" => "TimetrackWorker", "old" => $this->worker->id , "new" => $name );
|
|
$this->worker = $i;
|
|
}
|
|
return;
|
|
}
|
|
/**
|
|
* set the workday
|
|
*/
|
|
function setWorkday(&$value) {
|
|
$this->setDateField("wday",$value,"Date");
|
|
return;
|
|
}
|
|
/**
|
|
* set the Start
|
|
*/
|
|
function setStart(&$value) {
|
|
$this->setDateTimeField("t_start",$value,"AppStart");
|
|
return;
|
|
}
|
|
/**
|
|
* set the End
|
|
*/
|
|
function setEnd(&$value) {
|
|
$this->setDateTimeField("t_end",$value,"AppEnd");
|
|
return;
|
|
}
|
|
/**
|
|
* set the Currency
|
|
*/
|
|
function setCurrency($value) {
|
|
$this->setStrField("currency",$value,"Currency");
|
|
return;
|
|
}
|
|
/**
|
|
* set the costs per hour
|
|
*/
|
|
function setCph($value) {
|
|
$this->setFloatField("cph",$value,"TTcph");
|
|
return;
|
|
}
|
|
/**
|
|
* set the volume
|
|
*/
|
|
function setVolume($value) {
|
|
$this->setFloatField("volume",$value,"TaskVolumeDone");
|
|
return;
|
|
}
|
|
/**
|
|
* set the volume todo
|
|
*/
|
|
function setVolumeTodo($value) {
|
|
$this->setFloatField("volume_todo",$value,"TaskVolumeTodo");
|
|
return;
|
|
}
|
|
/**
|
|
* set the state
|
|
*/
|
|
function setState($value) {
|
|
$this->setIntField("state",$value,"TTState");
|
|
return;
|
|
}
|
|
/**
|
|
* set the Invoice
|
|
*/
|
|
function setInvoice($value) {
|
|
$this->setIntField("inv_id",$value,"Invoice");
|
|
return;
|
|
}
|
|
/**
|
|
* set the Invoice
|
|
*/
|
|
function setReference($value) {
|
|
$this->setIntField("link_id",$value,"TimetrackRef");
|
|
return;
|
|
}
|
|
/**
|
|
* Save Time Fraction to DB
|
|
*
|
|
* The norec parameter allows to create a timetrack from task.pink
|
|
* without re entrance problems that may occur when timetrack tries
|
|
* to save the ref task...
|
|
*/
|
|
function save($norec=0) {
|
|
global $table,$tutos, $lang, $current_user;
|
|
|
|
// We may have to compute the volume todo of this timetrack entry
|
|
// This is the same as the task volume todo
|
|
if( $this->volume_todo == -1 ) {
|
|
if (isset($this->ref->volume_todo) && ($this->ref->volume_todo != -1) ) {
|
|
$ref_todo = $this->ref->volume_todo;
|
|
} elseif (isset($this->ref->volume) && ($this->ref->volume != -1) ) {
|
|
// If no volume_todo has been set for the task, we consider
|
|
// the planned volume as the volume_todo
|
|
$ref_todo = $this->ref->volume;
|
|
} else {
|
|
// the diff will be zero
|
|
$ref_todo = $this->volume;
|
|
}
|
|
// And the calculated volume_todo is the volume todo before this
|
|
// timetrack entry, minus this timetrack entry volume...
|
|
$volume_todo = $ref_todo - $this->volume;
|
|
} else {
|
|
// If a volume has been entered, we then just take it
|
|
$volume_todo = $this->volume_todo;
|
|
}
|
|
$msg = "";
|
|
$q = new query($this->dbconn);
|
|
$q->setTable($this->tablename);
|
|
$q->addFV("link_id",$this->link_id,"");
|
|
$q->addFV("adr_id",$this->worker->id,"");
|
|
$q->addFV("volume",$this->volume,"FLOAT");
|
|
$q->addFV("volume_todo",$volume_todo,"FLOAT");
|
|
$q->addFV("description",$this->desc,"STRING",$table['timetrack']['description'][size]);
|
|
$q->addFV("vtime",$this->wday,"DATETIME");
|
|
$q->addFV("state",$this->state,"");
|
|
$q->addFV("invoice",$this->inv_id,"");
|
|
$q->addFV("cph",$this->cph,"FLOAT");
|
|
$q->addFV("currency",$this->currency,"STRING",4);
|
|
$q->addFV("t_start",$this->t_start,"DATETIME");
|
|
$q->addFV("t_end",$this->t_end,"DATETIME");
|
|
$this->save_custom_fields($q);
|
|
|
|
if ( $this->id < 0 ) {
|
|
$this->modified = array();
|
|
if ( isset($this->newid) ) {
|
|
$this->id = $this->newid;
|
|
$q->addFV("id",$this->id,"");
|
|
} else {
|
|
$this->id = $q->addFV("id",-1,"NEXTID");
|
|
acl_default($this,$current_user);
|
|
# Prepare the history
|
|
$this->modified[] = array ( "field" => "TimetrackCreate" ,
|
|
"old" => "" ,
|
|
"new" => $this->volume,
|
|
"obj_id" => $this->link_id
|
|
);
|
|
$this->modified[] = array ( "field" => "created" ,
|
|
"old" => $this->getType() ,
|
|
"new" => $this->id,
|
|
"obj_id" => $this->id
|
|
);
|
|
}
|
|
$q->addFV("creation",$this->creation,"DATETIME");
|
|
$q->addFV("creator",$this->creator,"OBJ");
|
|
|
|
$query = $q->getInsert();
|
|
} else {
|
|
$q->addWC("id",$this->id,"");
|
|
$query = $q->getUpdate();
|
|
}
|
|
|
|
$this->dbconn->Exec($query);
|
|
if ( $norec == 0 &&
|
|
($this->ref != -1) &&
|
|
($this->ref->getType() == "task") ) {
|
|
if ( $this->ref->r_start->notime == 1 ) {
|
|
$this->ref->setRStart(new Datetime());
|
|
}
|
|
|
|
// Task has to be considered running
|
|
if( $this->ref->state == TASK_PRE ) {
|
|
$this->ref->state = TASK_RUNNING;
|
|
}
|
|
// The volume todo has to be set on the task
|
|
$this->ref->setVolumeTodo($volume_todo);
|
|
|
|
$this->ref->save();
|
|
}
|
|
$msg .= parent::save();
|
|
|
|
return $msg;
|
|
}
|
|
/**
|
|
* delete timetrack entries for a object
|
|
*/
|
|
Function obj_delete(&$user,&$obj) {
|
|
global $table;
|
|
|
|
$msg = "";
|
|
|
|
# FIXME (mybe we should rebook the efforts to the user himself) !!
|
|
$q = "DELETE FROM ". $obj->dbconn->prefix .$table['timetrack'][name]." WHERE link_id = ". $obj->id;
|
|
$obj->dbconn->Exec($q);
|
|
return $msg;
|
|
}
|
|
/**
|
|
* Delete Timetrack fraction from DB
|
|
*/
|
|
function delete() {
|
|
$msg = "";
|
|
|
|
$q = "DELETE FROM ". $this->tablename ." WHERE id = ". $this->id;
|
|
$this->dbconn->Exec($q);
|
|
|
|
$this->modified[] = array ( "field" => "TimetrackDel" ,
|
|
"old" => $this->volume ,
|
|
"new" => "0",
|
|
"obj_id" => $this->link_id
|
|
);
|
|
$msg .= parent::delete();
|
|
|
|
return $msg;
|
|
}
|
|
/**
|
|
* Checks if the current user is allowed to delete this timetrack
|
|
*/
|
|
function del_ok () {
|
|
if ( $this->ref != -1 ) {
|
|
return $this->ref->del_ok();
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
function see_ok() {
|
|
if ( $this->ref != -1 ) {
|
|
return $this->ref->see_ok();
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
function mod_ok() {
|
|
if ( $this->ref != -1 ) {
|
|
return $this->ref->mod_ok();
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
/**
|
|
* Return a url that displays this timetrack fraction
|
|
*/
|
|
function getURL() {
|
|
return "timetrack_overview.php?id=". $this->id;
|
|
}
|
|
/**
|
|
* Return a url that allows modification of this timetrack fraction
|
|
*/
|
|
function getModURL() {
|
|
return "timetrack_new.php?id=". $this->id;
|
|
}
|
|
/**
|
|
* Return a url that deletes this timetrack fraction
|
|
*/
|
|
function getDelURL() {
|
|
return "timetrack_del.php?id=". $this->id;
|
|
}
|
|
/**
|
|
* Return a url that displays this timetrack fraction
|
|
*/
|
|
function getFullName() {
|
|
return $this->volume ."@" . $this->wday->getDate();
|
|
}
|
|
/**
|
|
* Return a link to this timefragement
|
|
*/
|
|
function getLink($text = "") {
|
|
global $lang;
|
|
|
|
if ( empty($text) ) {
|
|
$text = $this->getFullName();
|
|
}
|
|
if ( $this->see_ok() ) {
|
|
return makelink($this->getURL() , myentities($text) ,sprintf($lang['timetrack'] ." %s",$this->getFullName()));
|
|
} else {
|
|
return myentities($text);
|
|
}
|
|
}
|
|
/**
|
|
* Data of XML export
|
|
*/
|
|
function exportXML_body () {
|
|
$r = parent::exportXML_body();
|
|
$r .= "<worker>". utf8_encode(htmlspecialchars($this->worker->id)) ."</worker>\n";
|
|
if ( $this->worker->id != null ) {
|
|
$r .= "<workername>". utf8_encode(htmlspecialchars($this->worker->getFullName())) ."</workername>\n";
|
|
}
|
|
$r .= "<reference>". utf8_encode(htmlspecialchars($this->ref->id)) ."</reference>\n";
|
|
if ( $this->ref->id != null ) {
|
|
$r .= "<referencename>". utf8_encode(htmlspecialchars($this->ref->getFullName())) ."</referencename>\n";
|
|
}
|
|
$r .= "<volume>". utf8_encode(htmlspecialchars($this->volume)) ."</volume>\n";
|
|
$r .= "<volume_todo>". utf8_encode(htmlspecialchars($this->volume_todo)) ."</volume_todo>\n";
|
|
if ( $this->t_start->notime != 1 ) {
|
|
$r .= "<t_start>". $this->t_start->exportXML_body() ."</t_start>\n";
|
|
}
|
|
if ( $this->t_end->notime != 1 ) {
|
|
$r .= "<t_end>". $this->t_end->exportXML_body() ."</t_end>\n";
|
|
}
|
|
$r .= "<description>". utf8_encode(htmlspecialchars($this->desc)) ."</description>\n";
|
|
$r .= "<invoice>". utf8_encode(htmlspecialchars($this->invoice)) ."</invoice>\n";
|
|
$r .= "<state>". utf8_encode(htmlspecialchars($this->state)) ."</state>\n";
|
|
$r .= "<cph>". utf8_encode(htmlspecialchars($this->cph)) ."</cph>\n";
|
|
$r .= "<cost>". utf8_encode(htmlspecialchars($this->cph * $this->volume)) ."</cost>\n";
|
|
$r .= "<currency>". utf8_encode(htmlspecialchars($this->currency)) ."</currency>\n";
|
|
if ( $this->wday->notime != 1 ) {
|
|
$r .= "<vtime>". $this->wday->exportXML_body() ."</vtime>\n";
|
|
}
|
|
return $r;
|
|
}
|
|
/**
|
|
* Return a data as comma seperated values string
|
|
*/
|
|
function exportCSV() {
|
|
global $lang;
|
|
|
|
if ( $this->ref->id > 0 ) {
|
|
$r = $this->ref->getFullName();
|
|
} else {
|
|
$r = $lang['HistoryDeleted'];
|
|
}
|
|
if ( $this->worker->id > 0 ) {
|
|
$w = $this->worker->getFullName();
|
|
} else {
|
|
$w = $lang['HistoryDeleted'];
|
|
}
|
|
return $this->id .",\"". $w ."\",\"". $r ."\",\"". $this->desc ."\",". $this->volume .",". $this->cph .",\"". $this->currency ."\",". $this->state .",". $this->wday->getYYYYMMDD() ."\n";
|
|
}
|
|
/**
|
|
* Transfer reference ids according to given table
|
|
*/
|
|
function transfer_ids (&$trans) {
|
|
if (isset($trans[$this->worker->id])) {
|
|
$this->worker->id = $trans[$this->worker->id];
|
|
}
|
|
if (isset($trans[$this->inv_id])) {
|
|
$this->inv_id = $trans[$this->inv_id];
|
|
}
|
|
if (isset($trans[$this->link_id])) {
|
|
$this->link_id = $trans[$this->link_id];
|
|
}
|
|
return;
|
|
}
|
|
/**
|
|
* get the type of object
|
|
*/
|
|
function gettype () {
|
|
return "timetrack";
|
|
}
|
|
/**
|
|
* get the type id of object
|
|
*/
|
|
function gettypeid () {
|
|
return usetimetrack;
|
|
}
|
|
/* ---------------------------------------------------------------------------
|
|
* The following methods are abstract factory functions for groups
|
|
* which handle the membership list of an object
|
|
* --------------------------------------------------------------------------- */
|
|
/**
|
|
* Read a list of all timetrack elements
|
|
*/
|
|
function obj_read (&$obj) {
|
|
global $table;
|
|
|
|
if ( ! isset($obj->id) ) return;
|
|
|
|
$obj->ttlist = array();
|
|
$q = "SELECT * from ". $obj->dbconn->prefix .$table['timetrack'][name]." where link_id = ". $obj->id ." order by vtime desc";
|
|
$r = $obj->dbconn->Exec($q);
|
|
$n = $r->numrows();
|
|
$a = 0;
|
|
while ($a < $n) {
|
|
$tt = new timetrack($obj->dbconn);
|
|
$tt->read_result($r,$a);
|
|
if ( $tt->see_ok() ) {
|
|
$obj->ttlist[$tt->id] = &$tt;
|
|
}
|
|
$a++;
|
|
unset($tt);
|
|
}
|
|
$r->free();
|
|
return;
|
|
}
|
|
/**
|
|
* create a link where a timetrack for work on the given object could be added
|
|
*/
|
|
function getaddlink (&$user,&$obj,$text = "") {
|
|
global $lang;
|
|
|
|
if ( $obj == -1 ) return;
|
|
if (! is_object($obj) ) return;
|
|
if ( $obj->id == -1 ) return;
|
|
if (! $user->feature_ok(usetimetrack,PERM_NEW) ) return "";
|
|
if (! $obj->use_ok() ) return "";
|
|
|
|
if ($obj->gettype() == "product") {
|
|
if ($obj->state == PROD_STATE_CANCEL) return "";
|
|
if ($obj->state == PROD_STATE_QCANCEL) return "";
|
|
}
|
|
if ($obj->gettype() == "task") {
|
|
if ($obj->state == TASK_FINISH) return "";
|
|
}
|
|
|
|
if ($user->id == $obj->id ) {
|
|
$x = array( url => "timetrack_new.php?mode=1&lid=". $obj->id,
|
|
confirm => false,
|
|
text => ($text == "" ? $lang['TTRecord']:$text),
|
|
info => $lang['TTRecord'],
|
|
category => array("timetrack","new","module")
|
|
);
|
|
} else {
|
|
$x = array( url => "timetrack_new.php?lid=". $obj->id,
|
|
confirm => false,
|
|
text => ($text == "" ? $lang['TimetrackCreate']:$text),
|
|
info => sprintf($lang['TimetrackCreateI'], $obj->getFullName()),
|
|
category => array("timetrack","new","module")
|
|
);
|
|
}
|
|
return $x;
|
|
}
|
|
/**
|
|
* create a link to a overview page
|
|
*/
|
|
function getSelectLink (&$user,$text = "") {
|
|
global $lang,$tutos;
|
|
if ( ! $user->feature_ok(usetimetrack,PERM_SEL) ) {
|
|
return;
|
|
}
|
|
return array( url => "timetrack_select.php",
|
|
image => timetrack::getHtmlIcon(),
|
|
text => ($text == "" ? $lang['Search']: $text),
|
|
info => $lang['SearchForTT'],
|
|
category => array("search","timetrack","obj")
|
|
);
|
|
}
|
|
}
|
|
?>
|
|
|