29 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
40 public $element =
'project';
45 public $table_element =
'projet';
50 public $table_element_line =
'projet_task';
55 public $table_element_date;
60 public $fk_element =
'fk_projet';
66 public $ismultientitymanaged = 1;
71 public $picto =
'project';
93 public $thirdparty_name;
100 public $fk_user_close;
105 public $user_close_id;
107 public $budget_amount;
108 public $usage_bill_time;
110 public $statuts_short;
111 public $statuts_long;
121 public $weekWorkLoad;
122 public $weekWorkLoadPerTask;
181 public $fields = array(
182 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
183 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>1,
'showoncombobox'=>1,
'position'=>15,
'searchall'=>1),
184 'title' =>array(
'type'=>
'varchar(255)',
'label'=>
'ProjectLabel',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'position'=>17,
'showoncombobox'=>1,
'searchall'=>1),
185 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>3,
'notnull'=>1,
'position'=>19),
186 'fk_soc' =>array(
'type'=>
'integer',
'label'=>
'Thirdparty',
'enabled'=>1,
'visible'=>0,
'position'=>20),
187 'dateo' =>array(
'type'=>
'date',
'label'=>
'DateStart',
'enabled'=>1,
'visible'=>1,
'position'=>30),
188 'datee' =>array(
'type'=>
'date',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>1,
'position'=>35),
189 'description' =>array(
'type'=>
'text',
'label'=>
'Description',
'enabled'=>1,
'visible'=>3,
'position'=>55,
'searchall'=>1),
190 'public' =>array(
'type'=>
'integer',
'label'=>
'Visibility',
'enabled'=>1,
'visible'=>1,
'position'=>65),
191 'fk_opp_status' =>array(
'type'=>
'integer',
'label'=>
'OpportunityStatusShort',
'enabled'=>1,
'visible'=>1,
'position'=>75),
192 'opp_percent' =>array(
'type'=>
'double(5,2)',
'label'=>
'OpportunityProbabilityShort',
'enabled'=>1,
'visible'=>1,
'position'=>80),
193 'note_private' =>array(
'type'=>
'text',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>85,
'searchall'=>1),
194 'note_public' =>array(
'type'=>
'text',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>90,
'searchall'=>1),
195 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'ModelPdf',
'enabled'=>1,
'visible'=>0,
'position'=>95),
196 'date_close' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>0,
'position'=>105),
197 'fk_user_close' =>array(
'type'=>
'integer',
'label'=>
'UserClosing',
'enabled'=>1,
'visible'=>0,
'position'=>110),
198 'opp_amount' =>array(
'type'=>
'double(24,8)',
'label'=>
'OpportunityAmountShort',
'enabled'=>1,
'visible'=>1,
'position'=>115),
199 'budget_amount' =>array(
'type'=>
'double(24,8)',
'label'=>
'Budget',
'enabled'=>1,
'visible'=>1,
'position'=>119),
200 'usage_bill_time' =>array(
'type'=>
'integer',
'label'=>
'UsageBillTimeShort',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
201 'usage_opportunity' =>array(
'type'=>
'integer',
'label'=>
'UsageOpportunity',
'enabled'=>1,
'visible'=>-1,
'position'=>135),
202 'usage_task' =>array(
'type'=>
'integer',
'label'=>
'UsageTasks',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
203 'usage_organize_event' =>array(
'type'=>
'integer',
'label'=>
'Usage organize event',
'enabled'=>1,
'visible'=>-1,
'position'=>145),
204 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreationShort',
'enabled'=>1,
'visible'=>-2,
'position'=>200),
205 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModificationShort',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>205),
206 'fk_user_creat' =>array(
'type'=>
'integer',
'label'=>
'UserCreation',
'enabled'=>1,
'visible'=>0,
'notnull'=>1,
'position'=>210),
207 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'UserModification',
'enabled'=>1,
'visible'=>0,
'position'=>215),
208 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>0,
'position'=>220),
209 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'position'=>500)
237 $this->statuts_short = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
238 $this->statuts_long = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
242 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->
fields[
'rowid'][
'visible'] = 0;
244 if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
245 $this->
fields[
'fk_opp_status'][
'enabled'] = 0;
246 $this->
fields[
'opp_percent'][
'enabled'] = 0;
247 $this->
fields[
'opp_amount'][
'enabled'] = 0;
248 $this->
fields[
'usage_opportunity'][
'enabled'] = 0;
251 if (empty($conf->global->PROJECT_HIDE_TASKS)) {
252 $this->
fields[
'usage_bill_time'][
'visible'] = 0;
253 $this->
fields[
'usage_task'][
'visible'] = 0;
256 if (empty($conf->global->PROJECT_ORGANIZE_EVENTS)) {
257 $this->
fields[
'usage_organize_event'][
'visible'] = 0;
268 public function create($user, $notrigger = 0)
270 global $conf, $langs;
278 $this->note_private =
dol_substr($this->note_private, 0, 65535);
279 $this->note_public =
dol_substr($this->note_public, 0, 65535);
282 if (!trim($this->ref))
284 $this->error =
'ErrorFieldsRequired';
285 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
288 if (!empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) && !($this->socid > 0))
290 $this->error =
'ErrorFieldsRequired';
291 dol_syslog(get_class($this).
"::create error -1 thirdparty not defined and option PROJECT_THIRDPARTY_REQUIRED is set", LOG_ERR);
298 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet (";
301 $sql .=
", description";
303 $sql .=
", fk_user_creat";
304 $sql .=
", fk_statut";
305 $sql .=
", fk_opp_status";
306 $sql .=
", opp_percent";
311 $sql .=
", opp_amount";
312 $sql .=
", budget_amount";
313 $sql .=
", usage_opportunity";
314 $sql .=
", usage_task";
315 $sql .=
", usage_bill_time";
316 $sql .=
", usage_organize_event";
317 $sql .=
", email_msgid";
318 $sql .=
", note_private";
319 $sql .=
", note_public";
321 $sql .=
") VALUES (";
322 $sql .=
"'".$this->db->escape($this->ref).
"'";
323 $sql .=
", '".$this->db->escape($this->title).
"'";
324 $sql .=
", '".$this->db->escape($this->
description).
"'";
325 $sql .=
", ".($this->socid > 0 ? $this->socid :
"null");
326 $sql .=
", ".$user->id;
327 $sql .=
", ".(is_numeric($this->
statut) ? $this->
statut :
'0');
328 $sql .=
", ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status :
'NULL');
329 $sql .=
", ".(is_numeric($this->opp_percent) ? $this->opp_percent :
'NULL');
330 $sql .=
", ".($this->public ? 1 : 0);
331 $sql .=
", '".$this->db->idate($now).
"'";
332 $sql .=
", ".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
333 $sql .=
", ".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
334 $sql .=
", ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
'null');
335 $sql .=
", ".(strcmp($this->budget_amount,
'') ?
price2num($this->budget_amount) :
'null');
336 $sql .=
", ".($this->usage_opportunity ? 1 : 0);
337 $sql .=
", ".($this->usage_task ? 1 : 0);
338 $sql .=
", ".($this->usage_bill_time ? 1 : 0);
339 $sql .=
", ".($this->usage_organize_event ? 1 : 0);
340 $sql .=
", ".($this->email_msgid ?
"'".$this->db->escape($this->email_msgid).
"'" :
'null');
341 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
'null');
342 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
'null');
343 $sql .=
", ".$conf->entity;
346 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
350 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"projet");
357 if ($result < 0) { $error++; }
361 $this->error = $this->
db->lasterror();
362 $this->errno = $this->
db->lasterrno();
375 if (!$error && !empty($conf->global->MAIN_DISABLEDRAFTSTATUS))
378 if ($res < 0) $error++;
386 $this->
db->rollback();
398 public function update($user, $notrigger = 0)
400 global $langs, $conf;
405 $this->title = trim($this->title);
407 if ($this->opp_amount < 0) $this->opp_amount =
'';
408 if ($this->opp_percent < 0) $this->opp_percent =
'';
409 if ($this->date_end && $this->date_end < $this->date_start)
411 $this->error = $langs->trans(
"ErrorDateEndLowerThanDateStart");
412 $this->errors[] = $this->error;
413 $this->
db->rollback();
414 dol_syslog(get_class($this).
"::update error -3 ".$this->error, LOG_ERR);
422 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet SET";
423 $sql .=
" ref='".$this->db->escape($this->ref).
"'";
424 $sql .=
", title = '".$this->db->escape($this->title).
"'";
425 $sql .=
", description = '".$this->db->escape($this->
description).
"'";
426 $sql .=
", fk_soc = ".($this->socid > 0 ? $this->socid :
"null");
427 $sql .=
", fk_statut = ".$this->statut;
428 $sql .=
", fk_opp_status = ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status :
'null');
429 $sql .=
", opp_percent = ".((is_numeric($this->opp_percent) && $this->opp_percent !=
'') ? $this->opp_percent :
'null');
430 $sql .=
", public = ".($this->public ? 1 : 0);
431 $sql .=
", datec=".($this->date_c !=
'' ?
"'".$this->db->idate($this->date_c).
"'" :
'null');
432 $sql .=
", dateo=".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
433 $sql .=
", datee=".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
434 $sql .=
", date_close=".($this->date_close !=
'' ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
435 $sql .=
", fk_user_close=".($this->fk_user_close > 0 ? $this->fk_user_close :
"null");
436 $sql .=
", opp_amount = ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
"null");
437 $sql .=
", budget_amount = ".(strcmp($this->budget_amount,
'') ?
price2num($this->budget_amount) :
"null");
438 $sql .=
", fk_user_modif = ".$user->id;
439 $sql .=
", usage_opportunity = ".($this->usage_opportunity ? 1 : 0);
440 $sql .=
", usage_task = ".($this->usage_task ? 1 : 0);
441 $sql .=
", usage_bill_time = ".($this->usage_bill_time ? 1 : 0);
442 $sql .=
", usage_organize_event = ".($this->usage_organize_event ? 1 : 0);
443 $sql .=
" WHERE rowid = ".$this->id;
445 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
459 if (!$error && !$notrigger)
463 if ($result < 0) { $error++; }
467 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref))
470 if ($conf->projet->dir_output)
474 if (file_exists($olddir))
476 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
477 $res = @rename($olddir, $newdir);
480 $langs->load(
"errors");
481 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
492 $this->
db->rollback();
496 $this->error = $this->
db->lasterror();
497 $this->errors[] = $this->error;
498 $this->
db->rollback();
499 if ($this->
db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS')
505 dol_syslog(get_class($this).
"::update error ".$result.
" ".$this->error, LOG_ERR);
508 dol_syslog(get_class($this).
"::update ref null");
524 public function fetch($id, $ref =
'', $ref_ext =
'', $email_msgid =
'')
528 if (empty($id) && empty($ref))
return -1;
530 $sql =
"SELECT rowid, entity, ref, title, description, public, datec, opp_amount, budget_amount,";
531 $sql .=
" tms, dateo, datee, date_close, fk_soc, fk_user_creat, fk_user_modif, fk_user_close, fk_statut as status, fk_opp_status, opp_percent,";
532 $sql .=
" note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, email_msgid";
533 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet";
536 $sql .=
" WHERE rowid = ".$id;
538 $sql .=
" WHERE entity IN (".getEntity(
'project').
")";
540 $sql .=
" AND ref = '".$this->db->escape($ref).
"'";
541 } elseif (!empty($ref_ext)) {
542 $sql .=
" AND ref_ext = '".$this->db->escape($ref_ext).
"'";
544 $sql .=
" AND email_msgid = '".$this->db->escape($email_msgid).
"'";
548 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
552 $num_rows = $this->
db->num_rows(
$resql);
556 $obj = $this->
db->fetch_object(
$resql);
558 $this->
id = $obj->rowid;
559 $this->entity = $obj->entity;
560 $this->ref = $obj->ref;
561 $this->title = $obj->title;
563 $this->date_c = $this->
db->jdate($obj->datec);
564 $this->datec = $this->
db->jdate($obj->datec);
565 $this->date_m = $this->
db->jdate($obj->tms);
566 $this->datem = $this->
db->jdate($obj->tms);
567 $this->date_start = $this->
db->jdate($obj->dateo);
568 $this->date_end = $this->
db->jdate($obj->datee);
569 $this->date_close = $this->
db->jdate($obj->date_close);
570 $this->note_private = $obj->note_private;
571 $this->note_public = $obj->note_public;
572 $this->socid = $obj->fk_soc;
573 $this->user_author_id = $obj->fk_user_creat;
574 $this->user_modification_id = $obj->fk_user_modif;
575 $this->user_close_id = $obj->fk_user_close;
576 $this->
public = $obj->public;
577 $this->
statut = $obj->status;
578 $this->status = $obj->status;
579 $this->opp_status = $obj->fk_opp_status;
580 $this->opp_amount = $obj->opp_amount;
581 $this->opp_percent = $obj->opp_percent;
582 $this->budget_amount = $obj->budget_amount;
583 $this->model_pdf = $obj->model_pdf;
584 $this->modelpdf = $obj->model_pdf;
585 $this->usage_opportunity = (int) $obj->usage_opportunity;
586 $this->usage_task = (
int) $obj->usage_task;
587 $this->usage_bill_time = (int) $obj->usage_bill_time;
588 $this->usage_organize_event = (
int) $obj->usage_organize_event;
589 $this->email_msgid = $obj->email_msgid;
604 $this->error = $this->
db->lasterror();
621 public function get_element_list($type, $tablename, $datefieldname =
'', $dates =
'', $datee =
'', $projectkey =
'fk_projet')
629 if ($this->
id <= 0)
return $elements;
633 if ($type ==
'agenda')
635 $sql =
"SELECT id as rowid FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project IN (".$ids.
") AND entity IN (".
getEntity(
'agenda').
")";
636 } elseif ($type ==
'expensereport')
638 $sql =
"SELECT ed.rowid FROM ".MAIN_DB_PREFIX.
"expensereport as e, ".MAIN_DB_PREFIX.
"expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".
getEntity(
'expensereport').
") AND ed.fk_projet IN (".$ids.
")";
639 } elseif ($type ==
'project_task')
641 $sql =
"SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet IN (".$ids.
")";
642 } elseif ($type ==
'project_task_time')
644 $sql =
"SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet IN (".$ids.
")";
645 } elseif ($type ==
'stock_mouvement')
647 $sql =
'SELECT ms.rowid, ms.fk_user_author as fk_user FROM '.MAIN_DB_PREFIX.
"stock_mouvement as ms, ".MAIN_DB_PREFIX.
"entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".
getEntity(
'stock').
") AND ms.origintype = 'project' AND ms.fk_origin IN (".$ids.
") AND ms.type_mouvement = 1";
648 } elseif ($type ==
'loan')
650 $sql =
'SELECT l.rowid, l.fk_user_author as fk_user FROM '.MAIN_DB_PREFIX.
"loan as l WHERE l.entity IN (".
getEntity(
'loan').
") AND l.fk_projet IN (".$ids.
")";
652 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" IN (".$ids.
") AND entity IN (".
getEntity($type).
")";
655 if ($dates > 0 && $type ==
'loan') {
656 $sql .=
" AND (dateend > '".$this->db->idate($dates).
"' OR dateend IS NULL)";
657 } elseif ($dates > 0 && ($type !=
'project_task'))
659 if (empty($datefieldname) && !empty($this->table_element_date)) $datefieldname = $this->table_element_date;
660 if (empty($datefieldname))
return 'Error this object has no date field defined';
661 $sql .=
" AND (".$datefieldname.
" >= '".$this->
db->idate($dates).
"' OR ".$datefieldname.
" IS NULL)";
664 if ($datee > 0 && $type ==
'loan') {
665 $sql .=
" AND (datestart < '".$this->db->idate($datee).
"' OR datestart IS NULL)";
666 } elseif ($datee > 0 && ($type !=
'project_task'))
668 if (empty($datefieldname) && !empty($this->table_element_date)) $datefieldname = $this->table_element_date;
669 if (empty($datefieldname))
return 'Error this object has no date field defined';
670 $sql .=
" AND (".$datefieldname.
" <= '".$this->
db->idate($datee).
"' OR ".$datefieldname.
" IS NULL)";
676 'tablename' => $tablename,
677 'datefieldname' => $datefieldname,
680 'fk_projet' => $projectkey
682 $reshook = $hookmanager->executeHooks(
'getElementList', $parameters, $object, $action);
683 if ($reshook > 0) $sql = $hookmanager->resPrint;
684 else $sql .= $hookmanager->resPrint;
686 if (!$sql)
return -1;
689 dol_syslog(get_class($this).
"::get_element_list", LOG_DEBUG);
690 $result = $this->
db->query($sql);
693 $nump = $this->
db->num_rows($result);
699 $obj = $this->
db->fetch_object($result);
701 $elements[$i] = $obj->rowid.(empty($obj->fk_user) ?
'' :
'_'.$obj->fk_user);
705 $this->
db->free($result);
722 public function delete($user, $notrigger = 0)
724 global $langs, $conf;
725 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
737 $this->error =
'ErrorFailToDeleteLinkedContact';
739 $this->
db->rollback();
745 $listoftables = array(
746 'propal'=>
'fk_projet',
'commande'=>
'fk_projet',
'facture'=>
'fk_projet',
747 'supplier_proposal'=>
'fk_projet',
'commande_fournisseur'=>
'fk_projet',
'facture_fourn'=>
'fk_projet',
748 'expensereport_det'=>
'fk_projet',
'contrat'=>
'fk_projet',
'fichinter'=>
'fk_projet',
'don'=>
'fk_projet',
749 'actioncomm'=>
'fk_project',
'mrp_mo'=>
'fk_project'
751 foreach ($listoftables as $key => $value)
753 $sql =
"UPDATE ".MAIN_DB_PREFIX.$key.
" SET ".$value.
" = NULL where ".$value.
" = ".$this->id;
757 $this->errors[] = $this->
db->lasterror();
765 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_project";
766 $sql .=
" WHERE fk_project = ".$this->id;
768 $result = $this->
db->query($sql);
771 $this->errors[] = $this->
db->lasterror();
780 if ($ret < 0) $error++;
785 $elements = array(
'categorie_project');
786 foreach ($elements as $table)
789 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$table;
790 $sql .=
" WHERE fk_project = ".$this->id;
792 $result = $this->
db->query($sql);
795 $this->errors[] = $this->
db->lasterror();
803 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_extrafields";
804 $sql .=
" WHERE fk_object=".$this->id;
809 $this->errors[] = $this->
db->lasterror();
817 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet";
818 $sql .=
" WHERE rowid=".$this->id;
823 $this->errors[] = $langs->trans(
"CantRemoveProject", $langs->transnoentitiesnoconv(
"ProjectOverview"));
833 if ($conf->projet->dir_output) {
834 $dir = $conf->projet->dir_output.
"/".$projectref;
835 if (file_exists($dir)) {
838 $this->errors[] =
'ErrorFailToDeleteDir';
861 foreach ($this->errors as $errmsg)
863 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
864 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
866 dol_syslog(get_class($this).
"::delete ".$this->error, LOG_ERR);
867 $this->
db->rollback();
882 if ($this->
id <= 0)
return 0;
884 if ($type ==
'agenda') {
885 $sql =
"SELECT COUNT(id) as nb FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project = ".$this->
id.
" AND entity IN (".
getEntity(
'agenda').
")";
886 } elseif ($type ==
'expensereport') {
887 $sql =
"SELECT COUNT(ed.rowid) as nb FROM ".MAIN_DB_PREFIX.
"expensereport as e, ".MAIN_DB_PREFIX.
"expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".
getEntity(
'expensereport').
") AND ed.fk_projet = ".$this->id;
888 } elseif ($type ==
'project_task') {
889 $sql =
"SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet = ".$this->id;
890 } elseif ($type ==
'project_task_time') {
891 $sql =
"SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet = ".$this->id;
892 } elseif ($type ==
'stock_mouvement') {
893 $sql =
'SELECT COUNT(ms.rowid) as nb FROM '.MAIN_DB_PREFIX.
"stock_mouvement as ms, ".MAIN_DB_PREFIX.
"entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".
getEntity(
'stock').
") AND ms.origintype = 'project' AND ms.fk_origin = ".$this->
id.
" AND ms.type_mouvement = 1";
894 } elseif ($type ==
'loan') {
895 $sql =
'SELECT COUNT(l.rowid) as nb FROM '.MAIN_DB_PREFIX.
"loan as l WHERE l.entity IN (".
getEntity(
'loan').
") AND l.fk_projet = ".$this->id;
897 $sql =
"SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" = ".$this->
id.
" AND entity IN (".
getEntity($type).
")";
900 $result = $this->
db->query($sql);
902 if (!$result)
return 0;
904 $obj = $this->
db->fetch_object($result);
906 $this->
db->free($result);
919 $countTasks = count($this->lines);
923 foreach ($this->lines as $task)
925 if ($task->hasChildren() <= 0) {
927 $ret = $task->delete($user);
930 $this->errors[] = $this->
db->lasterror();
937 if ($deleted && count($this->lines) < $countTasks)
939 if (count($this->lines)) $this->
deleteTasks($this->lines);
954 global $langs, $conf;
961 if (preg_match(
'/^'.preg_quote($langs->trans(
"CopyOf").
' ').
'/', $this->title))
963 $this->error = $langs->trans(
"ErrorFieldFormat", $langs->transnoentities(
"Label")).
'. '.$langs->trans(
'RemoveString', $langs->transnoentitiesnoconv(
"CopyOf"));
969 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
970 $sql .=
" SET fk_statut = 1";
971 $sql .=
" WHERE rowid = ".$this->id;
972 $sql .=
" AND entity = ".$conf->entity;
974 dol_syslog(get_class($this).
"::setValid", LOG_DEBUG);
979 if (empty($notrigger))
981 $result = $this->
call_trigger(
'PROJECT_VALIDATE', $user);
982 if ($result < 0) { $error++; }
992 $this->
db->rollback();
993 $this->error = join(
',', $this->errors);
994 dol_syslog(get_class($this).
"::setValid ".$this->error, LOG_ERR);
998 $this->
db->rollback();
999 $this->error = $this->
db->lasterror();
1013 global $langs, $conf;
1019 if ($this->
statut != self::STATUS_CLOSED)
1023 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
1024 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", fk_user_close = ".$user->id.
", date_close = '".$this->
db->idate($now).
"'";
1025 $sql .=
" WHERE rowid = ".$this->id;
1026 $sql .=
" AND fk_statut = ".self::STATUS_VALIDATED;
1028 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1033 dol_syslog(get_class($this).
"::setClose", LOG_DEBUG);
1039 if ($result < 0) { $error++; }
1045 $this->
db->commit();
1048 $this->
db->rollback();
1049 $this->error = join(
',', $this->errors);
1050 dol_syslog(get_class($this).
"::setClose ".$this->error, LOG_ERR);
1054 $this->
db->rollback();
1055 $this->error = $this->
db->lasterror();
1087 $statustrans = array(
1093 $statusClass =
'status0';
1094 if (!empty($statustrans[$status])) {
1095 $statusClass = $statustrans[$status];
1098 return dolGetStatus($langs->trans($this->statuts_long[$status]), $langs->trans($this->statuts_short[$status]),
'', $statusClass, $mode);
1114 public function getNomUrl($withpicto = 0, $option =
'', $addlabel = 0, $moreinpopup =
'', $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1, $morecss =
'')
1116 global $conf, $langs, $user, $hookmanager;
1118 if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1;
1121 if (!empty($conf->global->PROJECT_OPEN_ALWAYS_ON_TAB)) {
1122 $option = $conf->global->PROJECT_OPEN_ALWAYS_ON_TAB;
1126 if ($option !=
'nolink') $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Project").
'</u>';
1127 if (isset($this->status)) {
1128 $label .=
' '.$this->getLibStatut(5);
1130 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'Ref').
': </b>'.$this->ref;
1131 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'Label').
': </b>'.$this->title;
1132 if (isset($this->
public)) {
1133 $label .=
'<br><b>'.$langs->trans(
"Visibility").
":</b> ".($this->
public ? $langs->trans(
"SharedProject") : $langs->trans(
"PrivateProject"));
1135 if (!empty($this->thirdparty_name)) {
1136 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'ThirdParty').
': </b>'.$this->thirdparty_name;
1138 if (!empty($this->dateo)) {
1139 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'DateStart').
': </b>'.
dol_print_date($this->dateo,
'day');
1141 if (!empty($this->datee)) {
1142 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'DateEnd').
': </b>'.
dol_print_date($this->datee,
'day');
1144 if ($moreinpopup) $label .=
'<br>'.$moreinpopup;
1147 if ($option !=
'nolink')
1149 if (preg_match(
'/\.php$/', $option)) {
1151 } elseif ($option ==
'task')
1153 $url = DOL_URL_ROOT.
'/projet/tasks.php?id='.$this->id;
1154 } elseif ($option ==
'preview')
1156 $url = DOL_URL_ROOT.
'/projet/element.php?id='.$this->id;
1158 $url = DOL_URL_ROOT.
'/projet/card.php?id='.$this->id;
1161 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1162 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/',
$_SERVER[
"PHP_SELF"])) $add_save_lastsearch_values = 1;
1163 if ($add_save_lastsearch_values) $url .=
'&save_lastsearch_values=1';
1167 if (empty($notooltip) && $user->rights->projet->lire)
1169 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1171 $label = $langs->trans(
"ShowProject");
1172 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1174 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1175 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
1177 else $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1179 $picto =
'projectpub';
1180 if (!$this->
public) $picto =
'project';
1182 $linkstart =
'<a href="'.$url.
'"';
1183 $linkstart .= $linkclose.
'>';
1186 $result .= $linkstart;
1187 if ($withpicto) $result .=
img_object(($notooltip ?
'' : $label), $picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1188 if ($withpicto != 2) $result .= $this->ref;
1189 $result .= $linkend;
1190 if ($withpicto != 2) $result .= (($addlabel && $this->title) ? $sep.dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) :
'');
1193 $hookmanager->initHooks(array(
'projectdao'));
1194 $parameters = array(
'id'=>$this->
id,
'getnomurl'=>$result);
1195 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1196 if ($reshook > 0) $result = $hookmanager->resPrint;
1197 else $result .= $hookmanager->resPrint;
1211 global $user, $langs, $conf;
1217 $this->ref =
'SPECIMEN';
1218 $this->specimen = 1;
1220 $this->date_c = $now;
1221 $this->date_m = $now;
1222 $this->date_start = $now;
1223 $this->date_end = $now + (3600 * 24 * 365);
1224 $this->note_public =
'SPECIMEN';
1225 $this->fk_ele = 20000;
1226 $this->opp_amount = 20000;
1227 $this->budget_amount = 10000;
1229 $this->usage_opportunity = 1;
1230 $this->usage_task = 1;
1231 $this->usage_bill_time = 1;
1232 $this->usage_organize_event = 1;
1261 if (($mode ==
'read' && !empty($user->rights->projet->all->lire)) || ($mode ==
'write' && !empty($user->rights->projet->all->creer)) || ($mode ==
'delete' && !empty($user->rights->projet->all->supprimer)))
1264 } elseif ($this->
public && (($mode ==
'read' && !empty($user->rights->projet->lire)) || ($mode ==
'write' && !empty($user->rights->projet->creer)) || ($mode ==
'delete' && !empty($user->rights->projet->supprimer))))
1268 foreach (array(
'internal',
'external') as $source)
1271 $num = count($userRole);
1274 while ($nblinks < $num)
1276 if ($source ==
'internal' && $user->id == $userRole[$nblinks][
'id'])
1278 if ($mode ==
'read' && $user->rights->projet->lire) $userAccess++;
1279 if ($mode ==
'write' && $user->rights->projet->creer) $userAccess++;
1280 if ($mode ==
'delete' && $user->rights->projet->supprimer) $userAccess++;
1282 if ($source ==
'external' && $user->socid > 0 && $user->socid == $userRole[$nblinks][
'socid'])
1284 if ($mode ==
'read' && $user->rights->projet->lire) $userAccess++;
1285 if ($mode ==
'write' && $user->rights->projet->creer) $userAccess++;
1286 if ($mode ==
'delete' && $user->rights->projet->supprimer) $userAccess++;
1300 return ($userAccess ? $userAccess : -1);
1315 $projects = array();
1318 $sql =
"SELECT ".(($mode == 0 || $mode == 1) ?
"DISTINCT " :
"").
"p.rowid, p.ref";
1319 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
1322 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_contact as ec ON ec.element_id = p.rowid";
1323 } elseif ($mode == 1)
1325 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1326 } elseif ($mode == 2)
1330 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
1333 if ($socid > 0) $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.
")";
1336 $listofprojectcontacttype = array();
1337 $sql2 =
"SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1338 $sql2 .=
" WHERE ctc.element = '".$this->db->escape($this->element).
"'";
1339 $sql2 .=
" AND ctc.source = 'internal'";
1343 while ($obj = $this->
db->fetch_object(
$resql))
1345 $listofprojectcontacttype[$obj->rowid] = $obj->code;
1348 if (count($listofprojectcontacttype) == 0) $listofprojectcontacttype[0] =
'0';
1352 $sql .=
" AND ( p.public = 1";
1353 $sql .=
" OR ( ec.fk_c_type_contact IN (".join(
',', array_keys($listofprojectcontacttype)).
")";
1354 $sql .=
" AND ec.fk_socpeople = ".$user->id.
")";
1356 } elseif ($mode == 1)
1358 $sql .=
" AND ec.element_id = p.rowid";
1360 $sql .=
" ( ec.fk_c_type_contact IN (".join(
',', array_keys($listofprojectcontacttype)).
")";
1361 $sql .=
" AND ec.fk_socpeople = ".$user->id.
")";
1363 } elseif ($mode == 2)
1374 $num = $this->
db->num_rows(
$resql);
1378 $row = $this->
db->fetch_row(
$resql);
1379 $projects[$row[0]] = $row[1];
1388 if (empty($temp))
return '0';
1389 $result = implode(
',', $temp);
1414 public function createFromClone(
User $user, $fromid, $clone_contact =
false, $clone_task =
true, $clone_project_file =
false, $clone_task_file =
false, $clone_note =
true, $move_date =
true, $notrigger = 0, $newthirdpartyid = 0)
1416 global $langs, $conf;
1420 dol_syslog(
"createFromClone clone_contact=".$clone_contact.
" clone_task=".$clone_task.
" clone_project_file=".$clone_project_file.
" clone_note=".$clone_note.
" move_date=".$move_date, LOG_DEBUG);
1424 $clone_project =
new Project($this->
db);
1426 $clone_project->context[
'createfromclone'] =
'createfromclone';
1431 $clone_project->fetch($fromid);
1432 $clone_project->fetch_optionals();
1433 if ($newthirdpartyid > 0) $clone_project->socid = $newthirdpartyid;
1434 $clone_project->fetch_thirdparty();
1436 $orign_dt_start = $clone_project->date_start;
1437 $orign_project_ref = $clone_project->ref;
1439 $clone_project->id = 0;
1441 $clone_project->date_start = $now;
1442 if (!(empty($clone_project->date_end)))
1444 $clone_project->date_end = $clone_project->date_end + ($now - $orign_dt_start);
1448 $clone_project->datec = $now;
1452 $clone_project->note_private =
'';
1453 $clone_project->note_public =
'';
1458 $obj = empty($conf->global->PROJECT_ADDON) ?
'mod_project_simple' : $conf->global->PROJECT_ADDON;
1460 $file =
''; $classname =
''; $filefound = 0;
1461 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1462 foreach ($dirmodels as $reldir)
1464 $file =
dol_buildpath($reldir.
"core/modules/project/".$obj.
'.php', 0);
1465 if (file_exists($file))
1469 $modProject =
new $obj;
1470 $defaultref = $modProject->getNextValue(is_object($clone_project->thirdparty) ? $clone_project->thirdparty : null, $clone_project);
1474 if (is_numeric($defaultref) && $defaultref <= 0) $defaultref =
'';
1476 $clone_project->ref = $defaultref;
1477 $clone_project->title = $langs->trans(
"CopyOf").
' '.$clone_project->title;
1480 $result = $clone_project->create($user, $notrigger);
1485 $this->error .= $clone_project->error;
1492 $clone_project_id = $clone_project->id;
1497 $clone_project->note_private =
'';
1498 $clone_project->note_public =
'';
1501 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
1504 $this->error .= $clone_project->error;
1506 $this->
db->rollback();
1508 $this->
db->commit();
1512 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
1515 $this->error .= $clone_project->error;
1517 $this->
db->rollback();
1519 $this->
db->commit();
1526 $origin_project =
new Project($this->
db);
1527 $origin_project->fetch($fromid);
1529 foreach (array(
'internal',
'external') as $source)
1531 $tab = $origin_project->liste_contact(-1, $source);
1533 foreach ($tab as $contacttoadd)
1535 $clone_project->add_contact($contacttoadd[
'id'], $contacttoadd[
'code'], $contacttoadd[
'source'], $notrigger);
1536 if ($clone_project->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS')
1538 $langs->load(
"errors");
1539 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
1542 if ($clone_project->error !=
'')
1544 $this->error .= $clone_project->error;
1553 if ($clone_project_file)
1555 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1562 $filearray =
dol_dir_list($ori_project_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
1563 foreach ($filearray as $key => $file)
1565 $rescopy =
dol_copy($ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name'], 0, 1);
1566 if (is_numeric($rescopy) && $rescopy < 0)
1568 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name']);
1573 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
1581 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
1583 $taskstatic =
new Task($this->
db);
1587 if ($user->socid > 0) $socid = $user->socid;
1589 $tasksarray = $taskstatic->getTasksArray(0, 0, $fromid, $socid, 0);
1591 $tab_conv_child_parent = array();
1594 foreach ($tasksarray as $tasktoclone)
1596 $result_clone = $taskstatic->createFromClone($user, $tasktoclone->id, $clone_project_id, $tasktoclone->fk_parent, $move_date,
true,
false, $clone_task_file,
true,
false);
1597 if ($result_clone <= 0)
1599 $this->error .= $result_clone->error;
1602 $new_task_id = $result_clone;
1603 $taskstatic->fetch($tasktoclone->id);
1607 if (($taskstatic->hasChildren()) && !array_key_exists($tasktoclone->id, $tab_conv_child_parent))
1609 $tab_conv_child_parent[$tasktoclone->id] = $new_task_id;
1615 $tasksarray = $taskstatic->getTasksArray(0, 0, $clone_project_id, $socid, 0);
1616 foreach ($tasksarray as $task_cloned)
1618 $taskstatic->fetch($task_cloned->id);
1619 if ($taskstatic->fk_task_parent != 0)
1621 $taskstatic->fk_task_parent = $tab_conv_child_parent[$taskstatic->fk_task_parent];
1623 $res = $taskstatic->update($user, $notrigger);
1624 if ($result_clone <= 0)
1626 $this->error .= $taskstatic->error;
1633 unset($clone_project->context[
'createfromclone']);
1637 $this->
db->commit();
1638 return $clone_project_id;
1640 $this->
db->rollback();
1641 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
1655 global $user, $langs, $conf;
1659 $taskstatic =
new Task($this->
db);
1663 if ($user->socid > 0) $socid = $user->socid;
1665 $tasksarray = $taskstatic->getTasksArray(0, 0, $this->
id, $socid, 0);
1667 foreach ($tasksarray as $tasktoshiftdate)
1671 if ((!empty($tasktoshiftdate->date_start)) || (!empty($tasktoshiftdate->date_end)))
1675 $task =
new Task($this->
db);
1676 $result = $task->fetch($tasktoshiftdate->id);
1680 $this->error .= $task->error;
1686 if (!empty($tasktoshiftdate->date_start))
1688 $task->date_start = $this->date_start + ($tasktoshiftdate->date_start - $old_project_dt_start);
1692 if (!empty($tasktoshiftdate->date_end))
1694 $task->date_end = $this->date_start + ($tasktoshiftdate->date_end - $old_project_dt_start);
1699 $result = $task->update($user);
1703 $this->error .= $task->error;
1726 $sql =
"UPDATE ".MAIN_DB_PREFIX.$tableName;
1728 if ($tableName ==
"actioncomm")
1730 $sql .=
" SET fk_project=".$this->id;
1731 $sql .=
" WHERE id=".$elementSelectId;
1733 $sql .=
" SET fk_projet=".$this->id;
1734 $sql .=
" WHERE rowid=".$elementSelectId;
1737 dol_syslog(get_class($this).
"::update_element", LOG_DEBUG);
1740 $this->error = $this->
db->lasterror();
1757 public function remove_element($tableName, $elementSelectId, $projectfield =
'fk_projet')
1760 $sql =
"UPDATE ".MAIN_DB_PREFIX.$tableName;
1762 if ($tableName ==
"actioncomm")
1764 $sql .=
" SET fk_project=NULL";
1765 $sql .=
" WHERE id=".$elementSelectId;
1767 $sql .=
" SET ".$projectfield.
"=NULL";
1768 $sql .=
" WHERE rowid=".$elementSelectId;
1771 dol_syslog(get_class($this).
"::remove_element", LOG_DEBUG);
1774 $this->error = $this->
db->lasterror();
1791 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1793 global $conf, $langs;
1795 $langs->load(
"projects");
1798 $modele =
'baleine';
1800 if ($this->model_pdf) {
1801 $modele = $this->model_pdf;
1802 } elseif (!empty($conf->global->PROJECT_ADDON_PDF)) {
1803 $modele = $conf->global->PROJECT_ADDON_PDF;
1807 $modelpath =
"core/modules/project/doc/";
1809 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
1826 $this->weekWorkLoad = array();
1827 $this->weekWorkLoadPerTask = array();
1829 if (empty($datestart))
dol_print_error(
'',
'Error datestart parameter is empty');
1831 $sql =
"SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task";
1832 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
1833 $sql .=
" WHERE ptt.fk_task = pt.rowid";
1834 $sql .=
" AND pt.fk_projet = ".$this->id;
1835 $sql .=
" AND (ptt.task_date >= '".$this->db->idate($datestart).
"' ";
1836 $sql .=
" AND ptt.task_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'w') - 1).
"')";
1837 if ($taskid) $sql .=
" AND ptt.fk_task=".$taskid;
1838 if (is_numeric($userid)) $sql .=
" AND ptt.fk_user=".$userid;
1844 $daylareadyfound = array();
1846 $num = $this->
db->num_rows(
$resql);
1851 $obj = $this->
db->fetch_object(
$resql);
1852 $day = $this->
db->jdate($obj->task_date);
1853 if (empty($daylareadyfound[$day]))
1855 $this->weekWorkLoad[$day] = $obj->task_duration;
1856 $this->weekWorkLoadPerTask[$day][$obj->fk_task] = $obj->task_duration;
1858 $this->weekWorkLoad[$day] += $obj->task_duration;
1859 $this->weekWorkLoadPerTask[$day][$obj->fk_task] += $obj->task_duration;
1861 $daylareadyfound[$day] = 1;
1867 $this->error =
"Error ".$this->db->lasterror();
1868 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
1886 $this->monthWorkLoad = array();
1887 $this->monthWorkLoadPerTask = array();
1889 if (empty($datestart))
dol_print_error(
'',
'Error datestart parameter is empty');
1891 $sql =
"SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task";
1892 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
1893 $sql .=
" WHERE ptt.fk_task = pt.rowid";
1894 $sql .=
" AND pt.fk_projet = ".$this->id;
1895 $sql .=
" AND (ptt.task_date >= '".$this->db->idate($datestart).
"' ";
1896 $sql .=
" AND ptt.task_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'm') - 1).
"')";
1897 if ($task_id) $sql .=
" AND ptt.fk_task=".$taskid;
1898 if (is_numeric($userid)) $sql .=
" AND ptt.fk_user=".$userid;
1904 $weekalreadyfound = array();
1906 $num = $this->
db->num_rows(
$resql);
1911 $obj = $this->
db->fetch_object(
$resql);
1912 if (!empty($obj->task_date)) {
1913 $date = explode(
'-', $obj->task_date);
1916 if (empty($weekalreadyfound[$week_number]))
1918 $this->monthWorkLoad[$week_number] = $obj->task_duration;
1919 $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] = $obj->task_duration;
1921 $this->monthWorkLoad[$week_number] += $obj->task_duration;
1922 $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] += $obj->task_duration;
1924 $weekalreadyfound[$week_number] = 1;
1930 $this->error =
"Error ".$this->db->lasterror();
1931 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
1947 global $conf, $langs;
1952 $projectsListId = null;
1955 $sql =
"SELECT p.rowid, p.fk_statut as status, p.fk_opp_status, p.datee as datee";
1956 $sql .=
" FROM (".MAIN_DB_PREFIX.
"projet as p";
1958 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
1961 $sql .=
" WHERE p.fk_statut = 1";
1962 $sql .=
" AND p.entity IN (".getEntity(
'project').
')';
1963 if (!empty($projectsListId)) $sql .=
" AND p.rowid IN (".$projectsListId.
")";
1973 $project_static =
new Project($this->
db);
1976 $response->warning_delay = $conf->projet->warning_delay / 60 / 60 / 24;
1977 $response->label = $langs->trans(
"OpenedProjects");
1978 $response->labelShort = $langs->trans(
"Opened");
1979 if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.
'/projet/list.php?search_status=1&mainmenu=project';
1980 else $response->url = DOL_URL_ROOT.
'/projet/list.php?search_project_user=-1&search_status=1&mainmenu=project';
1981 $response->img =
img_object(
'',
"projectpub");
1984 while ($obj = $this->
db->fetch_object(
$resql))
1986 $response->nbtodo++;
1988 $project_static->statut = $obj->status;
1989 $project_static->opp_status = $obj->opp_status;
1990 $project_static->datee = $this->
db->jdate($obj->datee);
1992 if ($project_static->hasDelay()) {
1993 $response->nbtodolate++;
1999 $this->error = $this->
db->error();
2034 $this->nb = array();
2036 $sql =
"SELECT count(p.rowid) as nb";
2037 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2039 $sql .=
" p.entity IN (".getEntity(
'project').
")";
2040 if (!$user->rights->projet->all->lire)
2043 $sql .=
"AND p.rowid IN (".$projectsListId.
")";
2049 while ($obj = $this->
db->fetch_object(
$resql))
2051 $this->nb[
"projects"] = $obj->nb;
2057 $this->error = $this->
db->error();
2072 if (!($this->
statut == self::STATUS_VALIDATED))
return false;
2073 if (!$this->datee && !$this->date_end)
return false;
2077 return ($this->datee ? $this->datee : $this->date_end) < ($now - $conf->projet->warning_delay);
2089 $sql =
'SELECT c.rowid, datec as datec, tms as datem,';
2090 $sql .=
' date_close as datecloture,';
2091 $sql .=
' fk_user_creat as fk_user_author, fk_user_close as fk_use_cloture';
2092 $sql .=
' FROM '.MAIN_DB_PREFIX.
'projet as c';
2093 $sql .=
' WHERE c.rowid = '.$id;
2094 $result = $this->
db->query($sql);
2097 if ($this->
db->num_rows($result))
2099 $obj = $this->
db->fetch_object($result);
2100 $this->
id = $obj->rowid;
2101 if ($obj->fk_user_author)
2103 $cuser =
new User($this->
db);
2104 $cuser->fetch($obj->fk_user_author);
2105 $this->user_creation = $cuser;
2108 if ($obj->fk_user_cloture)
2110 $cluser =
new User($this->
db);
2111 $cluser->fetch($obj->fk_user_cloture);
2112 $this->user_cloture = $cluser;
2115 $this->date_creation = $this->
db->jdate($obj->datec);
2116 $this->date_modification = $this->
db->jdate($obj->datem);
2117 $this->date_cloture = $this->
db->jdate($obj->datecloture);
2120 $this->
db->free($result);
2138 $type_categ = Categorie::TYPE_PROJECT;
2141 if (!is_array($categories)) {
2142 $categories = array($categories);
2146 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2148 $existing = $c->containing($this->
id, $type_categ,
'id');
2151 if (is_array($existing)) {
2152 $to_del = array_diff($existing, $categories);
2153 $to_add = array_diff($categories, $existing);
2156 $to_add = $categories;
2160 foreach ($to_del as $del) {
2161 if ($c->fetch($del) > 0) {
2162 $result = $c->del_type($this, $type_categ);
2164 $this->errors = $c->errors;
2165 $this->error = $c->error;
2170 foreach ($to_add as $add) {
2171 if ($c->fetch($add) > 0) {
2172 $result = $c->add_type($this, $type_categ);
2174 $this->errors = $c->errors;
2175 $this->error = $c->error;
2193 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
2194 $taskstatic =
new Task($this->
db);
2196 $this->lines = $taskstatic->getTasksArray(0, $user, $this->
id, 0, 0);
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname= '')
Make an include_once using default root and alternate root if it fails.
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
load_state_board()
Charge indicateurs this->nb pour le tableau de bord.
dol_substr($string, $start, $length, $stringencoding= '', $trunconbytes=0)
Make a substring.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm= 'auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
if(!empty($arrayfields['u.datec']['checked'])) print_liste_field_titre("DateCreationShort"u if(!empty($arrayfields['u.tms']['checked'])) print_liste_field_titre("DateModificationShort"u if(!empty($arrayfields['u.statut']['checked'])) print_liste_field_titre("Status"u statut
loadTimeSpentMonth($datestart, $taskid=0, $userid=0)
Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of projec...
</td > param sortfield sortorder printFieldListOption< tdclass="liste_titremaxwidthsearchright"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration center DesiredStock p desiredstock right StockLimitShort p seuil_stock_alerte right stock_physique right stock_real_warehouse right Ordered right StockToBuy right SupplierRef right param sortfield sortorder printFieldListTitle warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow StockTooLow help help help< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"> stock</td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
loadTimeSpent($datestart, $taskid=0, $userid=0)
Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of projec...
getNomUrl($withpicto=0, $option= '', $addlabel=0, $moreinpopup= '', $sep= '- ', $notooltip=0, $save_lastsearch_value=-1, $morecss= '')
Return clickable name (with picto eventually)
foreach($object->fields as $key=> $val) if(is_array($extrafields->attributes[$object->table_element]['label'])&&count($extrafields->attributes[$object->table_element]['label']) > 0) $object fields
initAsSpecimen()
Initialise an instance with random values.
dol_html_entity_decode($a, $b, $c= 'UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
dol_now($mode= 'auto')
Return date for now.
setCategories($categories)
Sets object to supplied categories.
delete_linked_contact($source= '', $code= '')
Delete all links between an object $this and all its contacts.
Class to manage Dolibarr users.
Class to manage Dolibarr database access.
deleteTasks($user)
Delete tasks with no children first, then task with children recursively.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
hasDelay()
Is the project delayed?
const STATUS_CLOSED
Closed status.
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
$conf db
API class for accounts.
const STATUS_VALIDATED
Open/Validated status.
restrictedProjectArea(User $user, $mode= 'read')
Check if user has permission on current project.
insertExtraFields($trigger= '', $userused=null)
Add/Update all extra fields values for the current object.
getElementCount($type, $tablename, $projectkey= 'fk_projet')
Return the count of a type of linked elements of this project.
__construct($db)
Constructor.
shiftTaskDate($old_project_dt_start)
Shift project task date from current date to delta.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
Class to manage categories.
get_element_list($type, $tablename, $datefieldname= '', $dates= '', $datee= '', $projectkey= 'fk_projet')
Return list of elements for type, linked to a project.
getLinesArray($user)
Create an array of tasks of current project.
Class to manage projects.
dol_strlen($string, $stringencoding= 'UTF-8')
Make a strlen call.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is '...
info($id)
Charge les informations d'ordre info dans l'objet commande.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Create an intervention document on disk using template defined into PROJECT_ADDON_PDF.
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
$user_author_id
Id of project creator. Not defined if shared project.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
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...
getWeekNumber($day, $month, $year)
Return week number.
liste_contact($status=-1, $source= 'external', $list=0, $code= '')
Get array of all contacts for an object.
print $_SERVER["PHP_SELF"]
Edit parameters.
remove_element($tableName, $elementSelectId, $projectfield= 'fk_projet')
Associate element to a project.
$public
Tell if this is a public or private project.
create($user, $notrigger=0)
Create a project into database.
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
call_trigger($triggerName, $user)
Call trigger based on this instance.
getProjectsAuthorizedForUser($user, $mode=0, $list=0, $socid=0, $filter= '')
Return array of projects a user has permission on, is affected to, or all projects.
createFromClone(User $user, $fromid, $clone_contact=false, $clone_task=true, $clone_project_file=false, $clone_task_file=false, $clone_note=true, $move_date=true, $notrigger=0, $newthirdpartyid=0)
Load an object from its id and create a new one in database.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
update($user, $notrigger=0)
Update a project.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
setValid($user, $notrigger=0)
Validate a project.
LibStatut($status, $mode=0)
Renvoi status label for a status.
update_element($tableName, $elementSelectId)
Associate element to a project.
dolGetStatus($statusLabel= '', $statusLabelShort= '', $html= '', $statusType= 'status0', $displayMode=0, $url= '', $params=array())
Output the badge of a status.
const STATUS_DRAFT
Draft status.
getLibStatut($mode=0)
Return status label of object.
dol_time_plus_duree($time, $duration_value, $duration_unit)
Add a delay to a date.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
setClose($user)
Close a project.
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
dol_mkdir($dir, $dataroot= '', $newmask=null)
Creation of a directory (this can create recursive subdir)
fetch($id, $ref= '', $ref_ext= '', $email_msgid= '')
Get object from database.