30 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
31 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
32 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
33 require_once DOL_DOCUMENT_ROOT.
'/core/class/timespent.class.php';
44 public $element =
'project_task';
49 public $table_element =
'projet_task';
54 public $fk_element =
'fk_element';
59 public $picto =
'projecttask';
64 protected $childtables = array(
65 'element_time' => array(
'name' =>
'Task',
'parent' =>
'projet_task',
'parentkey' =>
'fk_element',
'parenttypefield' =>
'elementtype',
'parenttypevalue' =>
'task')
71 public $fk_task_parent = 0;
83 public $duration_effective;
84 public $planned_workload;
105 public $fk_user_creat;
110 public $fk_user_valid;
114 public $timespent_min_date;
115 public $timespent_max_date;
116 public $timespent_total_duration;
117 public $timespent_total_amount;
118 public $timespent_nblinesnull;
119 public $timespent_nblines;
123 public $timespent_id;
124 public $timespent_duration;
125 public $timespent_old_duration;
126 public $timespent_date;
127 public $timespent_datehour;
128 public $timespent_withhour;
129 public $timespent_fk_user;
130 public $timespent_thm;
131 public $timespent_note;
132 public $timespent_fk_product;
133 public $timespent_invoiceid;
134 public $timespent_invoicelineid;
136 public $comments = array();
146 public $statuts_short;
154 public $projectstatus;
155 public $projectlabel;
158 public $fk_opp_status;
159 public $usage_bill_time;
161 public $array_options_project;
165 public $thirdparty_id;
166 public $thirdparty_name;
167 public $thirdparty_email;
173 public $budget_amount;
178 public $project_budget_amount;
200 public function create($user, $notrigger = 0)
202 global $conf, $langs;
210 $this->label = trim($this->label);
213 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
214 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
222 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet_task (";
224 $sql .=
", fk_projet";
226 $sql .=
", fk_task_parent";
228 $sql .=
", description";
230 $sql .=
", fk_user_creat";
233 $sql .=
", planned_workload";
234 $sql .=
", progress";
235 $sql .=
", budget_amount";
236 $sql .=
") VALUES (";
237 $sql .= (!empty($this->entity) ? (int) $this->entity : (
int) $conf->entity);
238 $sql .=
", ".((int) $this->fk_project);
239 $sql .=
", ".(!empty($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
'null');
240 $sql .=
", ".((int) $this->fk_task_parent);
241 $sql .=
", '".$this->db->escape($this->label).
"'";
243 $sql .=
", '".$this->db->idate($now).
"'";
244 $sql .=
", ".((int) $user->id);
245 $sql .=
", ".($this->date_start ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
246 $sql .=
", ".($this->date_end ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
247 $sql .=
", ".(($this->planned_workload !=
'' && $this->planned_workload >= 0) ? ((
int) $this->planned_workload) :
'null');
248 $sql .=
", ".(($this->progress !=
'' && $this->progress >= 0) ? ((
int) $this->progress) :
'null');
249 $sql .=
", ".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? ((
int) $this->budget_amount) :
'null');
254 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
255 $resql = $this->db->query(
$sql);
257 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
261 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"projet_task");
285 foreach ($this->errors as $errmsg) {
286 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
287 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
289 $this->db->rollback();
306 public function fetch($id, $ref =
'', $loadparentdata = 0)
308 global $langs, $conf;
313 $sql .=
" t.entity,";
314 $sql .=
" t.fk_projet as fk_project,";
315 $sql .=
" t.fk_task_parent,";
317 $sql .=
" t.description,";
318 $sql .=
" t.duration_effective,";
319 $sql .=
" t.planned_workload,";
323 $sql .=
" t.fk_user_creat,";
324 $sql .=
" t.fk_user_valid,";
325 $sql .=
" t.fk_statut,";
326 $sql .=
" t.progress,";
327 $sql .=
" t.budget_amount,";
328 $sql .=
" t.priority,";
329 $sql .=
" t.note_private,";
330 $sql .=
" t.note_public,";
332 if (!empty($loadparentdata)) {
333 $sql .=
", t2.ref as task_parent_ref";
334 $sql .=
", t2.rang as task_parent_position";
336 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as t";
337 if (!empty($loadparentdata)) {
338 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t2 ON t.fk_task_parent = t2.rowid";
342 $sql .=
"entity IN (".getEntity(
'project').
")";
343 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
345 $sql .=
"t.rowid = ".((int) $id);
348 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
349 $resql = $this->db->query(
$sql);
351 $num_rows = $this->db->num_rows($resql);
354 $obj = $this->db->fetch_object($resql);
356 $this->
id = $obj->rowid;
357 $this->
ref = $obj->ref;
358 $this->entity = $obj->entity;
359 $this->fk_project = $obj->fk_project;
360 $this->fk_task_parent = $obj->fk_task_parent;
361 $this->label = $obj->label;
363 $this->duration_effective = $obj->duration_effective;
364 $this->planned_workload = $obj->planned_workload;
365 $this->date_c = $this->db->jdate($obj->datec);
366 $this->date_start = $this->db->jdate($obj->dateo);
367 $this->date_end = $this->db->jdate($obj->datee);
368 $this->fk_user_creat = $obj->fk_user_creat;
369 $this->fk_user_valid = $obj->fk_user_valid;
370 $this->fk_statut = $obj->fk_statut;
371 $this->progress = $obj->progress;
372 $this->budget_amount = $obj->budget_amount;
373 $this->priority = $obj->priority;
374 $this->note_private = $obj->note_private;
375 $this->note_public = $obj->note_public;
376 $this->rang = $obj->rang;
378 if (!empty($loadparentdata)) {
379 $this->task_parent_ref = $obj->task_parent_ref;
380 $this->task_parent_position = $obj->task_parent_position;
387 $this->db->free($resql);
395 $this->error =
"Error ".$this->db->lasterror();
408 public function update($user =
null, $notrigger = 0)
410 global $conf, $langs;
414 if (isset($this->fk_project)) {
415 $this->fk_project = trim($this->fk_project);
417 if (isset($this->
ref)) {
418 $this->
ref = trim($this->
ref);
420 if (isset($this->fk_task_parent)) {
421 $this->fk_task_parent = (int) $this->fk_task_parent;
423 if (isset($this->label)) {
424 $this->label = trim($this->label);
429 if (isset($this->duration_effective)) {
430 $this->duration_effective = trim($this->duration_effective);
432 if (isset($this->planned_workload)) {
433 $this->planned_workload = trim($this->planned_workload);
435 if (isset($this->budget_amount)) {
436 $this->budget_amount = trim($this->budget_amount);
439 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
440 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
448 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task SET";
449 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
450 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"'".$this->db->escape($this->
id).
"'").
",";
451 $sql .=
" fk_task_parent=".(isset($this->fk_task_parent) ? $this->fk_task_parent :
"null").
",";
452 $sql .=
" label=".(isset($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
454 $sql .=
" duration_effective=".(isset($this->duration_effective) ? $this->duration_effective :
"null").
",";
455 $sql .=
" planned_workload=".((isset($this->planned_workload) && $this->planned_workload !=
'') ? $this->planned_workload :
"null").
",";
456 $sql .=
" dateo=".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null').
",";
457 $sql .=
" datee=".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null').
",";
458 $sql .=
" progress=".(($this->progress !=
'' && $this->progress >= 0) ? $this->progress :
'null').
",";
459 $sql .=
" budget_amount=".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? $this->budget_amount :
'null').
",";
460 $sql .=
" rang=".((!empty($this->rang)) ? $this->rang :
"0");
461 $sql .=
" WHERE rowid=".((int) $this->
id);
465 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
466 $resql = $this->db->query(
$sql);
468 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
479 if (!$error && !empty($conf->global->PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE)) {
481 $project =
new Project($this->db);
482 if ($project->fetch($this->fk_project) > 0) {
484 $project->getLinesArray(
null);
485 $projectCompleted = array_reduce(
487 function ($allTasksCompleted, $task) {
488 return $allTasksCompleted && $task->progress >= 100;
492 if ($projectCompleted) {
493 if ($project->setClose($user) <= 0) {
502 $this->errors[] = $project->error;
517 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) {
519 if ($conf->project->dir_output) {
520 $project =
new Project($this->db);
521 $project->fetch($this->fk_project);
525 if (file_exists($olddir)) {
526 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
529 $langs->load(
"errors");
530 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
539 foreach ($this->errors as $errmsg) {
540 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
541 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
543 $this->db->rollback();
559 public function delete($user, $notrigger = 0)
562 global $conf, $langs;
563 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
570 dol_syslog(get_class($this).
"::delete Can't delete record as it has some sub tasks", LOG_WARNING);
571 $this->error =
'ErrorRecordHasSubTasks';
572 $this->db->rollback();
577 if (!empty($objectisused)) {
578 dol_syslog(get_class($this).
"::delete Can't delete record as it has some child", LOG_WARNING);
579 $this->error =
'ErrorRecordHasChildren';
580 $this->db->rollback();
588 $this->error =
'ErrorFailToDeleteLinkedContact';
590 $this->db->rollback();
596 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"element_time";
597 $sql .=
" WHERE fk_element = ".((int) $this->
id).
" AND elementtype = 'task'";
599 $resql = $this->db->query(
$sql);
601 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
606 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task_extrafields";
607 $sql .=
" WHERE fk_object = ".((int) $this->
id);
609 $resql = $this->db->query(
$sql);
611 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
616 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task";
617 $sql .=
" WHERE rowid=".((int) $this->
id);
619 $resql = $this->db->query(
$sql);
621 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
638 foreach ($this->errors as $errmsg) {
639 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
640 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
642 $this->db->rollback();
646 if ($conf->project->dir_output) {
647 $projectstatic =
new Project($this->db);
648 $projectstatic->fetch($this->fk_project);
651 dol_syslog(get_class($this).
"::delete dir=".$dir, LOG_DEBUG);
652 if (file_exists($dir)) {
653 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
656 $this->error =
'ErrorFailToDeleteDir';
657 $this->db->rollback();
679 $sql =
"SELECT COUNT(*) as nb";
680 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task";
681 $sql .=
" WHERE fk_task_parent = ".((int) $this->
id);
683 dol_syslog(get_class($this).
"::hasChildren", LOG_DEBUG);
684 $resql = $this->db->query(
$sql);
686 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
688 $obj = $this->db->fetch_object($resql);
692 $this->db->free($resql);
712 $sql =
"SELECT COUNT(*) as nb";
713 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time";
714 $sql .=
" WHERE fk_element = ".((int) $this->
id);
715 $sql .=
" AND elementtype = 'task'";
717 dol_syslog(get_class($this).
"::hasTimeSpent", LOG_DEBUG);
718 $resql = $this->db->query(
$sql);
720 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
722 $obj = $this->db->fetch_object($resql);
726 $this->db->free($resql);
748 $langs->load(
'projects');
751 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u>'.$langs->trans(
"Task").
'</u>';
752 if (!empty($this->
ref)) {
753 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
755 if (!empty($this->label)) {
756 $datas[
'label'] =
'<br><b>'.$langs->trans(
'LabelTask').
':</b> '.$this->label;
758 if ($this->date_start || $this->date_end) {
759 $datas[
'range'] =
"<br>".get_date_range($this->date_start, $this->date_end,
'', $langs, 0);
777 public function getNomUrl($withpicto = 0, $option =
'', $mode =
'task', $addlabel = 0, $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1)
779 global $conf, $langs, $user;
781 if (!empty($conf->dol_no_mouse_hover)) {
788 'objecttype' => $this->element,
790 $classfortooltip =
'classfortooltip';
793 $classfortooltip =
'classforajaxtooltip';
794 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
800 $url = DOL_URL_ROOT.
'/projet/tasks/'.$mode.
'.php?id='.$this->
id.($option ==
'withproject' ?
'&withproject=1' :
'');
802 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
803 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
804 $add_save_lastsearch_values = 1;
806 if ($add_save_lastsearch_values) {
807 $url .=
'&save_lastsearch_values=1';
811 if (empty($notooltip)) {
812 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
813 $label = $langs->trans(
"ShowTask");
814 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
816 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
817 $linkclose .= $dataparams.
' class="'.$classfortooltip.
' nowraponall"';
819 $linkclose .=
' class="nowraponall"';
822 $linkstart =
'<a href="'.$url.
'"';
823 $linkstart .= $linkclose.
'>';
826 $picto =
'projecttask';
828 $result .= $linkstart;
830 $result .=
img_object(($notooltip ?
'' : $label), $picto,
'class="paddingright"', 0, 0, $notooltip ? 0 : 1);
832 if ($withpicto != 2) {
833 $result .= $this->ref;
836 if ($withpicto != 2) {
837 $result .= (($addlabel && $this->label) ? $sep.dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) :
'');
854 $this->fk_project =
'';
856 $this->fk_task_parent =
null;
857 $this->label =
'Specimen task TK01';
858 $this->duration_effective =
'';
859 $this->fk_user_creat =
null;
860 $this->progress =
'25';
861 $this->fk_statut =
null;
862 $this->note =
'This is a specimen task not';
888 public function getTasksArray($usert =
null, $userp =
null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj =
'', $filteronprojstatus =
'-1', $morewherefilter =
'', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields = array(), $includebilltime = 0, $search_array_options = array(), $loadextras = 0, $loadRoleMode = 1, $sortfield =
'', $sortorder =
'')
890 global $conf, $hookmanager;
898 if ($filteronprojuser > 0 || $filterontaskuser > 0) {
901 $sql .=
" p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus, p.usage_bill_time,";
902 $sql .=
" t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,";
903 $sql .=
" t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,";
904 $sql .=
" t.description, ";
905 $sql .=
" t.budget_amount, ";
906 $sql .=
" s.rowid as thirdparty_id, s.nom as thirdparty_name, s.email as thirdparty_email,";
907 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount as project_budget_amount";
909 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
910 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
911 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key.
" as options_".$key :
'');
915 if ($includebilltime) {
916 $sql .=
", SUM(tt.element_duration * ".$this->db->ifsql(
"invoice_id IS NULL",
"1",
"0").
") as tobill, SUM(tt.element_duration * ".$this->db->ifsql(
"invoice_id IS NULL",
"0",
"1").
") as billed";
919 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
920 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
922 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_extrafields as efp ON (p.rowid = efp.fk_object)";
926 if ($filteronprojuser > 0) {
927 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
928 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
930 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
931 if ($includebilltime) {
932 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')";
934 if ($filterontaskuser > 0) {
935 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
936 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
938 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
939 $sql .=
" AND t.fk_projet = p.rowid";
940 } elseif ($mode == 1) {
941 if ($filteronprojuser > 0) {
942 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
943 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
945 if ($filterontaskuser > 0) {
946 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
947 if ($includebilltime) {
948 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')";
950 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
951 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
953 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t on t.fk_projet = p.rowid";
954 if ($includebilltime) {
955 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype = 'task')";
958 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
960 return 'BadValueForParameterMode';
963 if ($filteronprojuser > 0) {
964 $sql .=
" AND p.rowid = ec.element_id";
965 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
966 $sql .=
" AND ctc.element = 'project'";
967 $sql .=
" AND ec.fk_socpeople = ".((int) $filteronprojuser);
968 $sql .=
" AND ec.statut = 4";
969 $sql .=
" AND ctc.source = 'internal'";
971 if ($filterontaskuser > 0) {
972 $sql .=
" AND t.fk_projet = p.rowid";
973 $sql .=
" AND p.rowid = ec2.element_id";
974 $sql .=
" AND ctc2.rowid = ec2.fk_c_type_contact";
975 $sql .=
" AND ctc2.element = 'project_task'";
976 $sql .=
" AND ec2.fk_socpeople = ".((int) $filterontaskuser);
977 $sql .=
" AND ec2.statut = 4";
978 $sql .=
" AND ctc2.source = 'internal'";
981 $sql .=
" AND p.fk_soc = ".((int) $socid);
984 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectid).
")";
989 if ($filteronprojstatus && $filteronprojstatus !=
'-1') {
990 $sql .=
" AND p.fk_statut IN (".$this->db->sanitize($filteronprojstatus).
")";
992 if ($morewherefilter) {
993 $sql .= $morewherefilter;
996 $extrafieldsobjectkey =
'projet_task';
997 $extrafieldsobjectprefix =
'efpt.';
999 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_sql.tpl.php';
1001 $parameters = array();
1002 $reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
1003 $sql .= $hookmanager->resPrint;
1004 if ($includebilltime) {
1005 $sql .=
" GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,";
1006 $sql .=
" t.datec, t.dateo, t.datee, t.tms,";
1007 $sql .=
" t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,";
1008 $sql .=
" t.dateo, t.datee, t.planned_workload, t.rang,";
1009 $sql .=
" t.description, ";
1010 $sql .=
" t.budget_amount, ";
1011 $sql .=
" s.rowid, s.nom, s.email,";
1012 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount";
1014 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1015 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1016 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key :
'');
1022 if ($sortfield && $sortorder) {
1023 $sql .= $this->db->order($sortfield, $sortorder);
1025 $sql .=
" ORDER BY p.ref, t.rang, t.dateo";
1029 dol_syslog(get_class($this).
"::getTasksArray", LOG_DEBUG);
1030 $resql = $this->db->query(
$sql);
1032 $num = $this->db->num_rows($resql);
1038 $obj = $this->db->fetch_object($resql);
1040 if ($loadRoleMode) {
1041 if ((!$obj->public) && (is_object($userp))) {
1046 if (is_object($usert)) {
1054 $tasks[$i] =
new Task($this->db);
1055 $tasks[$i]->id = $obj->taskid;
1056 $tasks[$i]->ref = $obj->taskref;
1057 $tasks[$i]->fk_project = $obj->projectid;
1060 $tasks[$i]->projectref = $obj->ref;
1061 $tasks[$i]->projectlabel = $obj->plabel;
1062 $tasks[$i]->projectstatus = $obj->projectstatus;
1063 $tasks[$i]->fk_opp_status = $obj->fk_opp_status;
1064 $tasks[$i]->opp_amount = $obj->opp_amount;
1065 $tasks[$i]->opp_percent = $obj->opp_percent;
1066 $tasks[$i]->budget_amount = $obj->budget_amount;
1067 $tasks[$i]->project_budget_amount = $obj->project_budget_amount;
1068 $tasks[$i]->usage_bill_time = $obj->usage_bill_time;
1070 $tasks[$i]->label = $obj->label;
1071 $tasks[$i]->description = $obj->description;
1072 $tasks[$i]->fk_task_parent = $obj->fk_task_parent;
1073 $tasks[$i]->duration_effective = $obj->duration_effective;
1074 $tasks[$i]->planned_workload = $obj->planned_workload;
1076 if ($includebilltime) {
1078 $tasks[$i]->tobill = $obj->tobill;
1079 $tasks[$i]->billed = $obj->billed;
1082 $tasks[$i]->progress = $obj->progress;
1083 $tasks[$i]->fk_statut = $obj->status;
1084 $tasks[$i]->public = $obj->public;
1085 $tasks[$i]->date_start = $this->db->jdate($obj->date_start);
1086 $tasks[$i]->date_end = $this->db->jdate($obj->date_end);
1087 $tasks[$i]->rang = $obj->rang;
1089 $tasks[$i]->socid = $obj->thirdparty_id;
1090 $tasks[$i]->thirdparty_id = $obj->thirdparty_id;
1091 $tasks[$i]->thirdparty_name = $obj->thirdparty_name;
1092 $tasks[$i]->thirdparty_email = $obj->thirdparty_email;
1095 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1096 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1097 if ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate') {
1098 $tmpvar =
'options_'.$key;
1099 $tasks[$i]->array_options_project[
'options_'.$key] = $obj->$tmpvar;
1117 $tasks[$i]->fetch_optionals();
1123 $this->db->free($resql);
1143 $arrayroles = array();
1145 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks userp=".is_object($userp).
" usert=".is_object($usert).
" projectid=".$projectid.
" taskid=".$taskid);
1148 if (empty($userp) && empty($usert)) {
1149 $this->error =
"CallWithWrongParameters";
1152 if (!empty($userp) && !empty($usert)) {
1153 $this->error =
"CallWithWrongParameters";
1158 $sql =
"SELECT pt.rowid as pid, ec.element_id, ctc.code, ctc.source";
1160 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as pt";
1162 if ($usert && $filteronprojstatus > -1) {
1163 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p, ".MAIN_DB_PREFIX.
"projet_task as pt";
1165 if ($usert && $filteronprojstatus <= -1) {
1166 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as pt";
1168 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1169 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1170 $sql .=
" WHERE pt.rowid = ec.element_id";
1171 if ($userp && $filteronprojstatus > -1) {
1172 $sql .=
" AND pt.fk_statut = ".((int) $filteronprojstatus);
1174 if ($usert && $filteronprojstatus > -1) {
1175 $sql .=
" AND pt.fk_projet = p.rowid AND p.fk_statut = ".((int) $filteronprojstatus);
1178 $sql .=
" AND ctc.element = 'project'";
1181 $sql .=
" AND ctc.element = 'project_task'";
1183 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
1185 $sql .=
" AND ec.fk_socpeople = ".((int) $userp->id);
1188 $sql .=
" AND ec.fk_socpeople = ".((int) $usert->id);
1190 $sql .=
" AND ec.statut = 4";
1191 $sql .=
" AND ctc.source = 'internal'";
1194 $sql .=
" AND pt.rowid IN (".$this->db->sanitize($projectid).
")";
1197 $sql .=
" AND pt.fk_projet IN (".$this->db->sanitize($projectid).
")";
1202 $sql .=
" ERROR SHOULD NOT HAPPENS";
1205 $sql .=
" AND pt.rowid = ".((int) $taskid);
1210 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG);
1211 $resql = $this->db->query(
$sql);
1213 $num = $this->db->num_rows($resql);
1216 $obj = $this->db->fetch_object($resql);
1217 if (empty($arrayroles[$obj->pid])) {
1218 $arrayroles[$obj->pid] = $obj->code;
1220 $arrayroles[$obj->pid] .=
','.$obj->code;
1224 $this->db->free($resql);
1241 $contactAlreadySelected = array();
1247 if ($source ==
'thirdparty') {
1248 $contactAlreadySelected[$i] = $tab[$i][
'socid'];
1250 $contactAlreadySelected[$i] = $tab[$i][
'id'];
1254 return $contactAlreadySelected;
1267 global $conf, $langs;
1269 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1275 if (!is_object($user)) {
1276 dol_print_error(
'',
"Method addTimeSpent was called with wrong parameter user");
1281 if (isset($this->timespent_note)) {
1282 $this->timespent_note = trim($this->timespent_note);
1284 if (empty($this->timespent_datehour) || ($this->timespent_date != $this->timespent_datehour)) {
1285 $this->timespent_datehour = $this->timespent_date;
1288 if (!empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1289 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1292 if ($this->timespent_date < $restrictBefore) {
1293 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1294 $this->errors[] = $this->error;
1303 $timespent->fk_element = $this->id;
1304 $timespent->elementtype =
'task';
1305 $timespent->element_date = $this->timespent_date;
1306 $timespent->element_datehour = $this->timespent_datehour;
1307 $timespent->element_date_withhour = $this->timespent_withhour;
1308 $timespent->element_duration = $this->timespent_duration;
1309 $timespent->fk_user = $this->timespent_fk_user;
1310 $timespent->fk_product = $this->timespent_fk_product;
1311 $timespent->note = $this->timespent_note;
1312 $timespent->datec = $this->db->idate($now);
1314 if ($timespent->create($user) > 0) {
1315 $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"element_time");
1316 $ret = $tasktime_id;
1317 $this->timespent_id = $ret;
1321 $result = $this->
call_trigger(
'TASK_TIMESPENT_CREATE', $user);
1328 $this->error = $this->db->lasterror();
1334 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1335 $sql .=
" SET duration_effective = (SELECT SUM(element_duration) FROM ".MAIN_DB_PREFIX.
"element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = ".((int) $this->
id).
")";
1336 if (isset($this->progress)) {
1337 $sql .=
", progress = ".((float) $this->progress);
1339 $sql .=
" WHERE rowid = ".((int) $this->
id);
1341 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1342 if (!$this->db->query(
$sql)) {
1343 $this->error = $this->db->lasterror();
1348 $resql_thm_user = $this->db->query(
"SELECT thm FROM " . MAIN_DB_PREFIX .
"user WHERE rowid = " . ((
int) $timespent->fk_user));
1349 if (!empty($resql_thm_user)) {
1350 $obj_thm_user = $this->db->fetch_object($resql_thm_user);
1351 $timespent->thm = $obj_thm_user->thm;
1353 $res_update = $timespent->update($user);
1355 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1356 if ($res_update <= 0) {
1357 $this->error = $this->db->lasterror();
1363 $this->db->commit();
1365 $this->db->rollback();
1380 $arrayres = array();
1383 $sql .=
" s.rowid as socid,";
1384 $sql .=
" s.nom as thirdparty_name,";
1385 $sql .=
" s.email as thirdparty_email,";
1386 $sql .=
" ptt.rowid,";
1387 $sql .=
" ptt.ref_ext,";
1388 $sql .=
" ptt.fk_element as fk_task,";
1389 $sql .=
" ptt.element_date as task_date,";
1390 $sql .=
" ptt.element_datehour as task_datehour,";
1391 $sql .=
" ptt.element_date_withhour as task_date_withhour,";
1392 $sql .=
" ptt.element_duration as task_duration,";
1393 $sql .=
" ptt.fk_user,";
1394 $sql .=
" ptt.note,";
1395 $sql .=
" ptt.thm,";
1396 $sql .=
" pt.rowid as task_id,";
1397 $sql .=
" pt.ref as task_ref,";
1398 $sql .=
" pt.label as task_label,";
1399 $sql .=
" p.rowid as project_id,";
1400 $sql .=
" p.ref as project_ref,";
1401 $sql .=
" p.title as project_label,";
1402 $sql .=
" p.public as public";
1403 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
1404 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1405 $sql .=
" WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid";
1406 $sql .=
" AND ptt.elementtype = 'task'";
1407 $sql .=
" AND pt.rowid = ".((int) $this->
id);
1408 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
1409 if ($morewherefilter) {
1410 $sql .= $morewherefilter;
1413 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
1414 $resql = $this->db->query(
$sql);
1416 $num = $this->db->num_rows($resql);
1420 $obj = $this->db->fetch_object($resql);
1422 $newobj =
new stdClass();
1424 $newobj->socid = $obj->socid;
1425 $newobj->thirdparty_name = $obj->thirdparty_name;
1426 $newobj->thirdparty_email = $obj->thirdparty_email;
1428 $newobj->fk_project = $obj->project_id;
1429 $newobj->project_ref = $obj->project_ref;
1430 $newobj->project_label = $obj->project_label;
1431 $newobj->public = $obj->project_public;
1433 $newobj->fk_task = $obj->task_id;
1434 $newobj->task_ref = $obj->task_ref;
1435 $newobj->task_label = $obj->task_label;
1437 $newobj->timespent_line_id = $obj->rowid;
1438 $newobj->timespent_line_ref_ext = $obj->ref_ext;
1439 $newobj->timespent_line_date = $this->db->jdate($obj->task_date);
1440 $newobj->timespent_line_datehour = $this->db->jdate($obj->task_datehour);
1441 $newobj->timespent_line_withhour = $obj->task_date_withhour;
1442 $newobj->timespent_line_duration = $obj->task_duration;
1443 $newobj->timespent_line_fk_user = $obj->fk_user;
1444 $newobj->timespent_line_thm = $obj->thm;
1445 $newobj->timespent_line_note = $obj->note;
1447 $arrayres[] = $newobj;
1452 $this->db->free($resql);
1454 $this->lines = $arrayres;
1458 $this->error =
"Error ".$this->db->lasterror();
1473 if (is_object($userobj)) {
1474 $userid = $userobj->id;
1480 if (empty($id) && empty($userid)) {
1481 dol_syslog(
"getSummaryOfTimeSpent called on a not loaded task without user param defined", LOG_ERR);
1488 $sql .=
" MIN(t.element_datehour) as min_date,";
1489 $sql .=
" MAX(t.element_datehour) as max_date,";
1490 $sql .=
" SUM(t.element_duration) as total_duration,";
1491 $sql .=
" SUM(t.element_duration / 3600 * ".$this->db->ifsql(
"t.thm IS NULL", 0,
"t.thm").
") as total_amount,";
1492 $sql .=
" COUNT(t.rowid) as nblines,";
1493 $sql .=
" SUM(".$this->db->ifsql(
"t.thm IS NULL", 1, 0).
") as nblinesnull";
1494 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as t";
1495 $sql .=
" WHERE t.elementtype='task'";
1496 if ($morewherefilter) {
1497 $sql .= $morewherefilter;
1500 $sql .=
" AND t.fk_element = ".((int) $id);
1503 $sql .=
" AND t.fk_user = ".((int) $userid);
1506 dol_syslog(get_class($this).
"::getSummaryOfTimeSpent", LOG_DEBUG);
1507 $resql = $this->db->query(
$sql);
1509 $obj = $this->db->fetch_object($resql);
1511 $result[
'min_date'] = $obj->min_date;
1512 $result[
'max_date'] = $obj->max_date;
1513 $result[
'total_duration'] = $obj->total_duration;
1515 $this->timespent_min_date = $this->db->jdate($obj->min_date);
1516 $this->timespent_max_date = $this->db->jdate($obj->max_date);
1517 $this->timespent_total_duration = $obj->total_duration;
1518 $this->timespent_total_amount = $obj->total_amount;
1519 $this->timespent_nblinesnull = ($obj->nblinesnull ? $obj->nblinesnull : 0);
1520 $this->timespent_nblines = ($obj->nblines ? $obj->nblines : 0);
1522 $this->db->free($resql);
1548 $sql .=
" SUM(t.element_duration) as nbseconds,";
1549 $sql .=
" SUM(t.element_duration / 3600 * ".$this->db->ifsql(
"t.thm IS NULL", 0,
"t.thm").
") as amount, SUM(".$this->db->ifsql(
"t.thm IS NULL", 1, 0).
") as nblinesnull";
1550 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as t";
1551 $sql .=
" WHERE t.elementtype='task' AND t.fk_element = ".((int) $id);
1552 if (is_object($fuser) && $fuser->id > 0) {
1553 $sql .=
" AND fk_user = ".((int) $fuser->id);
1556 $datefieldname =
"element_datehour";
1557 $sql .=
" AND (".$datefieldname.
" >= '".$this->db->idate($dates).
"' OR ".$datefieldname.
" IS NULL)";
1560 $datefieldname =
"element_datehour";
1561 $sql .=
" AND (".$datefieldname.
" <= '".$this->db->idate(
$datee).
"' OR ".$datefieldname.
" IS NULL)";
1565 dol_syslog(get_class($this).
"::getSumOfAmount", LOG_DEBUG);
1566 $resql = $this->db->query(
$sql);
1568 $obj = $this->db->fetch_object($resql);
1570 $result[
'amount'] = $obj->amount;
1571 $result[
'nbseconds'] = $obj->nbseconds;
1572 $result[
'nblinesnull'] = $obj->nblinesnull;
1574 $this->db->free($resql);
1593 $timespent->fetch($id);
1595 dol_syslog(get_class($this).
"::fetchTimeSpent", LOG_DEBUG);
1597 if ($timespent->id > 0) {
1598 $this->timespent_id = $timespent->id;
1599 $this->
id = $timespent->fk_element;
1600 $this->timespent_date = $this->db->jdate($timespent->element_date);
1601 $this->timespent_datehour = $this->db->jdate($timespent->element_datehour);
1602 $this->timespent_withhour = $timespent->element_date_withhour;
1603 $this->timespent_duration = $timespent->element_duration;
1604 $this->timespent_fk_user = $timespent->fk_user;
1605 $this->timespent_fk_product = $timespent->fk_product;
1606 $this->timespent_thm = $timespent->thm;
1607 $this->timespent_note = $timespent->note;
1624 $arrayres = array();
1627 $sql .=
" s.rowid as socid,";
1628 $sql .=
" s.nom as thirdparty_name,";
1629 $sql .=
" s.email as thirdparty_email,";
1630 $sql .=
" ptt.rowid,";
1631 $sql .=
" ptt.fk_element as fk_task,";
1632 $sql .=
" ptt.element_date as task_date,";
1633 $sql .=
" ptt.element_datehour as task_datehour,";
1634 $sql .=
" ptt.element_date_withhour as task_date_withhour,";
1635 $sql .=
" ptt.element_duration as task_duration,";
1636 $sql .=
" ptt.fk_user,";
1637 $sql .=
" ptt.note,";
1638 $sql .=
" ptt.thm,";
1639 $sql .=
" pt.rowid as task_id,";
1640 $sql .=
" pt.ref as task_ref,";
1641 $sql .=
" pt.label as task_label,";
1642 $sql .=
" p.rowid as project_id,";
1643 $sql .=
" p.ref as project_ref,";
1644 $sql .=
" p.title as project_label,";
1645 $sql .=
" p.public as public";
1646 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
1647 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1648 $sql .=
" WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid";
1649 $sql .=
" AND ptt.elementtype = 'task'";
1650 $sql .=
" AND ptt.fk_user = ".((int) $userobj->id);
1651 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
1652 if ($morewherefilter) {
1653 $sql .= $morewherefilter;
1656 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
1657 $resql = $this->db->query(
$sql);
1659 $num = $this->db->num_rows($resql);
1663 $obj = $this->db->fetch_object($resql);
1665 $newobj =
new stdClass();
1667 $newobj->socid = $obj->socid;
1668 $newobj->thirdparty_name = $obj->thirdparty_name;
1669 $newobj->thirdparty_email = $obj->thirdparty_email;
1671 $newobj->fk_project = $obj->project_id;
1672 $newobj->project_ref = $obj->project_ref;
1673 $newobj->project_label = $obj->project_label;
1674 $newobj->public = $obj->project_public;
1676 $newobj->fk_task = $obj->task_id;
1677 $newobj->task_ref = $obj->task_ref;
1678 $newobj->task_label = $obj->task_label;
1680 $newobj->timespent_id = $obj->rowid;
1681 $newobj->timespent_date = $this->db->jdate($obj->task_date);
1682 $newobj->timespent_datehour = $this->db->jdate($obj->task_datehour);
1683 $newobj->timespent_withhour = $obj->task_date_withhour;
1684 $newobj->timespent_duration = $obj->task_duration;
1685 $newobj->timespent_fk_user = $obj->fk_user;
1686 $newobj->timespent_thm = $obj->thm;
1687 $newobj->timespent_note = $obj->note;
1689 $arrayres[] = $newobj;
1694 $this->db->free($resql);
1697 $this->error =
"Error ".$this->db->lasterror();
1713 global $conf, $langs;
1718 if ($this->timespent_date ==
'') {
1719 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Date"));
1722 if (!($this->timespent_fk_user > 0)) {
1723 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"User"));
1728 if (empty($this->timespent_datehour)) {
1729 $this->timespent_datehour = $this->timespent_date;
1731 if (isset($this->timespent_note)) {
1732 $this->timespent_note = trim($this->timespent_note);
1735 if (!empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1736 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1739 if ($this->timespent_date < $restrictBefore) {
1740 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1741 $this->errors[] = $this->error;
1749 $timespent->fetch($this->timespent_id);
1750 $timespent->element_date = $this->timespent_date;
1751 $timespent->element_datehour = $this->timespent_datehour;
1752 $timespent->element_date_withhour = $this->timespent_withhour;
1753 $timespent->element_duration = $this->timespent_duration;
1754 $timespent->fk_user = $this->timespent_fk_user;
1755 $timespent->fk_product = $this->timespent_fk_product;
1756 $timespent->note = $this->timespent_note;
1757 $timespent->invoice_id = $this->timespent_invoiceid;
1758 $timespent->invoice_line_id = $this->timespent_invoicelineid;
1760 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
1761 if ($timespent->update($user) > 0) {
1764 $result = $this->
call_trigger(
'TASK_TIMESPENT_MODIFY', $user);
1766 $this->db->rollback();
1776 $this->error = $this->db->lasterror();
1777 $this->db->rollback();
1781 if ($ret == 1 && (($this->timespent_old_duration != $this->timespent_duration) || !empty($conf->global->TIMESPENT_ALWAYS_UPDATE_THM))) {
1782 if ($this->timespent_old_duration != $this->timespent_duration) {
1784 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"projet_task";
1785 $sql .=
" SET duration_effective = (SELECT SUM(element_duration) FROM " . MAIN_DB_PREFIX .
"element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = " . ((int) $this->
id) .
")";
1786 if (isset($this->progress)) {
1787 $sql .=
", progress = " . ((
float) $this->progress);
1789 $sql .=
" WHERE rowid = " . ((int) $this->
id);
1791 dol_syslog(get_class($this) .
"::updateTimeSpent", LOG_DEBUG);
1792 if (!$this->db->query(
$sql)) {
1793 $this->error = $this->db->lasterror();
1794 $this->db->rollback();
1801 if (empty($timespent->thm) || !empty($conf->global->TIMESPENT_ALWAYS_UPDATE_THM)) {
1802 $resql_thm_user = $this->db->query(
"SELECT thm FROM " . MAIN_DB_PREFIX .
"user WHERE rowid = " . ((
int) $timespent->fk_user));
1803 if (!empty($resql_thm_user)) {
1804 $obj_thm_user = $this->db->fetch_object($resql_thm_user);
1805 $timespent->thm = $obj_thm_user->thm;
1807 $res_update = $timespent->update($user);
1810 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
1811 if ($res_update <= 0) {
1812 $this->error = $this->db->lasterror();
1818 $this->db->commit();
1832 global $conf, $langs;
1836 if (!empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1837 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1840 if ($this->timespent_date < $restrictBefore) {
1841 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1842 $this->errors[] = $this->error;
1851 $result = $this->
call_trigger(
'TASK_TIMESPENT_DELETE', $user);
1860 $timespent->fetch($this->timespent_id);
1862 $res_del = $timespent->delete($user);
1865 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
1870 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1871 $sql .=
" SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration ? $this->timespent_duration : 0);
1872 $sql .=
" WHERE rowid = ".((int) $this->
id);
1874 dol_syslog(get_class($this).
"::delTimeSpent", LOG_DEBUG);
1875 if ($this->db->query(
$sql)) {
1878 $this->error = $this->db->lasterror();
1885 foreach ($this->errors as $errmsg) {
1886 dol_syslog(get_class($this).
"::delTimeSpent ".$errmsg, LOG_ERR);
1887 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1889 $this->db->rollback();
1892 $this->db->commit();
1911 public function createFromClone(
User $user, $fromid, $project_id, $parent_task_id, $clone_change_dt =
false, $clone_affectation =
false, $clone_time =
false, $clone_file =
false, $clone_note =
false, $clone_prog =
false)
1913 global $langs, $conf;
1922 $clone_task =
new Task($this->db);
1923 $origin_task =
new Task($this->db);
1925 $clone_task->context[
'createfromclone'] =
'createfromclone';
1930 $clone_task->fetch($fromid);
1931 $clone_task->fetch_optionals();
1934 $origin_task->fetch($fromid);
1937 $obj = empty($conf->global->PROJECT_TASK_ADDON) ?
'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON;
1938 if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT.
"/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.
".php")) {
1939 require_once DOL_DOCUMENT_ROOT.
"/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.
'.php';
1940 $modTask =
new $obj;
1941 $defaultref = $modTask->getNextValue(0, $clone_task);
1944 $ori_project_id = $clone_task->fk_project;
1946 $clone_task->id = 0;
1947 $clone_task->ref = $defaultref;
1948 $clone_task->fk_project = $project_id;
1949 $clone_task->fk_task_parent = $parent_task_id;
1950 $clone_task->date_c = $datec;
1951 $clone_task->planned_workload = $origin_task->planned_workload;
1952 $clone_task->rang = $origin_task->rang;
1955 if ($clone_change_dt) {
1956 $projectstatic =
new Project($this->db);
1957 $projectstatic->fetch($ori_project_id);
1960 $orign_project_dt_start = $projectstatic->date_start;
1963 if (!empty($clone_task->date_start)) {
1964 $clone_task->date_start = $now + $clone_task->date_start - $orign_project_dt_start;
1968 if (!empty($clone_task->date_end)) {
1969 $clone_task->date_end = $now + $clone_task->date_end - $orign_project_dt_start;
1974 $clone_task->progress = 0;
1978 $result = $clone_task->create($user);
1982 $this->error = $clone_task->error;
1988 $clone_task_id = $clone_task->id;
1989 $clone_task_ref = $clone_task->ref;
1993 $clone_task->note_private =
'';
1994 $clone_task->note_public =
'';
1997 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
1999 $this->error .= $clone_task->error;
2001 $this->db->rollback();
2003 $this->db->commit();
2007 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
2009 $this->error .= $clone_task->error;
2011 $this->db->rollback();
2013 $this->db->commit();
2019 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2022 $projectstatic =
new Project($this->db);
2023 $projectstatic->fetch($ori_project_id);
2024 $ori_project_ref = $projectstatic->ref;
2026 if ($ori_project_id != $project_id) {
2027 $projectstatic->fetch($project_id);
2028 $clone_project_ref = $projectstatic->ref;
2030 $clone_project_ref = $ori_project_ref;
2036 $filearray =
dol_dir_list($ori_task_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
2037 foreach ($filearray as $key => $file) {
2038 if (!file_exists($clone_task_dir)) {
2040 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
2045 $rescopy =
dol_copy($ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name'], 0, 1);
2046 if (is_numeric($rescopy) && $rescopy < 0) {
2047 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name']);
2054 if ($clone_affectation) {
2055 $origin_task =
new Task($this->db);
2056 $origin_task->fetch($fromid);
2058 foreach (array(
'internal',
'external') as $source) {
2059 $tab = $origin_task->liste_contact(-1, $source);
2063 $clone_task->add_contact($tab[$i][
'id'], $tab[$i][
'code'], $tab[$i][
'source']);
2064 if ($clone_task->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
2065 $langs->load(
"errors");
2066 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
2069 if ($clone_task->error !=
'') {
2070 $this->error .= $clone_task->error;
2084 unset($clone_task->context[
'createfromclone']);
2087 $this->db->commit();
2088 return $clone_task_id;
2090 $this->db->rollback();
2091 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
2105 return $this->
LibStatut($this->fk_statut, $mode);
2122 $this->statuts[0] =
'Draft';
2123 $this->statuts[1] =
'ToDo';
2124 $this->statuts[2] =
'Running';
2125 $this->statuts[3] =
'Finish';
2126 $this->statuts[4] =
'Transfered';
2127 $this->statuts_short[0] =
'Draft';
2128 $this->statuts_short[1] =
'ToDo';
2129 $this->statuts_short[2] =
'Running';
2130 $this->statuts_short[3] =
'Completed';
2131 $this->statuts_short[4] =
'Transfered';
2134 return $langs->trans($this->statuts[$status]);
2135 } elseif ($mode == 1) {
2136 return $langs->trans($this->statuts_short[$status]);
2137 } elseif ($mode == 2) {
2139 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0').
' '.$langs->trans($this->statuts_short[$status]);
2140 } elseif ($status == 1) {
2141 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1').
' '.$langs->trans($this->statuts_short[$status]);
2142 } elseif ($status == 2) {
2143 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3').
' '.$langs->trans($this->statuts_short[$status]);
2144 } elseif ($status == 3) {
2145 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts_short[$status]);
2146 } elseif ($status == 4) {
2147 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts_short[$status]);
2148 } elseif ($status == 5) {
2149 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5').
' '.$langs->trans($this->statuts_short[$status]);
2151 } elseif ($mode == 3) {
2153 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0');
2154 } elseif ($status == 1) {
2155 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1');
2156 } elseif ($status == 2) {
2157 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3');
2158 } elseif ($status == 3) {
2159 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6');
2160 } elseif ($status == 4) {
2161 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6');
2162 } elseif ($status == 5) {
2163 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5');
2165 } elseif ($mode == 4) {
2167 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0').
' '.$langs->trans($this->statuts[$status]);
2168 } elseif ($status == 1) {
2169 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1').
' '.$langs->trans($this->statuts[$status]);
2170 } elseif ($status == 2) {
2171 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3').
' '.$langs->trans($this->statuts[$status]);
2172 } elseif ($status == 3) {
2173 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts[$status]);
2174 } elseif ($status == 4) {
2175 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts[$status]);
2176 } elseif ($status == 5) {
2177 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5').
' '.$langs->trans($this->statuts[$status]);
2179 } elseif ($mode == 5) {
2189 } elseif ($mode == 6) {
2213 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2217 $outputlangs->load(
"projects");
2220 $modele =
'nodefault';
2222 if (!empty($this->model_pdf)) {
2223 $modele = $this->model_pdf;
2224 } elseif (!empty($this->modelpdf)) {
2225 $modele = $this->modelpdf;
2226 } elseif (!empty($conf->global->PROJECT_TASK_ADDON_PDF)) {
2227 $modele = $conf->global->PROJECT_TASK_ADDON_PDF;
2231 $modelpath =
"core/modules/project/task/doc/";
2233 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2247 global $conf, $langs;
2253 $projectstatic =
new Project($this->db);
2254 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
2257 $sql =
"SELECT p.rowid as projectid, p.fk_statut as projectstatus,";
2258 $sql .=
" t.rowid as taskid, t.progress as progress, t.fk_statut as status,";
2259 $sql .=
" t.dateo as date_start, t.datee as datee";
2260 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2263 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2264 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2265 $sql .=
" AND p.fk_statut = 1";
2266 $sql .=
" AND t.fk_projet = p.rowid";
2267 $sql .=
" AND (t.progress IS NULL OR t.progress < 100)";
2268 if (empty($user->rights->projet->all->lire)) {
2269 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2277 $resql = $this->db->query(
$sql);
2279 $task_static =
new Task($this->db);
2282 $response->warning_delay = $conf->project->task->warning_delay / 60 / 60 / 24;
2283 $response->label = $langs->trans(
"OpenedTasks");
2284 if ($user->hasRight(
"projet",
"all",
"lire")) {
2285 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mainmenu=project';
2287 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mode=mine&mainmenu=project';
2292 while ($obj = $this->db->fetch_object($resql)) {
2293 $response->nbtodo++;
2295 $task_static->projectstatus = $obj->projectstatus;
2296 $task_static->progress = $obj->progress;
2297 $task_static->fk_statut = $obj->status;
2298 $task_static->date_end = $this->db->jdate($obj->datee);
2300 if ($task_static->hasDelay()) {
2301 $response->nbtodolate++;
2307 $this->error = $this->db->error();
2324 $mine = 0; $socid = $user->socid;
2326 $projectstatic =
new Project($this->db);
2327 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, $mine, 1, $socid);
2330 $sql =
"SELECT count(p.rowid) as nb";
2331 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2332 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
2333 if (empty($user->rights->societe->client->voir) && !$socid) {
2334 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON sc.fk_soc = s.rowid";
2336 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2337 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2338 $sql .=
" AND t.fk_projet = p.rowid";
2339 if ($mine || empty($user->rights->projet->all->lire)) {
2340 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2345 $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).
")";
2347 if (empty($user->rights->societe->client->voir) && !$socid) {
2348 $sql .=
" AND ((s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id).
") OR (s.rowid IS NULL))";
2351 $resql = $this->db->query(
$sql);
2354 while ($obj = $this->db->fetch_object($resql)) {
2355 $this->nb[
"tasks"] = $obj->nb;
2357 $this->db->free($resql);
2361 $this->error = $this->db->error();
2375 if (!($this->progress >= 0 && $this->progress < 100)) {
2381 $datetouse = ($this->date_end > 0) ? $this->date_end : ((isset($this->datee) && $this->datee > 0) ? $this->datee : 0);
2383 return ($datetouse > 0 && ($datetouse < ($now - $conf->project->task->warning_delay)));
2395 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2397 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2398 $return .=
'<div class="info-box info-box-sm info-box-kanban">';
2399 $return .=
'<span class="info-box-icon bg-infobox-action">';
2402 $return .=
'</span>';
2403 $return .=
'<div class="info-box-content">';
2404 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2405 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2406 if (!empty($arraydata[
'projectlink'])) {
2409 $return .=
'<br><span class="info-box-status ">'.$arraydata[
'projectlink'].
'</span>';
2411 if (property_exists($this,
'budget_amount')) {
2414 if (property_exists($this,
'duration_effective')) {
2415 $return .=
'<br><br><div class="info-box-label progressinkanban">'.getTaskProgressView($this,
false,
true).
'</div>';
2417 $return .=
'</div>';
2418 $return .=
'</div>';
2419 $return .=
'</div>';
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
isObjectUsed($id=0, $entity=0)
Function to check if an object is used by others (by children).
liste_contact($statusoflink=-1, $source='external', $list=0, $code='', $status=-1, $arrayoftcids=array())
Get array of all contacts for an object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage projects.
const STATUS_VALIDATED
Open/Validated status.
create($user, $notrigger=0)
Create into database.
fetch($id, $ref='', $loadparentdata=0)
Load object in memory from database.
getLibStatut($mode=0)
Return status label of object.
getSumOfAmount($fuser='', $dates='', $datee='')
Calculate quantity and value of time consumed using the thm (hourly amount value of work for user ent...
__construct($db)
Constructor.
fetchTimeSpentOnTask($morewherefilter='')
Fetch records of time spent of this task.
hasTimeSpent()
Return nb of time spent.
getNomUrl($withpicto=0, $option='', $mode='task', $addlabel=0, $sep=' - ', $notooltip=0, $save_lastsearch_value=-1)
Return clicable name (with picto eventually)
getListContactId($source='internal')
Return list of id of contacts of task.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
delTimeSpent($user, $notrigger=0)
Delete time spent.
getTasksArray($usert=null, $userp=null, $projectid=0, $socid=0, $mode=0, $filteronproj='', $filteronprojstatus='-1', $morewherefilter='', $filteronprojuser=0, $filterontaskuser=0, $extrafields=array(), $includebilltime=0, $search_array_options=array(), $loadextras=0, $loadRoleMode=1, $sortfield='', $sortorder='')
Return list of tasks for all projects or for one particular project Sort order is on project,...
fetchAllTimeSpent(User $userobj, $morewherefilter='')
Load all records of time spent.
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
getUserRolesForProjectsOrTasks($userp, $usert, $projectid='', $taskid=0, $filteronprojstatus=-1)
Return list of roles for a user for each projects or each tasks (or a particular project or a particu...
update($user=null, $notrigger=0)
Update database.
getSummaryOfTimeSpent($userobj=null, $morewherefilter='')
Calculate total of time spent for task.
getTooltipContentArray($params)
getTooltipContentArray
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Create an intervention document on disk using template defined into PROJECT_TASK_ADDON_PDF.
fetchTimeSpent($id)
Load properties of timespent of a task from the time spent ID.
updateTimeSpent($user, $notrigger=0)
Update time spent.
createFromClone(User $user, $fromid, $project_id, $parent_task_id, $clone_change_dt=false, $clone_affectation=false, $clone_time=false, $clone_file=false, $clone_note=false, $clone_prog=false)
Load an object from its id and create a new one in database.
initAsSpecimen()
Initialise an instance with random values.
load_state_board()
Charge indicateurs this->nb de tableau de bord.
addTimeSpent($user, $notrigger=0)
Add time spent.
hasDelay()
Is the task delayed?
LibStatut($status, $mode=0)
Return status label for an object.
hasChildren()
Return nb of children.
Class to manage Dolibarr users.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_move_dir($srcdir, $destdir, $overwriteifexists=1, $indexdatabase=1, $renamedircontent=1)
Move a directory into another name.
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
div float
Buy price without taxes.