29 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
30 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
31 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
42 public $element =
'project_task';
47 public $table_element =
'projet_task';
52 public $fk_element =
'fk_task';
57 public $picto =
'projecttask';
62 protected $childtables = array(
63 'projet_task_time' => array(
'name' =>
'Task',
'parent' =>
'projet_task',
'parentkey' =>
'fk_task')
69 public $fk_task_parent = 0;
81 public $duration_effective;
82 public $planned_workload;
103 public $fk_user_creat;
108 public $fk_user_valid;
112 public $timespent_min_date;
113 public $timespent_max_date;
114 public $timespent_total_duration;
115 public $timespent_total_amount;
116 public $timespent_nblinesnull;
117 public $timespent_nblines;
121 public $timespent_id;
122 public $timespent_duration;
123 public $timespent_old_duration;
124 public $timespent_date;
125 public $timespent_datehour;
126 public $timespent_withhour;
127 public $timespent_fk_user;
128 public $timespent_thm;
129 public $timespent_note;
131 public $comments = array();
136 public $budget_amount;
141 public $project_budget_amount;
164 public function create($user, $notrigger = 0)
166 global $conf, $langs;
174 $this->label = trim($this->label);
177 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
178 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
186 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet_task (";
188 $sql .=
", fk_projet";
190 $sql .=
", fk_task_parent";
192 $sql .=
", description";
194 $sql .=
", fk_user_creat";
197 $sql .=
", planned_workload";
198 $sql .=
", progress";
199 $sql .=
", budget_amount";
200 $sql .=
") VALUES (";
201 $sql .= (!empty($this->entity) ? (int) $this->entity : (
int) $conf->entity);
202 $sql .=
", ".((int) $this->fk_project);
203 $sql .=
", ".(!empty($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
'null');
204 $sql .=
", ".((int) $this->fk_task_parent);
205 $sql .=
", '".$this->db->escape($this->label).
"'";
206 $sql .=
", '".$this->db->escape($this->
description).
"'";
207 $sql .=
", '".$this->db->idate($now).
"'";
208 $sql .=
", ".((int) $user->id);
209 $sql .=
", ".($this->date_start ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
210 $sql .=
", ".($this->date_end ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
211 $sql .=
", ".(($this->planned_workload !=
'' && $this->planned_workload >= 0) ? ((
int) $this->planned_workload) :
'null');
212 $sql .=
", ".(($this->progress !=
'' && $this->progress >= 0) ? ((
int) $this->progress) :
'null');
213 $sql .=
", ".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? ((
int) $this->budget_amount) :
'null');
218 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
221 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
225 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"projet_task");
249 foreach ($this->errors as $errmsg) {
250 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
251 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
253 $this->
db->rollback();
270 public function fetch($id, $ref =
'', $loadparentdata = 0)
272 global $langs, $conf;
277 $sql .=
" t.entity,";
278 $sql .=
" t.fk_projet as fk_project,";
279 $sql .=
" t.fk_task_parent,";
281 $sql .=
" t.description,";
282 $sql .=
" t.duration_effective,";
283 $sql .=
" t.planned_workload,";
287 $sql .=
" t.fk_user_creat,";
288 $sql .=
" t.fk_user_valid,";
289 $sql .=
" t.fk_statut,";
290 $sql .=
" t.progress,";
291 $sql .=
" t.budget_amount,";
292 $sql .=
" t.priority,";
293 $sql .=
" t.note_private,";
294 $sql .=
" t.note_public,";
296 if (!empty($loadparentdata)) {
297 $sql .=
", t2.ref as task_parent_ref";
298 $sql .=
", t2.rang as task_parent_position";
300 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as t";
301 if (!empty($loadparentdata)) {
302 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t2 ON t.fk_task_parent = t2.rowid";
306 $sql .=
"entity IN (".getEntity(
'project').
")";
307 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
309 $sql .=
"t.rowid = ".((int) $id);
312 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
315 $num_rows = $this->
db->num_rows(
$resql);
318 $obj = $this->
db->fetch_object(
$resql);
320 $this->
id = $obj->rowid;
321 $this->
ref = $obj->ref;
322 $this->entity = $obj->entity;
323 $this->fk_project = $obj->fk_project;
324 $this->fk_task_parent = $obj->fk_task_parent;
325 $this->label = $obj->label;
327 $this->duration_effective = $obj->duration_effective;
328 $this->planned_workload = $obj->planned_workload;
329 $this->date_c = $this->
db->jdate($obj->datec);
330 $this->date_start = $this->
db->jdate($obj->dateo);
331 $this->date_end = $this->
db->jdate($obj->datee);
332 $this->fk_user_creat = $obj->fk_user_creat;
333 $this->fk_user_valid = $obj->fk_user_valid;
334 $this->fk_statut = $obj->fk_statut;
335 $this->progress = $obj->progress;
336 $this->budget_amount = $obj->budget_amount;
337 $this->priority = $obj->priority;
338 $this->note_private = $obj->note_private;
339 $this->note_public = $obj->note_public;
340 $this->rang = $obj->rang;
342 if (!empty($loadparentdata)) {
343 $this->task_parent_ref = $obj->task_parent_ref;
344 $this->task_parent_position = $obj->task_parent_position;
359 $this->error =
"Error ".$this->db->lasterror();
372 public function update($user =
null, $notrigger = 0)
374 global $conf, $langs;
378 if (isset($this->fk_project)) {
379 $this->fk_project = trim($this->fk_project);
381 if (isset($this->
ref)) {
382 $this->
ref = trim($this->
ref);
384 if (isset($this->fk_task_parent)) {
385 $this->fk_task_parent = (int) $this->fk_task_parent;
387 if (isset($this->label)) {
388 $this->label = trim($this->label);
393 if (isset($this->duration_effective)) {
394 $this->duration_effective = trim($this->duration_effective);
396 if (isset($this->planned_workload)) {
397 $this->planned_workload = trim($this->planned_workload);
399 if (isset($this->budget_amount)) {
400 $this->budget_amount = trim($this->budget_amount);
403 if (!empty($this->date_start) && !empty($this->date_end) && $this->date_start > $this->date_end) {
404 $this->errors[] = $langs->trans(
'StartDateCannotBeAfterEndDate');
412 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task SET";
413 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
414 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"'".$this->db->escape($this->
id).
"'").
",";
415 $sql .=
" fk_task_parent=".(isset($this->fk_task_parent) ? $this->fk_task_parent :
"null").
",";
416 $sql .=
" label=".(isset($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
417 $sql .=
" description=".(isset($this->
description) ?
"'".$this->db->escape($this->
description).
"'" :
"null").
",";
418 $sql .=
" duration_effective=".(isset($this->duration_effective) ? $this->duration_effective :
"null").
",";
419 $sql .=
" planned_workload=".((isset($this->planned_workload) && $this->planned_workload !=
'') ? $this->planned_workload :
"null").
",";
420 $sql .=
" dateo=".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null').
",";
421 $sql .=
" datee=".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null').
",";
422 $sql .=
" progress=".(($this->progress !=
'' && $this->progress >= 0) ? $this->progress :
'null').
",";
423 $sql .=
" budget_amount=".(($this->budget_amount !=
'' && $this->budget_amount >= 0) ? $this->budget_amount :
'null').
",";
424 $sql .=
" rang=".((!empty($this->rang)) ? $this->rang :
"0");
425 $sql .=
" WHERE rowid=".((int) $this->
id);
429 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
432 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
443 if (!$error && !empty($conf->global->PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE)) {
446 if ($project->fetch($this->fk_project) > 0) {
448 $project->getLinesArray(
null);
449 $projectCompleted = array_reduce(
451 function ($allTasksCompleted, $task) {
452 return $allTasksCompleted && $task->progress >= 100;
456 if ($projectCompleted) {
457 if ($project->setClose($user) <= 0) {
466 $this->errors[] = $project->error;
481 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) {
483 if ($conf->project->dir_output) {
485 $project->fetch($this->fk_project);
489 if (file_exists($olddir)) {
490 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
493 $langs->load(
"errors");
494 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
503 foreach ($this->errors as $errmsg) {
504 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
505 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
507 $this->
db->rollback();
523 public function delete($user, $notrigger = 0)
526 global $conf, $langs;
527 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
534 dol_syslog(get_class($this).
"::delete Can't delete record as it has some sub tasks", LOG_WARNING);
535 $this->error =
'ErrorRecordHasSubTasks';
536 $this->
db->rollback();
541 if (!empty($objectisused)) {
542 dol_syslog(get_class($this).
"::delete Can't delete record as it has some child", LOG_WARNING);
543 $this->error =
'ErrorRecordHasChildren';
544 $this->
db->rollback();
552 $this->error =
'ErrorFailToDeleteLinkedContact';
554 $this->
db->rollback();
560 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task_time";
561 $sql .=
" WHERE fk_task = ".((int) $this->
id);
565 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
570 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task_extrafields";
571 $sql .=
" WHERE fk_object = ".((int) $this->
id);
575 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
580 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task";
581 $sql .=
" WHERE rowid=".((int) $this->
id);
585 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
602 foreach ($this->errors as $errmsg) {
603 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
604 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
606 $this->
db->rollback();
610 if ($conf->project->dir_output) {
612 $projectstatic->fetch($this->fk_project);
615 dol_syslog(get_class($this).
"::delete dir=".$dir, LOG_DEBUG);
616 if (file_exists($dir)) {
617 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
620 $this->error =
'ErrorFailToDeleteDir';
621 $this->
db->rollback();
643 $sql =
"SELECT COUNT(*) as nb";
644 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task";
645 $sql .=
" WHERE fk_task_parent = ".((int) $this->
id);
647 dol_syslog(get_class($this).
"::hasChildren", LOG_DEBUG);
650 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
652 $obj = $this->
db->fetch_object(
$resql);
676 $sql =
"SELECT COUNT(*) as nb";
677 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time";
678 $sql .=
" WHERE fk_task = ".((int) $this->
id);
680 dol_syslog(get_class($this).
"::hasTimeSpent", LOG_DEBUG);
683 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
685 $obj = $this->
db->fetch_object(
$resql);
712 public function getNomUrl($withpicto = 0, $option =
'', $mode =
'task', $addlabel = 0, $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1)
714 global $conf, $langs, $user;
716 if (!empty($conf->dol_no_mouse_hover)) {
721 $label =
img_picto(
'', $this->picto).
' <u>'.$langs->trans(
"Task").
'</u>';
722 if (!empty($this->
ref)) {
723 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
725 if (!empty($this->label)) {
726 $label .=
'<br><b>'.$langs->trans(
'LabelTask').
':</b> '.$this->label;
728 if ($this->date_start || $this->date_end) {
729 $label .=
"<br>".get_date_range($this->date_start, $this->date_end,
'', $langs, 0);
732 $url = DOL_URL_ROOT.
'/projet/tasks/'.$mode.
'.php?id='.$this->
id.($option ==
'withproject' ?
'&withproject=1' :
'');
734 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
735 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
736 $add_save_lastsearch_values = 1;
738 if ($add_save_lastsearch_values) {
739 $url .=
'&save_lastsearch_values=1';
743 if (empty($notooltip)) {
744 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
745 $label = $langs->trans(
"ShowTask");
746 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
748 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
749 $linkclose .=
' class="classfortooltip nowraponall"';
751 $linkclose .=
' class="nowraponall"';
754 $linkstart =
'<a href="'.$url.
'"';
755 $linkstart .= $linkclose.
'>';
758 $picto =
'projecttask';
760 $result .= $linkstart;
762 $result .=
img_object(($notooltip ?
'' : $label), $picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
764 if ($withpicto != 2) {
765 $result .= $this->ref;
768 if ($withpicto != 2) {
769 $result .= (($addlabel && $this->label) ? $sep.dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) :
'');
786 $this->fk_project =
'';
788 $this->fk_task_parent =
null;
789 $this->label =
'Specimen task TK01';
790 $this->duration_effective =
'';
791 $this->fk_user_creat =
null;
792 $this->progress =
'25';
793 $this->fk_statut =
null;
794 $this->note =
'This is a specimen task not';
820 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 =
'')
822 global $conf, $hookmanager;
830 if ($filteronprojuser > 0 || $filterontaskuser > 0) {
833 $sql .=
" p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus, p.usage_bill_time,";
834 $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,";
835 $sql .=
" t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,";
836 $sql .=
" t.description, ";
837 $sql .=
" t.budget_amount, ";
838 $sql .=
" s.rowid as thirdparty_id, s.nom as thirdparty_name, s.email as thirdparty_email,";
839 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount as project_budget_amount";
840 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
841 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
842 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key.
" as options_".$key :
'');
845 if (!empty($extrafields->attributes[
'projet_task'][
'label'])) {
846 foreach ($extrafields->attributes[
'projet_task'][
'label'] as $key => $val) {
847 $sql .= ($extrafields->attributes[
'projet_task'][
'type'][$key] !=
'separate' ?
",efpt.".$key.
" as options_".$key :
'');
850 if ($includebilltime) {
851 $sql .=
", SUM(tt.task_duration * ".$this->db->ifsql(
"invoice_id IS NULL",
"1",
"0").
") as tobill, SUM(tt.task_duration * ".$this->
db->ifsql(
"invoice_id IS NULL",
"0",
"1").
") as billed";
854 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
855 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
856 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_extrafields as efp ON (p.rowid = efp.fk_object)";
859 if ($filteronprojuser > 0) {
860 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
861 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
863 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
864 if ($includebilltime) {
865 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_time as tt ON tt.fk_task = t.rowid";
867 if ($filterontaskuser > 0) {
868 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
869 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
871 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)";
872 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
873 $sql .=
" AND t.fk_projet = p.rowid";
874 } elseif ($mode == 1) {
875 if ($filteronprojuser > 0) {
876 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
877 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
879 if ($filterontaskuser > 0) {
880 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
881 if ($includebilltime) {
882 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_time as tt ON tt.fk_task = t.rowid";
884 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec2";
885 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc2";
887 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task as t on t.fk_projet = p.rowid";
888 if ($includebilltime) {
889 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_time as tt ON tt.fk_task = t.rowid";
892 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)";
893 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
895 return 'BadValueForParameterMode';
898 if ($filteronprojuser > 0) {
899 $sql .=
" AND p.rowid = ec.element_id";
900 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
901 $sql .=
" AND ctc.element = 'project'";
902 $sql .=
" AND ec.fk_socpeople = ".((int) $filteronprojuser);
903 $sql .=
" AND ec.statut = 4";
904 $sql .=
" AND ctc.source = 'internal'";
906 if ($filterontaskuser > 0) {
907 $sql .=
" AND t.fk_projet = p.rowid";
908 $sql .=
" AND p.rowid = ec2.element_id";
909 $sql .=
" AND ctc2.rowid = ec2.fk_c_type_contact";
910 $sql .=
" AND ctc2.element = 'project_task'";
911 $sql .=
" AND ec2.fk_socpeople = ".((int) $filterontaskuser);
912 $sql .=
" AND ec2.statut = 4";
913 $sql .=
" AND ctc2.source = 'internal'";
916 $sql .=
" AND p.fk_soc = ".((int) $socid);
919 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectid).
")";
924 if ($filteronprojstatus && $filteronprojstatus !=
'-1') {
925 $sql .=
" AND p.fk_statut IN (".$this->db->sanitize($filteronprojstatus).
")";
927 if ($morewherefilter) {
928 $sql .= $morewherefilter;
931 $extrafieldsobjectkey =
'projet_task';
932 $extrafieldsobjectprefix =
'efpt.';
934 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_sql.tpl.php';
936 $parameters = array();
937 $reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
938 $sql .= $hookmanager->resPrint;
939 if ($includebilltime) {
940 $sql .=
" GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,";
941 $sql .=
" t.datec, t.dateo, t.datee, t.tms,";
942 $sql .=
" t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,";
943 $sql .=
" t.dateo, t.datee, t.planned_workload, t.rang,";
944 $sql .=
" t.description, ";
945 $sql .=
" t.budget_amount, ";
946 $sql .=
" s.rowid, s.nom, s.email,";
947 $sql .=
" p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount";
948 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
949 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
950 $sql .= ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate' ?
",efp.".$key :
'');
953 if (!empty($extrafields->attributes[
'projet_task'][
'label'])) {
954 foreach ($extrafields->attributes[
'projet_task'][
'label'] as $key => $val) {
955 $sql .= ($extrafields->attributes[
'projet_task'][
'type'][$key] !=
'separate' ?
",efpt.".$key :
'');
960 if ($sortfield && $sortorder) {
961 $sql .= $this->
db->order($sortfield, $sortorder);
963 $sql .=
" ORDER BY p.ref, t.rang, t.dateo";
967 dol_syslog(get_class($this).
"::getTasksArray", LOG_DEBUG);
976 $obj = $this->
db->fetch_object(
$resql);
979 if ((!$obj->public) && (is_object($userp))) {
984 if (is_object($usert)) {
992 $tasks[$i] =
new Task($this->
db);
993 $tasks[$i]->id = $obj->taskid;
994 $tasks[$i]->ref = $obj->taskref;
995 $tasks[$i]->fk_project = $obj->projectid;
996 $tasks[$i]->projectref = $obj->ref;
997 $tasks[$i]->projectlabel = $obj->plabel;
998 $tasks[$i]->projectstatus = $obj->projectstatus;
1000 $tasks[$i]->fk_opp_status = $obj->fk_opp_status;
1001 $tasks[$i]->opp_amount = $obj->opp_amount;
1002 $tasks[$i]->opp_percent = $obj->opp_percent;
1003 $tasks[$i]->budget_amount = $obj->budget_amount;
1004 $tasks[$i]->project_budget_amount = $obj->project_budget_amount;
1005 $tasks[$i]->usage_bill_time = $obj->usage_bill_time;
1007 $tasks[$i]->label = $obj->label;
1008 $tasks[$i]->description = $obj->description;
1009 $tasks[$i]->fk_parent = $obj->fk_task_parent;
1010 $tasks[$i]->fk_task_parent = $obj->fk_task_parent;
1011 $tasks[$i]->duration = $obj->duration_effective;
1012 $tasks[$i]->planned_workload = $obj->planned_workload;
1014 if ($includebilltime) {
1015 $tasks[$i]->tobill = $obj->tobill;
1016 $tasks[$i]->billed = $obj->billed;
1019 $tasks[$i]->progress = $obj->progress;
1020 $tasks[$i]->fk_statut = $obj->status;
1021 $tasks[$i]->public = $obj->public;
1022 $tasks[$i]->date_start = $this->
db->jdate($obj->date_start);
1023 $tasks[$i]->date_end = $this->
db->jdate($obj->date_end);
1024 $tasks[$i]->rang = $obj->rang;
1026 $tasks[$i]->socid = $obj->thirdparty_id;
1027 $tasks[$i]->thirdparty_id = $obj->thirdparty_id;
1028 $tasks[$i]->thirdparty_name = $obj->thirdparty_name;
1029 $tasks[$i]->thirdparty_email = $obj->thirdparty_email;
1031 if (!empty($extrafields->attributes[
'projet'][
'label'])) {
1032 foreach ($extrafields->attributes[
'projet'][
'label'] as $key => $val) {
1033 if ($extrafields->attributes[
'projet'][
'type'][$key] !=
'separate') {
1034 $tasks[$i]->{
'options_'.$key} = $obj->{
'options_'.$key};
1039 if (!empty($extrafields->attributes[
'projet_task'][
'label'])) {
1040 foreach ($extrafields->attributes[
'projet_task'][
'label'] as $key => $val) {
1041 if ($extrafields->attributes[
'projet_task'][
'type'][$key] !=
'separate') {
1042 $tasks[$i]->{
'options_'.$key} = $obj->{
'options_'.$key};
1048 $tasks[$i]->fetch_optionals();
1074 $arrayroles = array();
1076 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks userp=".is_object($userp).
" usert=".is_object($usert).
" projectid=".$projectid.
" taskid=".$taskid);
1079 if (empty($userp) && empty($usert)) {
1080 $this->error =
"CallWithWrongParameters";
1083 if (!empty($userp) && !empty($usert)) {
1084 $this->error =
"CallWithWrongParameters";
1089 $sql =
"SELECT pt.rowid as pid, ec.element_id, ctc.code, ctc.source";
1091 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as pt";
1093 if ($usert && $filteronprojstatus > -1) {
1094 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p, ".MAIN_DB_PREFIX.
"projet_task as pt";
1096 if ($usert && $filteronprojstatus <= -1) {
1097 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task as pt";
1099 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1100 $sql .=
", ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1101 $sql .=
" WHERE pt.rowid = ec.element_id";
1102 if ($userp && $filteronprojstatus > -1) {
1103 $sql .=
" AND pt.fk_statut = ".((int) $filteronprojstatus);
1105 if ($usert && $filteronprojstatus > -1) {
1106 $sql .=
" AND pt.fk_projet = p.rowid AND p.fk_statut = ".((int) $filteronprojstatus);
1109 $sql .=
" AND ctc.element = 'project'";
1112 $sql .=
" AND ctc.element = 'project_task'";
1114 $sql .=
" AND ctc.rowid = ec.fk_c_type_contact";
1116 $sql .=
" AND ec.fk_socpeople = ".((int) $userp->id);
1119 $sql .=
" AND ec.fk_socpeople = ".((int) $usert->id);
1121 $sql .=
" AND ec.statut = 4";
1122 $sql .=
" AND ctc.source = 'internal'";
1125 $sql .=
" AND pt.rowid IN (".$this->db->sanitize($projectid).
")";
1128 $sql .=
" AND pt.fk_projet IN (".$this->db->sanitize($projectid).
")";
1133 $sql .=
" ERROR SHOULD NOT HAPPENS";
1136 $sql .=
" AND pt.rowid = ".((int) $taskid);
1141 dol_syslog(get_class($this).
"::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG);
1144 $num = $this->
db->num_rows(
$resql);
1147 $obj = $this->
db->fetch_object(
$resql);
1148 if (empty($arrayroles[$obj->pid])) {
1149 $arrayroles[$obj->pid] = $obj->code;
1151 $arrayroles[$obj->pid] .=
','.$obj->code;
1172 $contactAlreadySelected = array();
1173 $tab = $this->liste_contact(-1, $source);
1178 if ($source ==
'thirdparty') {
1179 $contactAlreadySelected[$i] = $tab[$i][
'socid'];
1181 $contactAlreadySelected[$i] = $tab[$i][
'id'];
1185 return $contactAlreadySelected;
1198 global $conf, $langs;
1200 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1206 if (!is_object($user)) {
1207 dol_print_error(
'',
"Method addTimeSpent was called with wrong parameter user");
1212 if (isset($this->timespent_note)) {
1213 $this->timespent_note = trim($this->timespent_note);
1215 if (empty($this->timespent_datehour)) {
1216 $this->timespent_datehour = $this->timespent_date;
1219 if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1220 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1223 if ($this->timespent_date < $restrictBefore) {
1224 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1225 $this->errors[] = $this->error;
1233 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet_task_time (";
1235 $sql .=
", task_date";
1236 $sql .=
", task_datehour";
1237 $sql .=
", task_date_withhour";
1238 $sql .=
", task_duration";
1239 $sql .=
", fk_user";
1242 $sql .=
") VALUES (";
1243 $sql .= ((int) $this->
id);
1244 $sql .=
", '".$this->db->idate($this->timespent_date).
"'";
1245 $sql .=
", '".$this->db->idate($this->timespent_datehour).
"'";
1246 $sql .=
", ".(empty($this->timespent_withhour) ? 0 : 1);
1247 $sql .=
", ".((int) $this->timespent_duration);
1248 $sql .=
", ".((int) $this->timespent_fk_user);
1249 $sql .=
", ".(isset($this->timespent_note) ?
"'".$this->db->escape($this->timespent_note).
"'" :
"null");
1250 $sql .=
", '".$this->db->idate($now).
"'";
1255 $tasktime_id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"projet_task_time");
1256 $ret = $tasktime_id;
1257 $this->timespent_id = $ret;
1261 $result = $this->call_trigger(
'TASK_TIMESPENT_CREATE', $user);
1268 $this->error = $this->
db->lasterror();
1274 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1275 $sql .=
" SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX.
"projet_task_time as ptt where ptt.fk_task = ".((int) $this->
id).
")";
1276 if (isset($this->progress)) {
1277 $sql .=
", progress = ".((float) $this->progress);
1279 $sql .=
" WHERE rowid = ".((int) $this->
id);
1281 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1282 if (!$this->
db->query($sql)) {
1283 $this->error = $this->
db->lasterror();
1288 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task_time";
1289 $sql .=
" SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX.
"user WHERE rowid = ".((int) $this->timespent_fk_user).
")";
1290 $sql .=
" WHERE rowid = ".((int) $tasktime_id);
1292 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1293 if (!$this->
db->query($sql)) {
1294 $this->error = $this->
db->lasterror();
1300 $this->
db->commit();
1302 $this->
db->rollback();
1317 $arrayres = array();
1320 $sql .=
" s.rowid as socid,";
1321 $sql .=
" s.nom as thirdparty_name,";
1322 $sql .=
" s.email as thirdparty_email,";
1323 $sql .=
" ptt.rowid,";
1324 $sql .=
" ptt.fk_task,";
1325 $sql .=
" ptt.task_date,";
1326 $sql .=
" ptt.task_datehour,";
1327 $sql .=
" ptt.task_date_withhour,";
1328 $sql .=
" ptt.task_duration,";
1329 $sql .=
" ptt.fk_user,";
1330 $sql .=
" ptt.note,";
1331 $sql .=
" ptt.thm,";
1332 $sql .=
" pt.rowid as task_id,";
1333 $sql .=
" pt.ref as task_ref,";
1334 $sql .=
" pt.label as task_label,";
1335 $sql .=
" p.rowid as project_id,";
1336 $sql .=
" p.ref as project_ref,";
1337 $sql .=
" p.title as project_label,";
1338 $sql .=
" p.public as public";
1339 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
1340 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1341 $sql .=
" WHERE ptt.fk_task = pt.rowid AND pt.fk_projet = p.rowid";
1342 $sql .=
" AND pt.rowid = ".((int) $this->
id);
1343 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
1344 if ($morewherefilter) {
1345 $sql .= $morewherefilter;
1348 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
1351 $num = $this->
db->num_rows(
$resql);
1355 $obj = $this->
db->fetch_object(
$resql);
1357 $newobj =
new stdClass();
1359 $newobj->socid = $obj->socid;
1360 $newobj->thirdparty_name = $obj->thirdparty_name;
1361 $newobj->thirdparty_email = $obj->thirdparty_email;
1363 $newobj->fk_project = $obj->project_id;
1364 $newobj->project_ref = $obj->project_ref;
1365 $newobj->project_label = $obj->project_label;
1366 $newobj->public = $obj->project_public;
1368 $newobj->fk_task = $obj->task_id;
1369 $newobj->task_ref = $obj->task_ref;
1370 $newobj->task_label = $obj->task_label;
1372 $newobj->timespent_line_id = $obj->rowid;
1373 $newobj->timespent_line_date = $this->
db->jdate($obj->task_date);
1374 $newobj->timespent_line_datehour = $this->
db->jdate($obj->task_datehour);
1375 $newobj->timespent_line_withhour = $obj->task_date_withhour;
1376 $newobj->timespent_line_duration = $obj->task_duration;
1377 $newobj->timespent_line_fk_user = $obj->fk_user;
1378 $newobj->timespent_line_thm = $obj->thm;
1379 $newobj->timespent_line_note = $obj->note;
1381 $arrayres[] = $newobj;
1388 $this->lines = $arrayres;
1392 $this->error =
"Error ".$this->db->lasterror();
1409 if (is_object($userobj)) {
1410 $userid = $userobj->id;
1416 if (empty($id) && empty($userid)) {
1417 dol_syslog(
"getSummaryOfTimeSpent called on a not loaded task without user param defined", LOG_ERR);
1424 $sql .=
" MIN(t.task_datehour) as min_date,";
1425 $sql .=
" MAX(t.task_datehour) as max_date,";
1426 $sql .=
" SUM(t.task_duration) as total_duration,";
1427 $sql .=
" SUM(t.task_duration / 3600 * ".$this->db->ifsql(
"t.thm IS NULL", 0,
"t.thm").
") as total_amount,";
1428 $sql .=
" COUNT(t.rowid) as nblines,";
1429 $sql .=
" SUM(".$this->db->ifsql(
"t.thm IS NULL", 1, 0).
") as nblinesnull";
1430 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as t";
1431 $sql .=
" WHERE 1 = 1";
1432 if ($morewherefilter) {
1433 $sql .= $morewherefilter;
1436 $sql .=
" AND t.fk_task = ".((int) $id);
1439 $sql .=
" AND t.fk_user = ".((int) $userid);
1442 dol_syslog(get_class($this).
"::getSummaryOfTimeSpent", LOG_DEBUG);
1445 $obj = $this->
db->fetch_object(
$resql);
1447 $result[
'min_date'] = $obj->min_date;
1448 $result[
'max_date'] = $obj->max_date;
1449 $result[
'total_duration'] = $obj->total_duration;
1451 $this->timespent_min_date = $this->
db->jdate($obj->min_date);
1452 $this->timespent_max_date = $this->
db->jdate($obj->max_date);
1453 $this->timespent_total_duration = $obj->total_duration;
1454 $this->timespent_total_amount = $obj->total_amount;
1455 $this->timespent_nblinesnull = ($obj->nblinesnull ? $obj->nblinesnull : 0);
1456 $this->timespent_nblines = ($obj->nblines ? $obj->nblines : 0);
1484 $sql .=
" SUM(t.task_duration) as nbseconds,";
1485 $sql .=
" SUM(t.task_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";
1486 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as t";
1487 $sql .=
" WHERE t.fk_task = ".((int) $id);
1488 if (is_object($fuser) && $fuser->id > 0) {
1489 $sql .=
" AND fk_user = ".((int) $fuser->id);
1492 $datefieldname =
"task_datehour";
1493 $sql .=
" AND (".$datefieldname.
" >= '".$this->
db->idate($dates).
"' OR ".$datefieldname.
" IS NULL)";
1496 $datefieldname =
"task_datehour";
1497 $sql .=
" AND (".$datefieldname.
" <= '".$this->
db->idate($datee).
"' OR ".$datefieldname.
" IS NULL)";
1501 dol_syslog(get_class($this).
"::getSumOfAmount", LOG_DEBUG);
1504 $obj = $this->
db->fetch_object(
$resql);
1506 $result[
'amount'] = $obj->amount;
1507 $result[
'nbseconds'] = $obj->nbseconds;
1508 $result[
'nblinesnull'] = $obj->nblinesnull;
1529 $sql .=
" t.rowid,";
1530 $sql .=
" t.fk_task,";
1531 $sql .=
" t.task_date,";
1532 $sql .=
" t.task_datehour,";
1533 $sql .=
" t.task_date_withhour,";
1534 $sql .=
" t.task_duration,";
1535 $sql .=
" t.fk_user,";
1538 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as t";
1539 $sql .=
" WHERE t.rowid = ".((int) $id);
1541 dol_syslog(get_class($this).
"::fetchTimeSpent", LOG_DEBUG);
1545 $obj = $this->
db->fetch_object(
$resql);
1547 $this->timespent_id = $obj->rowid;
1548 $this->
id = $obj->fk_task;
1549 $this->timespent_date = $this->
db->jdate($obj->task_date);
1550 $this->timespent_datehour = $this->
db->jdate($obj->task_datehour);
1551 $this->timespent_withhour = $obj->task_date_withhour;
1552 $this->timespent_duration = $obj->task_duration;
1553 $this->timespent_fk_user = $obj->fk_user;
1554 $this->timespent_thm = $obj->thm;
1555 $this->timespent_note = $obj->note;
1562 $this->error =
"Error ".$this->db->lasterror();
1578 $arrayres = array();
1581 $sql .=
" s.rowid as socid,";
1582 $sql .=
" s.nom as thirdparty_name,";
1583 $sql .=
" s.email as thirdparty_email,";
1584 $sql .=
" ptt.rowid,";
1585 $sql .=
" ptt.fk_task,";
1586 $sql .=
" ptt.task_date,";
1587 $sql .=
" ptt.task_datehour,";
1588 $sql .=
" ptt.task_date_withhour,";
1589 $sql .=
" ptt.task_duration,";
1590 $sql .=
" ptt.fk_user,";
1591 $sql .=
" ptt.note,";
1592 $sql .=
" ptt.thm,";
1593 $sql .=
" pt.rowid as task_id,";
1594 $sql .=
" pt.ref as task_ref,";
1595 $sql .=
" pt.label as task_label,";
1596 $sql .=
" p.rowid as project_id,";
1597 $sql .=
" p.ref as project_ref,";
1598 $sql .=
" p.title as project_label,";
1599 $sql .=
" p.public as public";
1600 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time as ptt, ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet as p";
1601 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
1602 $sql .=
" WHERE ptt.fk_task = pt.rowid AND pt.fk_projet = p.rowid";
1603 $sql .=
" AND ptt.fk_user = ".((int) $userobj->id);
1604 $sql .=
" AND pt.entity IN (".getEntity(
'project').
")";
1605 if ($morewherefilter) {
1606 $sql .= $morewherefilter;
1609 dol_syslog(get_class($this).
"::fetchAllTimeSpent", LOG_DEBUG);
1612 $num = $this->
db->num_rows(
$resql);
1616 $obj = $this->
db->fetch_object(
$resql);
1618 $newobj =
new stdClass();
1620 $newobj->socid = $obj->socid;
1621 $newobj->thirdparty_name = $obj->thirdparty_name;
1622 $newobj->thirdparty_email = $obj->thirdparty_email;
1624 $newobj->fk_project = $obj->project_id;
1625 $newobj->project_ref = $obj->project_ref;
1626 $newobj->project_label = $obj->project_label;
1627 $newobj->public = $obj->project_public;
1629 $newobj->fk_task = $obj->task_id;
1630 $newobj->task_ref = $obj->task_ref;
1631 $newobj->task_label = $obj->task_label;
1633 $newobj->timespent_id = $obj->rowid;
1634 $newobj->timespent_date = $this->
db->jdate($obj->task_date);
1635 $newobj->timespent_datehour = $this->
db->jdate($obj->task_datehour);
1636 $newobj->timespent_withhour = $obj->task_date_withhour;
1637 $newobj->timespent_duration = $obj->task_duration;
1638 $newobj->timespent_fk_user = $obj->fk_user;
1639 $newobj->timespent_thm = $obj->thm;
1640 $newobj->timespent_note = $obj->note;
1642 $arrayres[] = $newobj;
1650 $this->error =
"Error ".$this->db->lasterror();
1666 global $conf, $langs;
1671 if ($this->timespent_date ==
'') {
1672 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Date"));
1675 if (!($this->timespent_fk_user > 0)) {
1676 $this->error = $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"User"));
1681 if (empty($this->timespent_datehour)) {
1682 $this->timespent_datehour = $this->timespent_date;
1684 if (isset($this->timespent_note)) {
1685 $this->timespent_note = trim($this->timespent_note);
1688 if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1689 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1692 if ($this->timespent_date < $restrictBefore) {
1693 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1694 $this->errors[] = $this->error;
1701 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task_time SET";
1702 $sql .=
" task_date = '".$this->db->idate($this->timespent_date).
"',";
1703 $sql .=
" task_datehour = '".$this->db->idate($this->timespent_datehour).
"',";
1704 $sql .=
" task_date_withhour = ".(empty($this->timespent_withhour) ? 0 : 1).
",";
1705 $sql .=
" task_duration = ".((int) $this->timespent_duration).
",";
1706 $sql .=
" fk_user = ".((int) $this->timespent_fk_user).
",";
1707 $sql .=
" note = ".(isset($this->timespent_note) ?
"'".$this->db->escape($this->timespent_note).
"'" :
"null");
1708 $sql .=
" WHERE rowid = ".((int) $this->timespent_id);
1710 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
1711 if ($this->
db->query($sql)) {
1714 $result = $this->call_trigger(
'TASK_TIMESPENT_MODIFY', $user);
1716 $this->
db->rollback();
1726 $this->error = $this->
db->lasterror();
1727 $this->
db->rollback();
1731 if ($ret == 1 && ($this->timespent_old_duration != $this->timespent_duration)) {
1733 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1734 $sql .=
" SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX.
"projet_task_time as ptt where ptt.fk_task = ".((int) $this->
id).
")";
1735 if (isset($this->progress)) {
1736 $sql .=
", progress = ".((float) $this->progress);
1738 $sql .=
" WHERE rowid = ".((int) $this->
id);
1740 dol_syslog(get_class($this).
"::updateTimeSpent", LOG_DEBUG);
1741 if (!$this->
db->query($sql)) {
1742 $this->error = $this->
db->lasterror();
1743 $this->
db->rollback();
1748 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task_time";
1749 $sql .=
" SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX.
"user WHERE rowid = ".((int) $this->timespent_fk_user).
")";
1750 $sql .=
" WHERE (thm IS NULL OR thm = 0) AND rowid = ".((int) $this->timespent_id);
1752 dol_syslog(get_class($this).
"::addTimeSpent", LOG_DEBUG);
1753 if (!$this->
db->query($sql)) {
1754 $this->error = $this->
db->lasterror();
1760 $this->
db->commit();
1774 global $conf, $langs;
1778 if (! empty($conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS)) {
1779 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
1782 if ($this->timespent_date < $restrictBefore) {
1783 $this->error = $langs->trans(
'TimeRecordingRestrictedToNMonthsBack', $conf->global->PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS);
1784 $this->errors[] = $this->error;
1793 $result = $this->call_trigger(
'TASK_TIMESPENT_DELETE', $user);
1801 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_task_time";
1802 $sql .=
" WHERE rowid = ".((int) $this->timespent_id);
1804 dol_syslog(get_class($this).
"::delTimeSpent", LOG_DEBUG);
1807 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
1812 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet_task";
1813 $sql .=
" SET duration_effective = duration_effective - ".$this->db->escape($this->timespent_duration ? $this->timespent_duration : 0);
1814 $sql .=
" WHERE rowid = ".((int) $this->
id);
1816 dol_syslog(get_class($this).
"::delTimeSpent", LOG_DEBUG);
1817 if ($this->
db->query($sql)) {
1820 $this->error = $this->
db->lasterror();
1827 foreach ($this->errors as $errmsg) {
1828 dol_syslog(get_class($this).
"::delTimeSpent ".$errmsg, LOG_ERR);
1829 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1831 $this->
db->rollback();
1834 $this->
db->commit();
1853 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)
1855 global $langs, $conf;
1864 $clone_task =
new Task($this->
db);
1865 $origin_task =
new Task($this->
db);
1867 $clone_task->context[
'createfromclone'] =
'createfromclone';
1872 $clone_task->fetch($fromid);
1873 $clone_task->fetch_optionals();
1876 $origin_task->fetch($fromid);
1879 $obj = empty($conf->global->PROJECT_TASK_ADDON) ?
'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON;
1880 if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT.
"/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.
".php")) {
1881 require_once DOL_DOCUMENT_ROOT.
"/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.
'.php';
1882 $modTask =
new $obj;
1883 $defaultref = $modTask->getNextValue(0, $clone_task);
1886 $ori_project_id = $clone_task->fk_project;
1888 $clone_task->id = 0;
1889 $clone_task->ref = $defaultref;
1890 $clone_task->fk_project = $project_id;
1891 $clone_task->fk_task_parent = $parent_task_id;
1892 $clone_task->date_c = $datec;
1893 $clone_task->planned_workload = $origin_task->planned_workload;
1894 $clone_task->rang = $origin_task->rang;
1897 if ($clone_change_dt) {
1898 $projectstatic =
new Project($this->
db);
1899 $projectstatic->fetch($ori_project_id);
1902 $orign_project_dt_start = $projectstatic->date_start;
1905 if (!empty($clone_task->date_start)) {
1906 $clone_task->date_start = $now + $clone_task->date_start - $orign_project_dt_start;
1910 if (!empty($clone_task->date_end)) {
1911 $clone_task->date_end = $now + $clone_task->date_end - $orign_project_dt_start;
1916 $clone_task->progress = 0;
1920 $result = $clone_task->create($user);
1924 $this->error = $clone_task->error;
1930 $clone_task_id = $clone_task->id;
1931 $clone_task_ref = $clone_task->ref;
1935 $clone_task->note_private =
'';
1936 $clone_task->note_public =
'';
1939 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
1941 $this->error .= $clone_task->error;
1943 $this->
db->rollback();
1945 $this->
db->commit();
1949 $res = $clone_task->update_note(
dol_html_entity_decode($clone_task->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
1951 $this->error .= $clone_task->error;
1953 $this->
db->rollback();
1955 $this->
db->commit();
1961 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1964 $projectstatic =
new Project($this->
db);
1965 $projectstatic->fetch($ori_project_id);
1966 $ori_project_ref = $projectstatic->ref;
1968 if ($ori_project_id != $project_id) {
1969 $projectstatic->fetch($project_id);
1970 $clone_project_ref = $projectstatic->ref;
1972 $clone_project_ref = $ori_project_ref;
1978 $filearray =
dol_dir_list($ori_task_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
1979 foreach ($filearray as $key => $file) {
1980 if (!file_exists($clone_task_dir)) {
1982 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
1987 $rescopy =
dol_copy($ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name'], 0, 1);
1988 if (is_numeric($rescopy) && $rescopy < 0) {
1989 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_task_dir.
'/'.$file[
'name'], $clone_task_dir.
'/'.$file[
'name']);
1996 if ($clone_affectation) {
1997 $origin_task =
new Task($this->
db);
1998 $origin_task->fetch($fromid);
2000 foreach (array(
'internal',
'external') as $source) {
2001 $tab = $origin_task->liste_contact(-1, $source);
2005 $clone_task->add_contact($tab[$i][
'id'], $tab[$i][
'code'], $tab[$i][
'source']);
2006 if ($clone_task->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
2007 $langs->load(
"errors");
2008 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
2011 if ($clone_task->error !=
'') {
2012 $this->error .= $clone_task->error;
2026 unset($clone_task->context[
'createfromclone']);
2029 $this->
db->commit();
2030 return $clone_task_id;
2032 $this->
db->rollback();
2033 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
2047 return $this->LibStatut($this->fk_statut, $mode);
2064 $this->statuts[0] =
'Draft';
2065 $this->statuts[1] =
'ToDo';
2066 $this->statuts[2] =
'Running';
2067 $this->statuts[3] =
'Finish';
2068 $this->statuts[4] =
'Transfered';
2069 $this->statuts_short[0] =
'Draft';
2070 $this->statuts_short[1] =
'ToDo';
2071 $this->statuts_short[2] =
'Running';
2072 $this->statuts_short[3] =
'Completed';
2073 $this->statuts_short[4] =
'Transfered';
2076 return $langs->trans($this->statuts[$status]);
2077 } elseif ($mode == 1) {
2078 return $langs->trans($this->statuts_short[$status]);
2079 } elseif ($mode == 2) {
2081 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0').
' '.$langs->trans($this->statuts_short[$status]);
2082 } elseif ($status == 1) {
2083 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1').
' '.$langs->trans($this->statuts_short[$status]);
2084 } elseif ($status == 2) {
2085 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3').
' '.$langs->trans($this->statuts_short[$status]);
2086 } elseif ($status == 3) {
2087 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts_short[$status]);
2088 } elseif ($status == 4) {
2089 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts_short[$status]);
2090 } elseif ($status == 5) {
2091 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5').
' '.$langs->trans($this->statuts_short[$status]);
2093 } elseif ($mode == 3) {
2095 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0');
2096 } elseif ($status == 1) {
2097 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1');
2098 } elseif ($status == 2) {
2099 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3');
2100 } elseif ($status == 3) {
2101 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6');
2102 } elseif ($status == 4) {
2103 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6');
2104 } elseif ($status == 5) {
2105 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5');
2107 } elseif ($mode == 4) {
2109 return img_picto($langs->trans($this->statuts_short[$status]),
'statut0').
' '.$langs->trans($this->statuts[$status]);
2110 } elseif ($status == 1) {
2111 return img_picto($langs->trans($this->statuts_short[$status]),
'statut1').
' '.$langs->trans($this->statuts[$status]);
2112 } elseif ($status == 2) {
2113 return img_picto($langs->trans($this->statuts_short[$status]),
'statut3').
' '.$langs->trans($this->statuts[$status]);
2114 } elseif ($status == 3) {
2115 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts[$status]);
2116 } elseif ($status == 4) {
2117 return img_picto($langs->trans($this->statuts_short[$status]),
'statut6').
' '.$langs->trans($this->statuts[$status]);
2118 } elseif ($status == 5) {
2119 return img_picto($langs->trans($this->statuts_short[$status]),
'statut5').
' '.$langs->trans($this->statuts[$status]);
2121 } elseif ($mode == 5) {
2131 } elseif ($mode == 6) {
2154 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2158 $outputlangs->load(
"projects");
2161 $modele =
'nodefault';
2163 if (!empty($this->model_pdf)) {
2164 $modele = $this->model_pdf;
2165 } elseif (!empty($this->modelpdf)) {
2166 $modele = $this->modelpdf;
2167 } elseif (!empty($conf->global->PROJECT_TASK_ADDON_PDF)) {
2168 $modele = $conf->global->PROJECT_TASK_ADDON_PDF;
2172 $modelpath =
"core/modules/project/task/doc/";
2174 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2188 global $conf, $langs;
2194 $projectstatic =
new Project($this->
db);
2195 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
2198 $sql =
"SELECT p.rowid as projectid, p.fk_statut as projectstatus,";
2199 $sql .=
" t.rowid as taskid, t.progress as progress, t.fk_statut as status,";
2200 $sql .=
" t.dateo as date_start, t.datee as datee";
2201 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2204 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2205 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2206 $sql .=
" AND p.fk_statut = 1";
2207 $sql .=
" AND t.fk_projet = p.rowid";
2208 $sql .=
" AND (t.progress IS NULL OR t.progress < 100)";
2209 if (empty($user->rights->projet->all->lire)) {
2210 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2220 $task_static =
new Task($this->
db);
2223 $response->warning_delay = $conf->project->task->warning_delay / 60 / 60 / 24;
2224 $response->label = $langs->trans(
"OpenedTasks");
2225 if ($user->rights->projet->all->lire) {
2226 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mainmenu=project';
2228 $response->url = DOL_URL_ROOT.
'/projet/tasks/list.php?mode=mine&mainmenu=project';
2233 while ($obj = $this->
db->fetch_object(
$resql)) {
2234 $response->nbtodo++;
2236 $task_static->projectstatus = $obj->projectstatus;
2237 $task_static->progress = $obj->progress;
2238 $task_static->fk_statut = $obj->status;
2239 $task_static->date_end = $this->
db->jdate($obj->datee);
2241 if ($task_static->hasDelay()) {
2242 $response->nbtodolate++;
2248 $this->error = $this->
db->error();
2265 $mine = 0; $socid = $user->socid;
2267 $projectstatic =
new Project($this->
db);
2268 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, $mine, 1, $socid);
2271 $sql =
"SELECT count(p.rowid) as nb";
2272 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2273 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
2274 if (empty($user->rights->societe->client->voir) && !$socid) {
2275 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON sc.fk_soc = s.rowid";
2277 $sql .=
", ".MAIN_DB_PREFIX.
"projet_task as t";
2278 $sql .=
" WHERE p.entity IN (".getEntity(
'project', 0).
')';
2279 $sql .=
" AND t.fk_projet = p.rowid";
2280 if ($mine || empty($user->rights->projet->all->lire)) {
2281 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2286 $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).
")";
2288 if (empty($user->rights->societe->client->voir) && !$socid) {
2289 $sql .=
" AND ((s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id).
") OR (s.rowid IS NULL))";
2295 while ($obj = $this->
db->fetch_object(
$resql)) {
2296 $this->nb[
"tasks"] = $obj->nb;
2302 $this->error = $this->
db->error();
2316 if (!($this->progress >= 0 && $this->progress < 100)) {
2322 $datetouse = ($this->date_end > 0) ? $this->date_end : ((isset($this->datee) && $this->datee > 0) ? $this->datee : 0);
2324 return ($datetouse > 0 && ($datetouse < ($now - $conf->project->task->warning_delay)));