32require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
33require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
34require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
35require_once DOL_DOCUMENT_ROOT.
'/core/class/timespent.class.php';
46 public $element =
'project_task';
51 public $table_element =
'projet_task';
56 public $fk_element =
'fk_element';
61 public $picto =
'projecttask';
66 protected $childtables = array(
67 'element_time' => array(
'name' =>
'Task',
'parent' =>
'projet_task',
'parentkey' =>
'fk_element',
'parenttypefield' =>
'elementtype',
'parenttypevalue' =>
'task')
73 public $fk_task_parent = 0;
88 public $duration_effective;
93 public $planned_workload;
152 public $fk_user_creat;
157 public $fk_user_valid;
167 public $timespent_min_date;
171 public $timespent_max_date;
175 public $timespent_total_duration;
179 public $timespent_total_amount;
183 public $timespent_nblinesnull;
187 public $timespent_nblines;
194 public $timespent_id;
198 public $timespent_duration;
202 public $timespent_old_duration;
206 public $timespent_date;
210 public $timespent_datehour;
215 public $timespent_withhour;
220 public $timespent_fk_user;
224 public $timespent_thm;
228 public $timespent_note;
232 public $timespent_fk_product;
236 public $timespent_invoiceid;
240 public $timespent_invoicelineid;
242 public $comments = array();
264 public $projectstatus;
269 public $projectlabel;
284 public $fk_opp_status;
289 public $usage_bill_time;
299 public $array_options_project;
313 public $thirdparty_id;
318 public $thirdparty_name;
323 public $thirdparty_email;
329 public $task_parent_ref;
334 public $task_parent_position;
340 public $billable = 1;
345 public $budget_amount;
350 public $project_budget_amount;
392 $this->labelStatus = array(
399 $this->labelStatusShort = array(
416 public function create($user, $notrigger = 0)
418 global
$conf, $langs;
426 $this->label = trim((
string) $this->label);
428 $this->note_public = trim((
string) $this->note_public);
429 $this->note_private = trim((
string) $this->note_private);
431 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
432 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
437 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet_task (";
439 $sql .=
", fk_projet";
441 $sql .=
", fk_task_parent";
443 $sql .=
", description";
444 $sql .=
", note_public";
445 $sql .=
", note_private";
447 $sql .=
", fk_user_creat";
450 $sql .=
", planned_workload";
451 $sql .=
", progress";
452 $sql .=
", budget_amount";
453 $sql .=
", priority";
454 $sql .=
", billable";
455 $sql .=
", fk_statut";
457 $sql .=
") VALUES (";
458 $sql .= (!empty($this->entity) ? (int) $this->entity : (int)
$conf->entity);
459 $sql .=
", ".((int) $this->fk_project);
460 $sql .=
", ".(!empty($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
'null');
461 $sql .=
", ".((int) $this->fk_task_parent);
462 $sql .=
", '".$this->db->escape($this->label).
"'";
463 $sql .=
", '".$this->db->escape($this->description).
"'";
464 $sql .=
", '".$this->db->escape($this->note_public).
"'";
465 $sql .=
", '".$this->db->escape($this->note_private).
"'";
466 $sql .=
", '".$this->db->idate($now).
"'";
467 $sql .=
", ".((int) $user->id);
468 $sql .=
", ".(isDolTms($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
469 $sql .=
", ".(isDolTms($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
470 $sql .=
", ".(($this->planned_workload !=
'' && $this->planned_workload >= 0) ? ((
int) $this->planned_workload) :
'null');
471 $sql .=
", ".(($this->progress !=
'' && $this->progress >= 0) ? ((
int) $this->progress) :
'null');
472 $sql .=
", ".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? ((
int) $this->budget_amount) :
'null');
473 $sql .=
", ".(($this->priority !=
'' && $this->priority >= 0) ? (
int) $this->priority :
'null');
474 $sql .=
", ".((int) $this->billable);
475 $sql .=
", ".((int) $this->
status);
476 $sql .=
", ".((!empty($this->rang)) ? ((
int) $this->rang) :
"0");
481 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
482 $resql = $this->db->query($sql);
485 $this->errors[] =
"Error ".$this->db->lasterror();
489 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"projet_task");
500 $result = $this->call_trigger(
'TASK_CREATE', $user);
510 foreach ($this->errors as $errmsg) {
511 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
512 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
514 $this->db->rollback();
531 public function fetch($id, $ref =
'', $loadparentdata = 0)
536 $sql .=
" t.entity,";
537 $sql .=
" t.fk_projet as fk_project,";
538 $sql .=
" t.fk_task_parent,";
540 $sql .=
" t.description,";
541 $sql .=
" t.duration_effective,";
542 $sql .=
" t.planned_workload,";
544 $sql .=
" t.dateo as date_start,";
545 $sql .=
" t.datee as date_end,";
546 $sql .=
" t.fk_user_creat,";
547 $sql .=
" t.fk_user_valid,";
548 $sql .=
" t.fk_statut as status,";
549 $sql .=
" t.progress,";
550 $sql .=
" t.budget_amount,";
551 $sql .=
" t.priority,";
552 $sql .=
" t.note_private,";
553 $sql .=
" t.note_public,";
555 $sql .=
" t.billable";
556 if (!empty($loadparentdata)) {
557 $sql .=
", t2.ref as task_parent_ref";
558 $sql .=
", t2.rang as task_parent_position";
560 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as t";
561 if (!empty($loadparentdata)) {
562 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t2 ON t.fk_task_parent = t2.rowid";
566 $sql .=
"entity IN (".getEntity(
'project').
")";
567 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
569 $sql .=
"t.rowid = ".((int) $id);
572 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
573 $resql = $this->db->query($sql);
575 $num_rows = $this->db->num_rows($resql);
578 $obj = $this->db->fetch_object($resql);
580 $this->
id = $obj->rowid;
581 $this->
ref = $obj->ref;
582 $this->entity = $obj->entity;
583 $this->fk_project = $obj->fk_project;
584 $this->fk_task_parent = $obj->fk_task_parent;
585 $this->label = $obj->label;
587 $this->duration_effective = $obj->duration_effective;
588 $this->planned_workload = $obj->planned_workload;
589 $this->date_c = $this->db->jdate($obj->datec);
590 $this->date_start = $this->db->jdate($obj->date_start);
591 $this->date_end = $this->db->jdate($obj->date_end);
592 $this->fk_user_creat = $obj->fk_user_creat;
593 $this->fk_user_valid = $obj->fk_user_valid;
594 $this->
status = $obj->status;
595 $this->progress = $obj->progress;
596 $this->budget_amount = $obj->budget_amount;
597 $this->priority = $obj->priority;
598 $this->note_private = $obj->note_private;
599 $this->note_public = $obj->note_public;
600 $this->rang = $obj->rang;
602 if (!empty($loadparentdata)) {
603 $this->task_parent_ref = $obj->task_parent_ref;
604 $this->task_parent_position = $obj->task_parent_position;
606 $this->billable = $obj->billable;
612 $this->db->free($resql);
620 $this->error =
"Error ".$this->db->lasterror();
633 public function update($user =
null, $notrigger = 0)
635 global
$conf, $langs;
639 if (isset($this->fk_project)) {
640 $this->fk_project = (int) $this->fk_project;
642 if (isset($this->
ref)) {
643 $this->
ref = trim($this->
ref);
645 if (isset($this->fk_task_parent)) {
646 $this->fk_task_parent = (int) $this->fk_task_parent;
648 if (isset($this->label)) {
649 $this->label = trim($this->label);
654 if (isset($this->note_public)) {
655 $this->note_public = trim($this->note_public);
657 if (isset($this->note_private)) {
658 $this->note_private = trim($this->note_private);
660 if (isset($this->duration_effective)) {
661 $this->duration_effective = trim($this->duration_effective);
663 if (isset($this->planned_workload)) {
664 $this->planned_workload = trim($this->planned_workload);
666 if (isset($this->budget_amount)) {
667 $this->budget_amount = (float) $this->budget_amount;
670 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
671 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
679 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task SET";
680 $sql .=
" fk_projet=".(isset($this->fk_project) ? ((int) $this->fk_project) :
"null").
",";
681 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"'".$this->db->escape((
string) $this->id).
"'").
",";
682 $sql .=
" fk_task_parent=".(isset($this->fk_task_parent) ? ((int) $this->fk_task_parent) :
"null").
",";
683 $sql .=
" label=".(isset($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
684 $sql .=
" description=".(isset($this->
description) ?
"'".$this->db->escape($this->
description).
"'" :
"null").
",";
685 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
686 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
687 $sql .=
" duration_effective=".(isset($this->duration_effective) ? ((int) $this->duration_effective) :
"null").
",";
688 $sql .=
" planned_workload=".((isset($this->planned_workload) && $this->planned_workload !=
'') ? ((
int) $this->planned_workload) :
"null").
",";
689 $sql .=
" datec=".(isDolTms($this->date_c) ?
"'".$this->db->idate($this->date_c).
"'" :
'null').
",";
690 $sql .=
" dateo=".(isDolTms($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
'null').
",";
691 $sql .=
" datee=".(isDolTms($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
'null').
",";
692 $sql .=
" progress=".(($this->progress !=
'' && $this->progress >= 0) ? ((
int) $this->progress) :
'null').
",";
693 $sql .=
" budget_amount=".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? ((
float) $this->budget_amount) :
'null').
",";
694 $sql .=
" rang=".((!empty($this->rang)) ? ((
int) $this->rang) :
"0").
",";
695 $sql .=
" priority=".((!empty($this->priority)) ? ((
int) $this->priority) :
"0").
",";
696 $sql .=
" billable=".((int) $this->billable).
",";
697 $sql .=
" fk_statut=".((int) $this->
status);
698 $sql .=
" WHERE rowid=".((int) $this->
id);
702 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
703 $resql = $this->db->query($sql);
706 $this->errors[] =
"Error ".$this->db->lasterror();
719 $project =
new Project($this->db);
720 if ($project->fetch($this->fk_project) > 0) {
722 $project->getLinesArray(
null);
723 $projectCompleted = array_reduce(
730 static function ($allTasksCompleted, $task) {
731 return $allTasksCompleted && $task->progress >= 100;
735 if ($projectCompleted) {
736 if ($project->setClose($user) <= 0) {
745 $this->errors[] = $project->error;
752 $result = $this->call_trigger(
'TASK_MODIFY', $user);
760 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) {
762 if (
$conf->project->dir_output) {
763 $project =
new Project($this->db);
764 $project->fetch($this->fk_project);
768 if (file_exists($olddir)) {
769 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
772 $langs->load(
"errors");
773 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
782 foreach ($this->errors as $errmsg) {
783 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
784 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
786 $this->db->rollback();
801 public function delete($user, $notrigger = 0)
804 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
811 dol_syslog(get_class($this).
"::delete Can't delete record as it has some sub tasks", LOG_WARNING);
812 $this->error =
'ErrorRecordHasSubTasks';
813 $this->db->rollback();
818 if (!empty($objectisused)) {
819 dol_syslog(get_class($this).
"::delete Can't delete record as it has some child", LOG_WARNING);
820 $this->error =
'ErrorRecordHasChildren';
821 $this->db->rollback();
829 $this->error =
'ErrorFailToDeleteLinkedContact';
831 $this->db->rollback();
837 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"element_time";
838 $sql .=
" WHERE fk_element = ".((int) $this->
id).
" AND elementtype = 'task'";
840 $resql = $this->db->query($sql);
843 $this->errors[] =
"Error ".$this->db->lasterror();
848 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task_extrafields";
849 $sql .=
" WHERE fk_object = ".((int) $this->
id);
851 $resql = $this->db->query($sql);
854 $this->errors[] =
"Error ".$this->db->lasterror();
859 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task";
860 $sql .=
" WHERE rowid=".((int) $this->
id);
862 $resql = $this->db->query($sql);
865 $this->errors[] =
"Error ".$this->db->lasterror();
872 $result = $this->call_trigger(
'TASK_DELETE', $user);
882 foreach ($this->errors as $errmsg) {
883 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
884 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
886 $this->db->rollback();
890 if (
$conf->project->dir_output) {
891 $projectstatic =
new Project($this->db);
892 $projectstatic->fetch($this->fk_project);
895 dol_syslog(get_class($this).
"::delete dir=".$dir, LOG_DEBUG);
896 if (file_exists($dir)) {
897 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
900 $this->error =
'ErrorFailToDeleteDir';
901 $this->db->rollback();
923 $sql =
"SELECT COUNT(*) as nb";
924 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task";
925 $sql .=
" WHERE fk_task_parent = ".((int) $this->
id);
927 dol_syslog(get_class($this).
"::hasChildren", LOG_DEBUG);
928 $resql = $this->db->query($sql);
931 $this->errors[] =
"Error ".$this->db->lasterror();
933 $obj = $this->db->fetch_object($resql);
937 $this->db->free($resql);
957 $sql =
"SELECT COUNT(*) as nb";
958 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time";
959 $sql .=
" WHERE fk_element = ".((int) $this->
id);
960 $sql .=
" AND elementtype = 'task'";
962 dol_syslog(get_class($this).
"::hasTimeSpent", LOG_DEBUG);
963 $resql = $this->db->query($sql);
966 $this->errors[] =
"Error ".$this->db->lasterror();
968 $obj = $this->db->fetch_object($resql);
972 $this->db->free($resql);
993 $langs->load(
'projects');
996 $datas[
'picto'] = img_picto(
'', $this->picto).
' <u>'.$langs->trans(
"Task").
'</u>';
997 if (!empty($this->
ref)) {
998 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1000 if (!empty($this->label)) {
1001 $datas[
'label'] =
'<br><b>'.$langs->trans(
'LabelTask').
':</b> '.$this->label;
1003 if ($this->date_start || $this->date_end) {
1004 $datas[
'range'] =
"<br>".get_date_range($this->date_start, $this->date_end,
'', $langs, 0);
1022 public function getNomUrl($withpicto = 0, $option =
'', $mode =
'task', $addlabel = 0, $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1)
1024 global $action,
$conf, $hookmanager, $langs;
1026 if (!empty(
$conf->dol_no_mouse_hover)) {
1033 'objecttype' => $this->element,
1035 $classfortooltip =
'classfortooltip';
1038 $classfortooltip =
'classforajaxtooltip';
1039 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1045 $query = [
'id' => $this->id];
1046 if ($option ==
'withproject') {
1047 $query[
'withproject'] = 1;
1050 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1051 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1052 $add_save_lastsearch_values = 1;
1054 if ($add_save_lastsearch_values) {
1055 $query[
'save_lastsearch_values'] = 1;
1057 $url =
dolBuildUrl(DOL_URL_ROOT.
'/projet/tasks/'.$mode.
'.php', $query);
1060 if (empty($notooltip)) {
1062 $label = $langs->trans(
"ShowTask");
1063 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1065 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1066 $linkclose .= $dataparams.
' class="'.$classfortooltip.
' nowraponall"';
1068 $linkclose .=
' class="nowraponall"';
1071 $linkstart =
'<a href="'.$url.
'"';
1072 $linkstart .= $linkclose.
'>';
1075 $picto =
'projecttask';
1077 $result .= $linkstart;
1079 $result .= img_object(($notooltip ?
'' : $label), $picto,
'class="paddingright"', 0, 0, $notooltip ? 0 : 1);
1081 if ($withpicto != 2) {
1082 if ($addlabel >= 0) {
1083 $result .= $this->ref;
1085 $result .= $this->label;
1088 $result .= $linkend;
1089 if ($withpicto != 2) {
1090 $result .= (($addlabel > 0 && $this->label) ?
'<span class="opacitymedium">'.$sep.dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)).
'</span>' :
'');
1093 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1094 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1096 $result = $hookmanager->resPrint;
1098 $result .= $hookmanager->resPrint;
1117 $this->fk_project = 0;
1118 $this->
ref =
'TK01';
1119 $this->fk_task_parent = 0;
1120 $this->label =
'Specimen task TK01';
1121 $this->duration_effective =
'';
1122 $this->fk_user_creat = $user->id;
1123 $this->progress = 25;
1125 $this->priority = 0;
1126 $this->note_private =
'This is a specimen private note';
1127 $this->note_public =
'This is a specimen public note';
1128 $this->billable = 1;
1156 public function getTasksArray($usert =
null, $userp =
null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj =
'', $filteronprojstatus =
'-1', $morewherefilter =
'', $filteronprojuser = 0, $filterontaskuser = 0, $extrafields =
null, $includebilltime = 0, $search_array_options = array(), $loadextras = 0, $loadRoleMode = 1, $sortfield =
'', $sortorder =
'')
1158 global $hookmanager;
1166 if ($filteronprojuser > 0 || $filterontaskuser > 0) {
1167 $sql .=
" DISTINCT";
1169 $sql .=
" p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus, p.usage_bill_time,";
1170 $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,";
1171 $sql .=
" t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang, t.priority,";
1172 $sql .=
" t.budget_amount, t.billable,";
1173 $sql .=
" t.note_public, t.note_private,";
1174 $sql .=
" s.rowid as thirdparty_id, s.nom as thirdparty_name, s.email as thirdparty_email,";
1175 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount as project_budget_amount";
1177 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1178 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1179 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key.
" as options_".$key :
'');
1182 if (!empty($extrafields->attributes[
'projet_task'][
'label'])) {
1183 foreach ($extrafields->attributes[
'projet_task'][
'label'] as $key => $val) {
1184 $sql .= ($extrafields->attributes[
'projet_task'][
'type'][$key] !=
'separate' ?
",efpt.".$key.
" as options_".$key :
'');
1188 if ($includebilltime) {
1189 $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";
1192 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
1193 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1195 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_extrafields as efp ON (p.rowid = efp.fk_object)";
1199 if ($filteronprojuser > 0) {
1200 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1201 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1203 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
1205 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)";
1207 if ($includebilltime) {
1208 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')";
1210 if ($filterontaskuser > 0) {
1211 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
1212 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
1214 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
1215 $sql .=
" AND t.fk_projet = p.rowid";
1216 } elseif ($mode == 1) {
1217 if ($filteronprojuser > 0) {
1218 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1219 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1221 if ($filterontaskuser > 0) {
1222 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
1223 if ($includebilltime) {
1224 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')";
1226 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
1227 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
1229 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t on t.fk_projet = p.rowid";
1230 if ($includebilltime) {
1231 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype = 'task')";
1234 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
1236 return 'BadValueForParameterMode';
1239 if ($filteronprojuser > 0) {
1240 $sql .=
" AND p.rowid = ec.element_id";
1241 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
1242 $sql .=
" AND ctc.element = 'project'";
1243 $sql .=
" AND ec.fk_socpeople = ".((int) $filteronprojuser);
1244 $sql .=
" AND ec.statut = 4";
1245 $sql .=
" AND ctc.source = 'internal'";
1247 if ($filterontaskuser > 0) {
1248 $sql .=
" AND t.fk_projet = p.rowid";
1249 $sql .=
" AND p.rowid = ec2.element_id";
1250 $sql .=
" AND ctc2.rowid = ec2.fk_c_type_contact";
1251 $sql .=
" AND ctc2.element = 'project_task'";
1252 $sql .=
" AND ec2.fk_socpeople = ".((int) $filterontaskuser);
1253 $sql .=
" AND ec2.statut = 4";
1254 $sql .=
" AND ctc2.source = 'internal'";
1257 $sql .=
" AND p.fk_soc = ".((int) $socid);
1260 $sql .=
" AND p.rowid IN (".$this->db->sanitize((
string) $projectid).
")";
1262 if ($filteronproj) {
1263 $sql .=
natural_search(array(
"p.ref",
"p.title"), $filteronproj);
1265 if ($filteronprojstatus && (
int) $filteronprojstatus !=
'-1') {
1266 $sql .=
" AND p.fk_statut IN (".$this->db->sanitize($filteronprojstatus).
")";
1268 if ($morewherefilter) {
1269 $sql .= $morewherefilter;
1273 $extrafieldsobjectkey =
'projet_task';
1274 $extrafieldsobjectprefix =
'efpt.';
1275 $search_options_pattern =
'search_task_options_';
1277 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_sql.tpl.php';
1280 $parameters = array();
1281 $reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
1282 $sql .= $hookmanager->resPrint;
1283 if ($includebilltime) {
1284 $sql .=
" GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,";
1285 $sql .=
" t.datec, t.dateo, t.datee, t.tms,";
1286 $sql .=
" t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,";
1287 $sql .=
" t.dateo, t.datee, t.planned_workload, t.rang, t.priority,";
1288 $sql .=
" t.budget_amount, t.billable,";
1289 $sql .=
" t.note_public, t.note_private,";
1290 $sql .=
" s.rowid, s.nom, s.email,";
1291 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount";
1293 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1294 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1295 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key :
'');
1298 if (!empty($extrafields->attributes[
'projet_task'][
'label'])) {
1299 foreach ($extrafields->attributes[
'projet_task'][
'label'] as $key => $val) {
1300 $sql .= ($extrafields->attributes[
'projet_task'][
'type'][$key] !=
'separate' ?
",efpt.".$key :
'');
1306 if ($sortfield && $sortorder) {
1307 $sql .= $this->db->order($sortfield, $sortorder);
1309 $sql .=
" ORDER BY p.ref, t.rang, t.dateo";
1313 dol_syslog(get_class($this).
"::getTasksArray", LOG_DEBUG);
1314 $resql = $this->db->query($sql);
1316 $num = $this->db->num_rows($resql);
1322 $obj = $this->db->fetch_object($resql);
1324 if ($loadRoleMode) {
1325 if ((!$obj->public) && (is_object($userp))) {
1330 if (is_object($usert)) {
1338 $tasks[$i] =
new Task($this->db);
1339 $tasks[$i]->id = $obj->taskid;
1340 $tasks[$i]->ref = $obj->taskref;
1341 $tasks[$i]->fk_project = $obj->projectid;
1344 $tasks[$i]->projectref = $obj->ref;
1345 $tasks[$i]->projectlabel = $obj->plabel;
1346 $tasks[$i]->projectstatus = $obj->projectstatus;
1347 $tasks[$i]->fk_opp_status = $obj->fk_opp_status;
1348 $tasks[$i]->opp_amount = $obj->opp_amount;
1349 $tasks[$i]->opp_percent = $obj->opp_percent;
1350 $tasks[$i]->budget_amount = $obj->budget_amount;
1351 $tasks[$i]->project_budget_amount = $obj->project_budget_amount;
1352 $tasks[$i]->usage_bill_time = $obj->usage_bill_time;
1354 $tasks[$i]->label = $obj->label;
1355 $tasks[$i]->description = $obj->description;
1357 $tasks[$i]->fk_task_parent = $obj->fk_task_parent;
1358 $tasks[$i]->note_public = $obj->note_public;
1359 $tasks[$i]->note_private = $obj->note_private;
1360 $tasks[$i]->duration_effective = $obj->duration_effective;
1361 $tasks[$i]->planned_workload = $obj->planned_workload;
1363 if ($includebilltime) {
1365 $tasks[$i]->tobill = $obj->tobill;
1366 $tasks[$i]->billed = $obj->billed;
1369 $tasks[$i]->progress = $obj->progress;
1370 $tasks[$i]->fk_statut = $obj->status;
1371 $tasks[$i]->status = $obj->status;
1372 $tasks[$i]->public = $obj->public;
1373 $tasks[$i]->date_start = $this->db->jdate($obj->date_start);
1374 $tasks[$i]->date_end = $this->db->jdate($obj->date_end);
1375 $tasks[$i]->rang = $obj->rang;
1376 $tasks[$i]->priority = $obj->priority;
1378 $tasks[$i]->socid = $obj->thirdparty_id;
1379 $tasks[$i]->thirdparty_id = $obj->thirdparty_id;
1380 $tasks[$i]->thirdparty_name = $obj->thirdparty_name;
1381 $tasks[$i]->thirdparty_email = $obj->thirdparty_email;
1383 $tasks[$i]->billable = $obj->billable;
1386 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1387 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1388 if ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate') {
1389 $tmpvar =
'options_'.$key;
1390 $tasks[$i]->array_options_project[
'options_'.$key] = $obj->$tmpvar;
1397 $tasks[$i]->fetch_optionals();
1403 $this->db->free($resql);
1405 dol_print_error($this->db);
1423 $arrayroles = array();
1425 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks userp=".json_encode(is_object($userp)).
" usert=".json_encode(is_object($usert)).
" projectid=".$projectid.
" taskid=".$taskid);
1428 if (empty($userp) && empty($usert)) {
1429 $this->error =
"CallWithWrongParameters";
1432 if (!empty($userp) && !empty($usert)) {
1433 $this->error =
"CallWithWrongParameters";
1440 $sql .=
" p.rowid as pid,";
1442 $sql .=
" pt.rowid as pid,";
1444 $sql .=
" ec.element_id, ctc.code, ctc.source";
1446 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
1448 if ($usert && $filteronprojstatus > -1) {
1449 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p, ".MAIN_DB_PREFIX.
"projet_task as pt";
1451 if ($usert && $filteronprojstatus <= -1) {
1452 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as pt";
1454 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1455 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1457 $sql .=
" WHERE p.rowid = ec.element_id";
1459 $sql .=
" WHERE pt.rowid = ec.element_id";
1461 if ($userp && $filteronprojstatus > -1) {
1462 $sql .=
" AND p.fk_statut = ".((int) $filteronprojstatus);
1464 if ($usert && $filteronprojstatus > -1) {
1465 $sql .=
" AND pt.fk_projet = p.rowid AND p.fk_statut = ".((int) $filteronprojstatus);
1468 $sql .=
" AND ctc.element = 'project'";
1471 $sql .=
" AND ctc.element = 'project_task'";
1473 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
1475 $sql .=
" AND ec.fk_socpeople = ".((int) $userp->id);
1478 $sql .=
" AND ec.fk_socpeople = ".((int) $usert->id);
1480 $sql .=
" AND ec.statut = 4";
1481 $sql .=
" AND ctc.source = 'internal'";
1484 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectid).
")";
1487 $sql .=
" AND pt.fk_projet IN (".$this->db->sanitize($projectid).
")";
1492 $sql .=
" ERROR SHOULD NOT HAPPENS";
1495 $sql .=
" AND pt.rowid = ".((int) $taskid);
1500 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG);
1501 $resql = $this->db->query($sql);
1503 $num = $this->db->num_rows($resql);
1506 $obj = $this->db->fetch_object($resql);
1507 if (empty($arrayroles[$obj->pid])) {
1508 $arrayroles[$obj->pid] = $obj->code;
1510 $arrayroles[$obj->pid] .=
','.$obj->code;
1514 $this->db->free($resql);
1516 dol_print_error($this->db);
1531 $contactAlreadySelected = array();
1537 if ($source ==
'thirdparty') {
1538 $contactAlreadySelected[$i] = $tab[$i][
'socid'];
1540 $contactAlreadySelected[$i] = $tab[$i][
'id'];
1544 return $contactAlreadySelected;
1557 $origintask =
new Task($this->db);
1558 $result = $origintask->fetch($origin_id);
1564 $arraycontactorigin = array_merge($origintask->liste_contact(-1,
'internal'), $origintask->liste_contact(-1,
'external'));
1565 if (is_array($arraycontactorigin)) {
1566 foreach ($arraycontactorigin as $key => $contact) {
1567 $result = $this->
add_contact($contact[
"id"], $contact[
"fk_c_type_contact"], $contact[
"source"]);
1589 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"element_time as et";
1590 $sql .=
" SET et.fk_element = ".((int) $dest_id);
1591 $sql .=
" WHERE et.elementtype = 'task'";
1592 $sql .=
" AND et.fk_element = ".((int) $origin_id);
1594 dol_syslog(get_class($this).
"::mergeTimeSpentTask", LOG_DEBUG);
1595 if (!$this->db->query($sql)) {
1596 $this->error = $this->db->lasterror();
1601 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1602 $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) $dest_id).
")";
1603 $sql .=
" WHERE rowid = ".((int) $dest_id);
1605 dol_syslog(get_class($this).
"::mergeTimeSpentTask update project_task", LOG_DEBUG);
1606 if (!$this->db->query($sql)) {
1607 $this->error = $this->db->lasterror();
1613 $this->db->commit();
1615 $this->db->rollback();
1631 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1637 if (!is_object($user)) {
1638 dol_print_error(
null,
"Method addTimeSpent was called with wrong parameter user");
1643 if (isset($this->timespent_note)) {
1644 $this->timespent_note = trim($this->timespent_note);
1646 if (empty($this->timespent_datehour) || empty($this->timespent_withhour)) {
1650 $this->timespent_datehour = $this->timespent_date;
1654 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1657 if ($this->timespent_date < $restrictBefore) {
1658 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack',
getDolGlobalString(
'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS'));
1659 $this->errors[] = $this->error;
1667 $timespent->fk_element = $this->id;
1668 $timespent->elementtype =
'task';
1669 $timespent->element_date = $this->timespent_date;
1670 $timespent->element_datehour = $this->timespent_datehour;
1671 $timespent->element_date_withhour = $this->timespent_withhour;
1672 $timespent->element_duration = $this->timespent_duration;
1673 $timespent->fk_user = $this->timespent_fk_user;
1674 $timespent->fk_product = $this->timespent_fk_product;
1675 $timespent->note = $this->timespent_note;
1676 $timespent->datec = $now;
1678 $result = $timespent->create($user);
1681 $this->timespent_id = $result;
1685 $result = $this->call_trigger(
'TASK_TIMESPENT_CREATE', $user);
1692 $this->error = $this->db->lasterror();
1699 if ($ret <= 0 && empty($this->error) && !empty($this->errors)) {
1700 foreach ($this->errors as $errmsg) {
1701 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
1702 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1708 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1709 $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).
")";
1710 if (isset($this->progress)) {
1711 $sql .=
", progress = ".((float) $this->progress);
1712 if ($this->progress == 100) {
1714 } elseif ($this->progress != 0) {
1719 $sql .=
", fk_statut = ".((int) $this->
status);
1722 $sql .=
", fk_statut = ".((int) $this->
status);
1724 $sql .=
" WHERE rowid = ".((int) $this->
id);
1726 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1727 if (!$this->db->query($sql)) {
1728 $this->error = $this->db->lasterror();
1733 $resql_thm_user = $this->db->query(
"SELECT thm FROM " . MAIN_DB_PREFIX .
"user WHERE rowid = " . ((
int) $timespent->fk_user));
1734 if (!empty($resql_thm_user)) {
1735 $obj_thm_user = $this->db->fetch_object($resql_thm_user);
1736 $timespent->thm = $obj_thm_user->thm;
1738 $res_update = $timespent->update($user);
1740 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1741 if ($res_update <= 0) {
1742 $this->error = $this->db->lasterror();
1748 $this->db->commit();
1750 $this->db->rollback();
1763 $arrayres = array();
1766 $sql .=
" s.rowid as socid,";
1767 $sql .=
" s.nom as thirdparty_name,";
1768 $sql .=
" s.email as thirdparty_email,";
1769 $sql .=
" ptt.rowid,";
1770 $sql .=
" ptt.ref_ext,";
1771 $sql .=
" ptt.fk_element as fk_task,";
1772 $sql .=
" ptt.element_date as task_date,";
1773 $sql .=
" ptt.element_datehour as task_datehour,";
1774 $sql .=
" ptt.element_date_withhour as task_date_withhour,";
1775 $sql .=
" ptt.element_duration as task_duration,";
1776 $sql .=
" ptt.fk_user,";
1777 $sql .=
" ptt.fk_product,";
1778 $sql .=
" ptt.note,";
1779 $sql .=
" ptt.thm,";
1780 $sql .=
" pt.rowid as task_id,";
1781 $sql .=
" pt.ref as task_ref,";
1782 $sql .=
" pt.label as task_label,";
1783 $sql .=
" p.rowid as project_id,";
1784 $sql .=
" p.ref as project_ref,";
1785 $sql .=
" p.title as project_label,";
1786 $sql .=
" p.public as project_public";
1787 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
1788 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1789 $sql .=
" WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid";
1790 $sql .=
" AND ptt.elementtype = 'task'";
1791 $sql .=
" AND pt.rowid = ".((int) $this->
id);
1792 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
1793 if ($morewherefilter) {
1794 $sql .= $morewherefilter;
1797 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
1798 $resql = $this->db->query($sql);
1800 $num = $this->db->num_rows($resql);
1804 $obj = $this->db->fetch_object($resql);
1808 $newobj->socid = $obj->socid;
1809 $newobj->thirdparty_name = $obj->thirdparty_name;
1810 $newobj->thirdparty_email = $obj->thirdparty_email;
1812 $newobj->fk_project = $obj->project_id;
1813 $newobj->project_ref = $obj->project_ref;
1814 $newobj->project_label = $obj->project_label;
1815 $newobj->project_public = $obj->project_public;
1816 $newobj->public = $obj->project_public;
1818 $newobj->fk_task = $obj->task_id;
1819 $newobj->task_ref = $obj->task_ref;
1820 $newobj->task_label = $obj->task_label;
1822 $newobj->timespent_line_id = $obj->rowid;
1823 $newobj->timespent_line_ref_ext = $obj->ref_ext;
1824 $newobj->timespent_line_date = $this->db->jdate($obj->task_date);
1825 $newobj->timespent_line_datehour = $this->db->jdate($obj->task_datehour);
1826 $newobj->timespent_line_withhour = $obj->task_date_withhour;
1827 $newobj->timespent_line_duration = $obj->task_duration;
1828 $newobj->timespent_line_fk_user = $obj->fk_user;
1829 $newobj->timespent_line_fk_product = $obj->fk_product;
1830 $newobj->timespent_line_thm = $obj->thm;
1831 $newobj->timespent_line_note = $obj->note;
1833 $arrayres[] = $newobj;
1838 $this->db->free($resql);
1840 $this->lines = $arrayres;
1843 dol_print_error($this->db);
1844 $this->error =
"Error ".$this->db->lasterror();
1859 if (is_object($userobj)) {
1860 $userid = $userobj->id;
1866 if (empty($id) && empty($userid)) {
1867 dol_syslog(
"getSummaryOfTimeSpent called on a not loaded task without user param defined", LOG_ERR);
1874 $sql .=
" MIN(t.element_datehour) as min_date,";
1875 $sql .=
" MAX(t.element_datehour) as max_date,";
1876 $sql .=
" SUM(t.element_duration) as total_duration,";
1877 $sql .=
" SUM(t.element_duration / 3600 * ".$this->db->ifsql(
"t.thm IS NULL",
'0',
"t.thm").
") as total_amount,";
1878 $sql .=
" COUNT(t.rowid) as nblines,";
1879 $sql .=
" SUM(".$this->db->ifsql(
"t.thm IS NULL",
'1',
'0').
") as nblinesnull";
1880 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as t";
1881 $sql .=
" WHERE t.elementtype='task'";
1882 if ($morewherefilter) {
1883 $sql .= $morewherefilter;
1886 $sql .=
" AND t.fk_element = ".((int) $id);
1889 $sql .=
" AND t.fk_user = ".((int) $userid);
1892 dol_syslog(get_class($this).
"::getSummaryOfTimeSpent", LOG_DEBUG);
1893 $resql = $this->db->query($sql);
1895 $obj = $this->db->fetch_object($resql);
1897 $result[
'min_date'] = $obj->min_date;
1898 $result[
'max_date'] = $obj->max_date;
1899 $result[
'total_duration'] = $obj->total_duration;
1901 $this->timespent_min_date = $this->db->jdate($obj->min_date);
1902 $this->timespent_max_date = $this->db->jdate($obj->max_date);
1903 $this->timespent_total_duration = $obj->total_duration;
1904 $this->timespent_total_amount = $obj->total_amount;
1905 $this->timespent_nblinesnull = ($obj->nblinesnull ? $obj->nblinesnull : 0);
1906 $this->timespent_nblines = ($obj->nblines ? $obj->nblines : 0);
1908 $this->db->free($resql);
1910 dol_print_error($this->db);
1930 $sql .=
" SUM(t.element_duration) as nbseconds,";
1931 $sql .=
" SUM(".$this->db->ifsql(
"u.thm IS NULL",
'1',
'0').
") as nbuserthmnull,";
1932 $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";
1933 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as t";
1934 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"user as u ON u.rowid = t.fk_user";
1935 $sql .=
" WHERE t.elementtype='task' AND t.fk_element = ".((int) $id);
1936 if (is_object($fuser) && $fuser->id > 0) {
1937 $sql .=
" AND fk_user = ".((int) $fuser->id);
1940 $datefieldname =
"element_datehour";
1941 $sql .=
" AND (".$this->db->sanitize($datefieldname).
" >= '".$this->db->idate((
int) $dates).
"' OR ".$this->db->sanitize($datefieldname).
" IS NULL)";
1944 $datefieldname =
"element_datehour";
1945 $sql .=
" AND (".$this->db->sanitize($datefieldname).
" <= '".$this->db->idate((
int) $datee).
"' OR ".$this->db->sanitize($datefieldname).
" IS NULL)";
1949 dol_syslog(get_class($this).
"::getSumOfAmount", LOG_DEBUG);
1950 $resql = $this->db->query($sql);
1952 $obj = $this->db->fetch_object($resql);
1954 $result[
'amount'] = $obj->amount;
1955 $result[
'nbseconds'] = $obj->nbseconds;
1956 $result[
'nblinesnull'] = $obj->nblinesnull;
1957 $result[
'nbuserthmnull'] = $obj->nbuserthmnull;
1959 $this->db->free($resql);
1962 dol_print_error($this->db);
1976 $timespent->fetch($id);
1978 dol_syslog(get_class($this).
"::fetchTimeSpent", LOG_DEBUG);
1980 if ($timespent->id > 0) {
1981 $this->timespent_id = $timespent->id;
1982 $this->
id = $timespent->fk_element;
1983 $this->timespent_date = $timespent->element_date;
1984 $this->timespent_datehour = $timespent->element_datehour;
1985 $this->timespent_withhour = $timespent->element_date_withhour;
1986 $this->timespent_duration = $timespent->element_duration;
1987 $this->timespent_fk_user = $timespent->fk_user;
1988 $this->timespent_fk_product = $timespent->fk_product;
1989 $this->timespent_thm = $timespent->thm;
1990 $this->timespent_note = $timespent->note;
2007 $arrayres = array();
2010 $sql .=
" s.rowid as socid,";
2011 $sql .=
" s.nom as thirdparty_name,";
2012 $sql .=
" s.email as thirdparty_email,";
2013 $sql .=
" ptt.rowid,";
2014 $sql .=
" ptt.fk_element as fk_task,";
2015 $sql .=
" ptt.element_date as task_date,";
2016 $sql .=
" ptt.element_datehour as task_datehour,";
2017 $sql .=
" ptt.element_date_withhour as task_date_withhour,";
2018 $sql .=
" ptt.element_duration as task_duration,";
2019 $sql .=
" ptt.fk_user,";
2020 $sql .=
" ptt.note,";
2021 $sql .=
" ptt.thm,";
2022 $sql .=
" pt.rowid as task_id,";
2023 $sql .=
" pt.ref as task_ref,";
2024 $sql .=
" pt.label as task_label,";
2025 $sql .=
" p.rowid as project_id,";
2026 $sql .=
" p.ref as project_ref,";
2027 $sql .=
" p.title as project_label,";
2028 $sql .=
" p.public as public";
2029 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
2030 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
2031 $sql .=
" WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid";
2032 $sql .=
" AND ptt.elementtype = 'task'";
2033 $sql .=
" AND ptt.fk_user = ".((int) $userobj->id);
2034 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
2035 if ($morewherefilter) {
2036 $sql .= $morewherefilter;
2039 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
2040 $resql = $this->db->query($sql);
2042 $num = $this->db->num_rows($resql);
2046 $obj = $this->db->fetch_object($resql);
2050 $newobj->socid = $obj->socid;
2051 $newobj->thirdparty_name = $obj->thirdparty_name;
2052 $newobj->thirdparty_email = $obj->thirdparty_email;
2054 $newobj->fk_project = $obj->project_id;
2055 $newobj->project_ref = $obj->project_ref;
2056 $newobj->project_label = $obj->project_label;
2057 $newobj->public = $obj->project_public;
2059 $newobj->fk_task = $obj->task_id;
2060 $newobj->task_ref = $obj->task_ref;
2061 $newobj->task_label = $obj->task_label;
2063 $newobj->timespent_id = $obj->rowid;
2064 $newobj->timespent_date = $this->db->jdate($obj->task_date);
2065 $newobj->timespent_datehour = $this->db->jdate($obj->task_datehour);
2066 $newobj->timespent_withhour = $obj->task_date_withhour;
2067 $newobj->timespent_duration = $obj->task_duration;
2068 $newobj->timespent_fk_user = $obj->fk_user;
2069 $newobj->timespent_thm = $obj->thm;
2070 $newobj->timespent_note = $obj->note;
2072 $arrayres[] = $newobj;
2077 $this->db->free($resql);
2079 dol_print_error($this->db);
2080 $this->error =
"Error ".$this->db->lasterror();
2096 global
$conf, $langs;
2101 if ($this->timespent_date ==
'') {
2102 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Date"));
2107 if (empty($this->timespent_datehour) || empty($this->timespent_withhour)) {
2111 $this->timespent_datehour = $this->timespent_date;
2113 if (isset($this->timespent_note)) {
2114 $this->timespent_note = trim($this->timespent_note);
2118 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
2121 if ($this->timespent_date < $restrictBefore) {
2122 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack',
getDolGlobalString(
'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS'));
2123 $this->errors[] = $this->error;
2131 $timespent->fetch($this->timespent_id);
2132 $old_fk_element = $timespent->fk_element;
2134 $timespent->element_date = $this->timespent_date;
2135 $timespent->element_datehour = $this->timespent_datehour;
2137 $timespent->element_date_withhour = $this->timespent_withhour;
2138 $timespent->element_duration = $this->timespent_duration;
2139 if ($this->timespent_fk_user > 0) {
2140 $timespent->fk_user = $this->timespent_fk_user;
2142 $timespent->fk_product = $this->timespent_fk_product;
2143 $timespent->fk_element = $this->id;
2144 $timespent->note = $this->timespent_note;
2145 $timespent->invoice_id = $this->timespent_invoiceid;
2146 $timespent->invoice_line_id = $this->timespent_invoicelineid;
2148 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
2150 $resupdate = $timespent->update($user);
2151 if ($resupdate > 0) {
2154 $result = $this->call_trigger(
'TASK_TIMESPENT_MODIFY', $user);
2156 $this->db->rollback();
2166 $this->error = $this->db->lasterror();
2167 $this->db->rollback();
2174 if ($ret < 0 && empty($this->error) && !empty($this->errors)) {
2175 foreach ($this->errors as $errmsg) {
2176 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2177 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2181 if ($ret == 1 && (($this->timespent_old_duration != $this->timespent_duration) ||
getDolGlobalString(
'TIMESPENT_ALWAYS_UPDATE_THM'))) {
2182 if ($this->timespent_old_duration != $this->timespent_duration) {
2184 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"projet_task";
2185 $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) .
")";
2186 if (isset($this->progress)) {
2187 $sql .=
", progress = " . ((float) $this->progress);
2189 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2191 dol_syslog(get_class($this) .
"::updateTimeSpent", LOG_DEBUG);
2192 if (!$this->db->query($sql)) {
2193 $this->error = $this->db->lasterror();
2194 $this->db->rollback();
2202 $resql_thm_user = $this->db->query(
"SELECT thm FROM " . MAIN_DB_PREFIX .
"user WHERE rowid = " . ((
int) $timespent->fk_user));
2203 if (!empty($resql_thm_user)) {
2204 $obj_thm_user = $this->db->fetch_object($resql_thm_user);
2205 $timespent->thm = $obj_thm_user->thm;
2207 $res_update = $timespent->update($user);
2210 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
2211 if ($res_update <= 0) {
2212 $this->error = $this->db->lasterror();
2218 if ($ret == 1 && $old_fk_element != $this->
id) {
2220 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"projet_task";
2221 $sql .=
" SET duration_effective = (SELECT COALESCE(SUM(element_duration), 0) FROM " . MAIN_DB_PREFIX .
"element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = " . ((int) $old_fk_element) .
")";
2222 $sql .=
" WHERE rowid = " . ((int) $old_fk_element);
2223 dol_syslog(get_class($this) .
"::updateTimeSpent update old task", LOG_DEBUG);
2224 if (!$this->db->query($sql)) {
2225 $this->error = $this->db->lasterror();
2226 $this->db->rollback();
2231 $sql =
"UPDATE " . MAIN_DB_PREFIX .
"projet_task";
2232 $sql .=
" SET duration_effective = (SELECT COALESCE(SUM(element_duration), 0) FROM " . MAIN_DB_PREFIX .
"element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = " . ((int) $this->
id) .
")";
2233 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2234 dol_syslog(get_class($this) .
"::updateTimeSpent update new task", LOG_DEBUG);
2235 if (!$this->db->query($sql)) {
2236 $this->error = $this->db->lasterror();
2237 $this->db->rollback();
2244 $this->db->commit();
2258 global
$conf, $langs;
2263 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
2266 if ($this->timespent_date < $restrictBefore) {
2267 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack',
getDolGlobalString(
'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS'));
2268 $this->errors[] = $this->error;
2277 $result = $this->call_trigger(
'TASK_TIMESPENT_DELETE', $user);
2286 $timespent->fetch($this->timespent_id);
2288 $res_del = $timespent->delete($user);
2292 $this->errors[] =
"Error ".$this->db->lasterror();
2297 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
2298 $sql .=
" SET duration_effective = duration_effective - ".((int) $this->timespent_duration);
2299 $sql .=
" WHERE rowid = ".((int) $this->
id);
2301 dol_syslog(get_class($this).
"::delTimeSpent", LOG_DEBUG);
2302 if ($this->db->query($sql)) {
2305 $this->error = $this->db->lasterror();
2312 foreach ($this->errors as $errmsg) {
2313 dol_syslog(get_class($this).
"::delTimeSpent ".$errmsg, LOG_ERR);
2314 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2316 $this->db->rollback();
2319 $this->db->commit();
2338 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)
2340 global $langs,
$conf;
2349 $clone_task =
new Task($this->db);
2350 $origin_task =
new Task($this->db);
2352 $clone_task->context[
'createfromclone'] =
'createfromclone';
2357 $clone_task->fetch($fromid);
2358 $clone_task->fetch_optionals();
2361 $origin_task->fetch($fromid);
2363 $clone_task->date_c = $datec;
2368 require_once DOL_DOCUMENT_ROOT.
"/core/modules/project/task/" .
getDolGlobalString(
'PROJECT_TASK_ADDON').
'.php';
2369 $modTask =
new $obj();
2370 '@phan-var-force ModeleNumRefTask $modTask';
2371 $defaultref = $modTask->getNextValue(
null, $clone_task);
2374 $ori_project_id = $clone_task->fk_project;
2376 $clone_task->id = 0;
2377 $clone_task->ref = $defaultref;
2378 $clone_task->fk_project = $project_id;
2379 $clone_task->fk_task_parent = $parent_task_id;
2380 $clone_task->planned_workload = $origin_task->planned_workload;
2381 $clone_task->rang = $origin_task->rang;
2382 $clone_task->priority = $origin_task->priority;
2385 if ($clone_change_dt) {
2386 $projectstatic =
new Project($this->db);
2387 $projectstatic->fetch($ori_project_id);
2390 $orign_project_dt_start = (!isset($projectstatic->date_start) || $projectstatic->date_start ==
'') ? $projectstatic->date_c : $projectstatic->date_start;
2393 if (!empty($clone_task->date_start)) {
2394 $clone_task->date_start = $now + $clone_task->date_start - $orign_project_dt_start;
2398 if (!empty($clone_task->date_end)) {
2399 $clone_task->date_end = $now + $clone_task->date_end - $orign_project_dt_start;
2404 $clone_task->progress = 0;
2408 $result = $clone_task->create($user);
2412 $this->error = $clone_task->error;
2419 $clone_task_id = $clone_task->id;
2420 $clone_task_ref = $clone_task->ref;
2424 $clone_task->note_private =
'';
2425 $clone_task->note_public =
'';
2428 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
2430 $this->error .= $clone_task->error;
2432 $this->db->rollback();
2434 $this->db->commit();
2438 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
2440 $this->error .= $clone_task->error;
2442 $this->db->rollback();
2444 $this->db->commit();
2450 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2453 $projectstatic =
new Project($this->db);
2454 $projectstatic->fetch($ori_project_id);
2455 $ori_project_ref = $projectstatic->ref;
2457 if ($ori_project_id != $project_id) {
2458 $projectstatic->fetch($project_id);
2459 $clone_project_ref = $projectstatic->ref;
2461 $clone_project_ref = $ori_project_ref;
2467 $filearray =
dol_dir_list($ori_task_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
2468 foreach ($filearray as $file) {
2469 if (!file_exists($clone_task_dir)) {
2471 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
2476 $rescopy =
dol_copy($ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name'],
'0', 1);
2477 if (is_numeric($rescopy) && $rescopy < 0) {
2478 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name']);
2485 if ($clone_affectation) {
2486 $origin_task =
new Task($this->db);
2487 $origin_task->fetch($fromid);
2489 foreach (array(
'internal',
'external') as $source) {
2490 $tab = $origin_task->liste_contact(-1, $source);
2494 $clone_task->add_contact($tab[$i][
'id'], $tab[$i][
'code'], $tab[$i][
'source']);
2495 if ($clone_task->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
2496 $langs->load(
"errors");
2497 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
2500 if ($clone_task->error !=
'') {
2501 $this->error .= $clone_task->error;
2515 unset($clone_task->context[
'createfromclone']);
2518 $this->db->commit();
2519 return $clone_task_id;
2521 $this->db->rollback();
2522 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
2553 return $langs->trans($this->labelStatus[$status]);
2554 } elseif ($mode == 1) {
2555 return $langs->trans($this->labelStatusShort[$status]);
2556 } elseif ($mode == 2) {
2559 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut0').
' '.$langs->trans($this->labelStatusShort[$status]);
2561 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut1').
' '.$langs->trans($this->labelStatusShort[$status]);
2563 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut3').
' '.$langs->trans($this->labelStatusShort[$status]);
2565 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut6').
' '.$langs->trans($this->labelStatusShort[$status]);
2567 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut6').
' '.$langs->trans($this->labelStatusShort[$status]);
2569 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut5').
' '.$langs->trans($this->labelStatusShort[$status]);
2571 } elseif ($mode == 3) {
2574 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut0');
2576 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut1');
2578 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut3');
2580 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut6');
2582 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut6');
2584 return img_picto($langs->trans($this->labelStatusShort[$status]),
'statut5');
2586 } elseif ($mode == 4) {
2589 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status0', $mode);
2591 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status1', $mode);
2593 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status3', $mode);
2595 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status6', $mode);
2597 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status6', $mode);
2599 return dolGetStatus($langs->trans($this->labelStatus[$status]), $langs->trans($this->labelStatusShort[$status]),
'',
'status5', $mode);
2601 } elseif ($mode == 5) {
2611 } elseif ($mode == 6) {
2635 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2637 $outputlangs->load(
"projects");
2640 $modele =
'nodefault';
2642 if (!empty($this->model_pdf)) {
2643 $modele = $this->model_pdf;
2649 $modelpath =
"core/modules/project/task/doc/";
2651 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2665 global
$conf, $langs;
2671 $projectstatic =
new Project($this->db);
2672 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
2677 $sql =
"SELECT COUNT(t.rowid) as nb,";
2678 $sql .=
" SUM(CASE WHEN (t.progress IS NULL OR t.progress >= 0) AND t.datee IS NOT NULL AND t.datee < '".$this->db->idate(
dol_now() -
$conf->project->task->warning_delay).
"' THEN 1 ELSE 0 END) as nblate";
2679 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2682 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2683 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2684 $sql .=
" AND p.fk_statut = 1";
2685 $sql .=
" AND t.fk_projet = p.rowid";
2686 $sql .=
" AND (t.progress IS NULL OR t.progress < 100)";
2687 if (!$user->hasRight(
'projet',
'all',
'lire')) {
2688 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2696 $resql = $this->db->query($sql);
2699 $response->warning_delay =
$conf->project->task->warning_delay / 60 / 60 / 24;
2700 $response->label = $langs->trans(
"OpenedTasks");
2701 if ($user->hasRight(
"projet",
"all",
"lire")) {
2702 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mainmenu=project';
2704 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mode=mine&mainmenu=project';
2706 $response->img = img_object(
'',
"task");
2709 $obj = $this->db->fetch_object($resql);
2711 $response->nbtodo = (int) $obj->nb;
2712 $response->nbtodolate = (int) $obj->nblate;
2717 $this->error = $this->db->error();
2733 $socid = $user->socid;
2735 $projectstatic =
new Project($this->db);
2736 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, $mine, 1, $socid);
2739 $sql =
"SELECT count(p.rowid) as nb";
2740 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2741 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
2742 if (!$user->hasRight(
'societe',
'client',
'voir')) {
2743 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON sc.fk_soc = s.rowid";
2745 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2746 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2747 $sql .=
" AND t.fk_projet = p.rowid";
2748 if ($mine || !$user->hasRight(
'projet',
'all',
'lire')) {
2749 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2754 $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).
")";
2756 if (!$user->hasRight(
'societe',
'client',
'voir')) {
2757 $sql .=
" AND ((s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id).
") OR (s.rowid IS NULL))";
2760 $resql = $this->db->query($sql);
2763 while ($obj = $this->db->fetch_object($resql)) {
2764 $this->nb[
"tasks"] = $obj->nb;
2766 $this->db->free($resql);
2769 dol_print_error($this->db);
2770 $this->error = $this->db->error();
2784 if (!($this->progress >= 0 && $this->progress < 100)) {
2790 $datetouse = ($this->date_end > 0) ? $this->date_end : ((isset($this->datee) && $this->datee > 0) ? $this->datee : 0);
2792 return ($datetouse > 0 && ($datetouse < ($now -
$conf->project->task->warning_delay)));
2804 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2806 $return =
'<div class="box-flex-item box-flex-grow-zero">';
2807 $return .=
'<div class="info-box info-box-sm info-box-kanban">';
2808 $return .=
'<span class="info-box-icon bg-infobox-action">';
2809 $return .= img_picto(
'', $this->picto);
2811 $return .=
'</span>';
2812 $return .=
'<div class="info-box-content">';
2813 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl(1) : $this->ref).
'</span>';
2814 if ($selected >= 0) {
2815 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2817 if (!empty($arraydata[
'projectlink'])) {
2820 $return .=
'<br><span class="info-box-status ">'.$arraydata[
'projectlink'].
'</span>';
2825 if (property_exists($this,
'duration_effective')) {
2826 $return .=
'<br><div class="info-box-label progressinkanban paddingtop">'.getTaskProgressView($this,
false,
true).
'</div>';
2828 $return .=
'</div>';
2829 $return .=
'</div>';
2830 $return .=
'</div>';
2844 global $langs, $hookmanager, $user, $action;
2847 $task_origin =
new Task($this->db);
2849 dol_syslog(
"mergeTask merge task id=".$task_origin_id.
" (will be deleted) into the task id=".$this->id);
2851 $langs->load(
'error');
2853 if (!$error && $task_origin->fetch($task_origin_id) < 1) {
2854 $this->error = $langs->trans(
'ErrorRecordNotFound');
2862 $listofproperties = array(
2863 'label',
'description',
'duration_effective',
'planned_workload',
'datec',
'date_start',
2864 'date_end',
'fk_user_creat',
'fk_user_valid',
'fk_statut',
'progress',
'budget_amount',
2865 'priority',
'rang',
'fk_projet',
'fk_task_parent'
2867 foreach ($listofproperties as $property) {
2868 if (empty($this->$property)) {
2869 $this->$property = $task_origin->$property;
2874 $listofproperties = array(
2875 'note_public',
'note_private'
2877 foreach ($listofproperties as $property) {
2878 $this->$property =
dol_concatdesc($this->$property, $task_origin->$property);
2882 if (is_array($task_origin->array_options)) {
2883 foreach ($task_origin->array_options as $key => $val) {
2884 if (empty($this->array_options[$key])) {
2885 $this->array_options[$key] = $val;
2891 $result = $this->
update($user);
2900 if ($result !=
true) {
2908 if ($result !=
true) {
2915 $parameters = array(
'task_origin' => $task_origin->id,
'task_dest' => $this->id);
2916 $reshook = $hookmanager->executeHooks(
'replaceThirdparty', $parameters, $this, $action);
2919 $this->error = $hookmanager->error;
2920 $this->errors = $hookmanager->errors;
2927 $this->context = array(
'merge' => 1,
'mergefromid' => $task_origin->id,
'mergefromref' => $task_origin->ref);
2930 $result = $this->call_trigger(
'TASK_MODIFY', $user);
2939 if ($task_origin->delete($user) < 1) {
2940 $this->error = $task_origin->error;
2941 $this->errors = $task_origin->errors;
2947 $this->db->commit();
2950 $langs->load(
"errors");
2951 $this->error = $langs->trans(
'ErrorsTaskMerge');
2952 $this->db->rollback();
2972 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2973 return parent::setCategoriesCommon($categories, Categorie::TYPE_PROJECT_TASK);
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.
liste_contact($statusoflink=-1, $source='external', $list=0, $code='', $status=-1, $arrayoftcids=array())
Get array of all contacts for an object.
isObjectUsed($id=0, $entity=0)
Function to check if an object is used by others (by children).
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.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
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.
mergeContactTask($origin_id, $dest_id)
Merge contact of tasks.
const STATUS_TRANSFERRED
Transferred status.
getSumOfAmount($fuser='', $dates='', $datee='')
Calculate quantity and value of time consumed using the thm (hourly amount value of work for user ent...
mergeTask($task_origin_id)
Merge a task with another one, deleting the given task.
__construct($db)
Constructor.
fetchTimeSpentOnTask($morewherefilter='')
Fetch records of time spent of this task.
setCategories($categories)
Sets object to task categories.
const STATUS_VALIDATED
Validated status (To do).
hasTimeSpent()
Return nb of time spent.
getNomUrl($withpicto=0, $option='', $mode='task', $addlabel=0, $sep=' - ', $notooltip=0, $save_lastsearch_value=-1)
Return clickable name (with picto eventually)
getListContactId($source='internal')
Return list of id of contacts of task.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
delTimeSpent($user, $notrigger=0)
Delete time spent.
mergeTimeSpentTask($origin_id, $dest_id)
Merge time spent of tasks.
const STATUS_DRAFT
Draft status.
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
const STATUS_CANCELED
status canceled
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 line with id $this->timespent_id.
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.
loadStateBoard()
Load indicators this->nb for state board.
const STATUS_ONGOING
Ongoing status (In progress).
initAsSpecimen()
Initialise an instance with random values.
getTasksArray($usert=null, $userp=null, $projectid=0, $socid=0, $mode=0, $filteronproj='', $filteronprojstatus='-1', $morewherefilter='', $filteronprojuser=0, $filterontaskuser=0, $extrafields=null, $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,...
addTimeSpent($user, $notrigger=0)
Add time spent.
hasDelay()
Is the task delayed?
LibStatut($status, $mode=0)
Return status label for an object.
const STATUS_CLOSED
Finished status.
hasChildren()
Return nb of children.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_copy($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
dol_move_dir($srcdir, $destdir, $overwriteifexists=1, $indexdatabase=1, $renamedircontent=1)
Move a directory into another name.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_dir_list($utf8_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_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
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)