30 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
41 public $element =
'project';
46 public $table_element =
'projet';
51 public $table_element_line =
'projet_task';
56 public $table_element_date;
61 public $fk_element =
'fk_projet';
67 public $ismultientitymanaged = 1;
72 public $picto =
'project';
119 public $thirdparty_name;
126 public $fk_user_close;
131 public $user_close_id;
137 public $budget_amount;
142 public $usage_opportunity;
152 public $usage_bill_time;
157 public $usage_organize_event;
162 public $accept_conference_suggestions;
167 public $accept_booth_suggestions;
172 public $price_registration;
182 public $max_attendees;
184 public $statuts_short;
185 public $statuts_long;
190 public $fk_opp_status;
197 public $weekWorkLoad;
198 public $weekWorkLoadPerTask;
257 public $fields = array(
258 'rowid' =>array(
'type'=>
'integer',
'label'=>
'ID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
259 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>1,
'showoncombobox'=>1,
'position'=>15,
'searchall'=>1),
260 'title' =>array(
'type'=>
'varchar(255)',
'label'=>
'ProjectLabel',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'position'=>17,
'showoncombobox'=>2,
'searchall'=>1),
261 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>3,
'notnull'=>1,
'position'=>19),
262 'fk_soc' =>array(
'type'=>
'integer',
'label'=>
'Thirdparty',
'enabled'=>1,
'visible'=>0,
'position'=>20),
263 'dateo' =>array(
'type'=>
'date',
'label'=>
'DateStart',
'enabled'=>1,
'visible'=>1,
'position'=>30),
264 'datee' =>array(
'type'=>
'date',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>1,
'position'=>35),
265 'description' =>array(
'type'=>
'text',
'label'=>
'Description',
'enabled'=>1,
'visible'=>3,
'position'=>55,
'searchall'=>1),
266 'public' =>array(
'type'=>
'integer',
'label'=>
'Visibility',
'enabled'=>1,
'visible'=>1,
'position'=>65),
267 'fk_opp_status' =>array(
'type'=>
'integer',
'label'=>
'OpportunityStatusShort',
'enabled'=>
'!empty($conf->global->PROJECT_USE_OPPORTUNITIES)',
'visible'=>1,
'position'=>75),
268 'opp_percent' =>array(
'type'=>
'double(5,2)',
'label'=>
'OpportunityProbabilityShort',
'enabled'=>
'!empty($conf->global->PROJECT_USE_OPPORTUNITIES)',
'visible'=>1,
'position'=>80),
269 'note_private' =>array(
'type'=>
'text',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>85,
'searchall'=>1),
270 'note_public' =>array(
'type'=>
'text',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>90,
'searchall'=>1),
271 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'ModelPdf',
'enabled'=>1,
'visible'=>0,
'position'=>95),
272 'date_close' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>0,
'position'=>105),
273 'fk_user_close' =>array(
'type'=>
'integer',
'label'=>
'UserClosing',
'enabled'=>1,
'visible'=>0,
'position'=>110),
274 'opp_amount' =>array(
'type'=>
'double(24,8)',
'label'=>
'OpportunityAmountShort',
'enabled'=>1,
'visible'=>
'!empty($conf->global->PROJECT_USE_OPPORTUNITIES)',
'position'=>115),
275 'budget_amount' =>array(
'type'=>
'double(24,8)',
'label'=>
'Budget',
'enabled'=>1,
'visible'=>1,
'position'=>119),
276 'usage_bill_time' =>array(
'type'=>
'integer',
'label'=>
'UsageBillTimeShort',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
277 'usage_opportunity' =>array(
'type'=>
'integer',
'label'=>
'UsageOpportunity',
'enabled'=>1,
'visible'=>-1,
'position'=>135),
278 'usage_task' =>array(
'type'=>
'integer',
'label'=>
'UsageTasks',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
279 'usage_organize_event' =>array(
'type'=>
'integer',
'label'=>
'UsageOrganizeEvent',
'enabled'=>1,
'visible'=>-1,
'position'=>145),
280 'accept_conference_suggestions' =>array(
'type'=>
'integer',
'label'=>
'AllowUnknownPeopleSuggestConf',
'enabled'=>1,
'visible'=>-1,
'position'=>146),
281 'accept_booth_suggestions' =>array(
'type'=>
'integer',
'label'=>
'AllowUnknownPeopleSuggestBooth',
'enabled'=>1,
'visible'=>-1,
'position'=>147),
282 'price_registration' =>array(
'type'=>
'double(24,8)',
'label'=>
'PriceOfRegistration',
'enabled'=>1,
'visible'=>-1,
'position'=>148),
283 'price_booth' =>array(
'type'=>
'double(24,8)',
'label'=>
'PriceOfBooth',
'enabled'=>1,
'visible'=>-1,
'position'=>149),
284 'max_attendees' =>array(
'type'=>
'integer',
'label'=>
'MaxNbOfAttendees',
'enabled'=>1,
'visible'=>-1,
'position'=>150),
285 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreationShort',
'enabled'=>1,
'visible'=>-2,
'position'=>200),
286 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModificationShort',
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>205),
287 'fk_user_creat' =>array(
'type'=>
'integer',
'label'=>
'UserCreation',
'enabled'=>1,
'visible'=>0,
'notnull'=>1,
'position'=>210),
288 'fk_user_modif' =>array(
'type'=>
'integer',
'label'=>
'UserModification',
'enabled'=>1,
'visible'=>0,
'position'=>215),
289 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>0,
'position'=>220),
290 'email_msgid'=>array(
'type'=>
'varchar(255)',
'label'=>
'EmailMsgID',
'enabled'=>1,
'visible'=>-1,
'position'=>250,
'help'=>
'EmailMsgIDWhenSourceisEmail'),
291 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>1,
'notnull'=>1,
'position'=>500)
321 $this->statuts_short = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
322 $this->statuts_long = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
326 if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) {
327 $this->fields[
'rowid'][
'visible'] = 0;
330 if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
331 $this->fields[
'fk_opp_status'][
'enabled'] = 0;
332 $this->fields[
'opp_percent'][
'enabled'] = 0;
333 $this->fields[
'opp_amount'][
'enabled'] = 0;
334 $this->fields[
'usage_opportunity'][
'enabled'] = 0;
337 if (!empty($conf->global->PROJECT_HIDE_TASKS)) {
338 $this->fields[
'usage_bill_time'][
'visible'] = 0;
339 $this->fields[
'usage_task'][
'visible'] = 0;
342 if (empty($conf->eventorganization->enabled)) {
343 $this->fields[
'usage_organize_event'][
'visible'] = 0;
344 $this->fields[
'accept_conference_suggestions'][
'enabled'] = 0;
345 $this->fields[
'accept_booth_suggestions'][
'enabled'] = 0;
346 $this->fields[
'price_registration'][
'enabled'] = 0;
347 $this->fields[
'price_booth'][
'enabled'] = 0;
348 $this->fields[
'max_attendees'][
'enabled'] = 0;
359 public function create($user, $notrigger = 0)
361 global $conf, $langs;
369 $this->note_private =
dol_substr($this->note_private, 0, 65535);
370 $this->note_public =
dol_substr($this->note_public, 0, 65535);
373 if (!trim($this->
ref)) {
374 $this->error =
'ErrorFieldsRequired';
375 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
378 if (!empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) && !($this->socid > 0)) {
379 $this->error =
'ErrorFieldsRequired';
380 dol_syslog(get_class($this).
"::create error -1 thirdparty not defined and option PROJECT_THIRDPARTY_REQUIRED is set", LOG_ERR);
387 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet (";
390 $sql .=
", description";
392 $sql .=
", fk_user_creat";
393 $sql .=
", fk_statut";
394 $sql .=
", fk_opp_status";
395 $sql .=
", opp_percent";
400 $sql .=
", opp_amount";
401 $sql .=
", budget_amount";
402 $sql .=
", usage_opportunity";
403 $sql .=
", usage_task";
404 $sql .=
", usage_bill_time";
405 $sql .=
", usage_organize_event";
406 $sql .=
", accept_conference_suggestions";
407 $sql .=
", accept_booth_suggestions";
408 $sql .=
", price_registration";
409 $sql .=
", price_booth";
410 $sql .=
", max_attendees";
411 $sql .=
", email_msgid";
412 $sql .=
", note_private";
413 $sql .=
", note_public";
415 $sql .=
") VALUES (";
416 $sql .=
"'".$this->db->escape($this->
ref).
"'";
417 $sql .=
", '".$this->db->escape($this->title).
"'";
418 $sql .=
", '".$this->db->escape($this->
description).
"'";
419 $sql .=
", ".($this->socid > 0 ? $this->socid :
"null");
420 $sql .=
", ".((int) $user->id);
421 $sql .=
", ".(is_numeric($this->statut) ? ((int) $this->statut) :
'0');
422 $sql .=
", ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? ((
int) $this->opp_status) :
'NULL');
423 $sql .=
", ".(is_numeric($this->opp_percent) ? ((int) $this->opp_percent) :
'NULL');
424 $sql .=
", ".($this->public ? 1 : 0);
425 $sql .=
", '".$this->db->idate($now).
"'";
426 $sql .=
", ".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
427 $sql .=
", ".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
428 $sql .=
", ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
'null');
429 $sql .=
", ".(strcmp($this->budget_amount,
'') ?
price2num($this->budget_amount) :
'null');
430 $sql .=
", ".($this->usage_opportunity ? 1 : 0);
431 $sql .=
", ".($this->usage_task ? 1 : 0);
432 $sql .=
", ".($this->usage_bill_time ? 1 : 0);
433 $sql .=
", ".($this->usage_organize_event ? 1 : 0);
434 $sql .=
", ".($this->accept_conference_suggestions ? 1 : 0);
435 $sql .=
", ".($this->accept_booth_suggestions ? 1 : 0);
436 $sql .=
", ".(strcmp($this->price_registration,
'') ?
price2num($this->price_registration) :
'null');
437 $sql .=
", ".(strcmp($this->price_booth,
'') ?
price2num($this->price_booth) :
'null');
438 $sql .=
", ".(strcmp($this->max_attendees,
'') ? ((int) $this->max_attendees) :
'null');
439 $sql .=
", ".($this->email_msgid ?
"'".$this->db->escape($this->email_msgid).
"'" :
'null');
440 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
'null');
441 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
'null');
442 $sql .=
", ".((int) $conf->entity);
445 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
448 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"projet");
460 $this->error = $this->
db->lasterror();
461 $this->errno = $this->
db->lasterrno();
473 if (!$error && !empty($conf->global->MAIN_DISABLEDRAFTSTATUS)) {
484 $this->
db->rollback();
496 public function update($user, $notrigger = 0)
498 global $langs, $conf;
503 $this->title = trim($this->title);
505 if ($this->opp_amount < 0) {
506 $this->opp_amount =
'';
508 if ($this->opp_percent < 0) {
509 $this->opp_percent =
'';
511 if ($this->date_end && $this->date_end < $this->date_start) {
512 $this->error = $langs->trans(
"ErrorDateEndLowerThanDateStart");
513 $this->errors[] = $this->error;
514 $this->
db->rollback();
515 dol_syslog(get_class($this).
"::update error -3 ".$this->error, LOG_ERR);
519 $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
524 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet SET";
525 $sql .=
" ref='".$this->db->escape($this->
ref).
"'";
526 $sql .=
", title = '".$this->db->escape($this->title).
"'";
527 $sql .=
", description = '".$this->db->escape($this->
description).
"'";
528 $sql .=
", fk_soc = ".($this->socid > 0 ? $this->socid :
"null");
529 $sql .=
", fk_statut = ".((int) $this->statut);
530 $sql .=
", fk_opp_status = ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status :
'null');
531 $sql .=
", opp_percent = ".((is_numeric($this->opp_percent) && $this->opp_percent !=
'') ? $this->opp_percent :
'null');
532 $sql .=
", public = ".($this->public ? 1 : 0);
533 $sql .=
", datec=".($this->date_c !=
'' ?
"'".$this->db->idate($this->date_c).
"'" :
'null');
534 $sql .=
", dateo=".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
535 $sql .=
", datee=".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
536 $sql .=
", date_close=".($this->date_close !=
'' ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
537 $sql .=
", fk_user_close=".($this->fk_user_close > 0 ? $this->fk_user_close :
"null");
538 $sql .=
", opp_amount = ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
"null");
539 $sql .=
", budget_amount = ".(strcmp($this->budget_amount,
'') ?
price2num($this->budget_amount) :
"null");
540 $sql .=
", fk_user_modif = ".$user->id;
541 $sql .=
", usage_opportunity = ".($this->usage_opportunity ? 1 : 0);
542 $sql .=
", usage_task = ".($this->usage_task ? 1 : 0);
543 $sql .=
", usage_bill_time = ".($this->usage_bill_time ? 1 : 0);
544 $sql .=
", usage_organize_event = ".($this->usage_organize_event ? 1 : 0);
545 $sql .=
", accept_conference_suggestions = ".($this->accept_conference_suggestions ? 1 : 0);
546 $sql .=
", accept_booth_suggestions = ".($this->accept_booth_suggestions ? 1 : 0);
547 $sql .=
", price_registration = ".(strcmp($this->price_registration,
'') ?
price2num($this->price_registration) :
"null");
548 $sql .=
", price_booth = ".(strcmp($this->price_booth,
'') ?
price2num($this->price_booth) :
"null");
549 $sql .=
", max_attendees = ".(strcmp($this->max_attendees,
'') ?
price2num($this->max_attendees) :
"null");
550 $sql .=
", entity = ".((int) $this->entity);
551 $sql .=
" WHERE rowid = ".((int) $this->
id);
553 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
564 if (!$error && !$notrigger) {
573 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) {
575 if ($conf->project->dir_output) {
578 if (file_exists($olddir)) {
579 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
580 $res = @rename($olddir, $newdir);
582 $langs->load(
"errors");
583 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
593 $this->
db->rollback();
597 $this->error = $this->
db->lasterror();
598 $this->errors[] = $this->error;
599 $this->
db->rollback();
600 if ($this->
db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
605 dol_syslog(get_class($this).
"::update error ".$result.
" ".$this->error, LOG_ERR);
608 dol_syslog(get_class($this).
"::update ref null");
624 public function fetch($id, $ref =
'', $ref_ext =
'', $email_msgid =
'')
628 if (empty($id) && empty($ref) && empty($ref_ext) && empty($email_msgid)) {
629 dol_syslog(get_class($this).
"::fetch Bad parameters", LOG_WARNING);
633 $sql =
"SELECT rowid, entity, ref, title, description, public, datec, opp_amount, budget_amount,";
634 $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,";
635 $sql .=
" note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, email_msgid,";
636 $sql .=
" accept_conference_suggestions, accept_booth_suggestions, price_registration, price_booth, max_attendees";
637 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet";
639 $sql .=
" WHERE rowid = ".((int) $id);
641 $sql .=
" WHERE entity IN (".getEntity(
'project').
")";
643 $sql .=
" AND ref = '".$this->db->escape($ref).
"'";
644 } elseif (!empty($ref_ext)) {
645 $sql .=
" AND ref_ext = '".$this->db->escape($ref_ext).
"'";
647 $sql .=
" AND email_msgid = '".$this->db->escape($email_msgid).
"'";
651 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
654 $num_rows = $this->
db->num_rows(
$resql);
657 $obj = $this->
db->fetch_object(
$resql);
659 $this->
id = $obj->rowid;
660 $this->entity = $obj->entity;
661 $this->
ref = $obj->ref;
662 $this->title = $obj->title;
664 $this->date_c = $this->
db->jdate($obj->datec);
665 $this->datec = $this->
db->jdate($obj->datec);
666 $this->date_m = $this->
db->jdate($obj->tms);
667 $this->datem = $this->
db->jdate($obj->tms);
668 $this->date_start = $this->
db->jdate($obj->dateo);
669 $this->date_end = $this->
db->jdate($obj->datee);
670 $this->date_close = $this->
db->jdate($obj->date_close);
671 $this->note_private = $obj->note_private;
672 $this->note_public = $obj->note_public;
673 $this->socid = $obj->fk_soc;
674 $this->user_author_id = $obj->fk_user_creat;
675 $this->user_modification_id = $obj->fk_user_modif;
676 $this->user_close_id = $obj->fk_user_close;
677 $this->
public = $obj->public;
678 $this->statut = $obj->status;
679 $this->status = $obj->status;
680 $this->opp_status = $obj->fk_opp_status;
681 $this->opp_amount = $obj->opp_amount;
682 $this->opp_percent = $obj->opp_percent;
683 $this->budget_amount = $obj->budget_amount;
684 $this->model_pdf = $obj->model_pdf;
685 $this->modelpdf = $obj->model_pdf;
686 $this->usage_opportunity = (int) $obj->usage_opportunity;
687 $this->usage_task = (
int) $obj->usage_task;
688 $this->usage_bill_time = (int) $obj->usage_bill_time;
689 $this->usage_organize_event = (
int) $obj->usage_organize_event;
690 $this->accept_conference_suggestions = (int) $obj->accept_conference_suggestions;
691 $this->accept_booth_suggestions = (
int) $obj->accept_booth_suggestions;
692 $this->price_registration = $obj->price_registration;
693 $this->price_booth = $obj->price_booth;
694 $this->max_attendees = $obj->max_attendees;
695 $this->email_msgid = $obj->email_msgid;
710 $this->error = $this->
db->lasterror();
711 $this->errors[] = $this->
db->lasterror();
728 public function get_element_list($type, $tablename, $datefieldname =
'', $date_start =
'', $date_end =
'', $projectkey =
'fk_projet')
736 if ($this->
id <= 0) {
742 if ($type ==
'agenda') {
743 $sql =
"SELECT id as rowid FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project IN (".$this->
db->sanitize($ids).
") AND entity IN (".
getEntity(
'agenda').
")";
744 } elseif ($type ==
'expensereport') {
745 $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 (".$this->
db->sanitize($ids).
")";
746 } elseif ($type ==
'project_task') {
747 $sql =
"SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet IN (".$this->
db->sanitize($ids).
")";
748 } elseif ($type ==
'project_task_time') {
749 $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 (".$this->
db->sanitize($ids).
")";
750 } elseif ($type ==
'stock_mouvement') {
751 $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 (".$this->
db->sanitize($ids).
") AND ms.type_mouvement = 1";
752 } elseif ($type ==
'loan') {
753 $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 (".$this->
db->sanitize($ids).
")";
755 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" IN (".$this->
db->sanitize($ids).
") AND entity IN (".
getEntity($type).
")";
758 if ($date_start > 0 && $type ==
'loan') {
759 $sql .=
" AND (dateend > '".$this->db->idate($date_start).
"' OR dateend IS NULL)";
760 } elseif ($date_start > 0 && ($type !=
'project_task')) {
761 if (empty($datefieldname) && !empty($this->table_element_date)) {
762 $datefieldname = $this->table_element_date;
764 if (empty($datefieldname)) {
765 return 'Error this object has no date field defined';
767 $sql .=
" AND (".$datefieldname.
" >= '".$this->
db->idate($date_start).
"' OR ".$datefieldname.
" IS NULL)";
770 if ($date_end > 0 && $type ==
'loan') {
771 $sql .=
" AND (datestart < '".$this->db->idate($date_end).
"' OR datestart IS NULL)";
772 } elseif ($date_end > 0 && ($type !=
'project_task')) {
773 if (empty($datefieldname) && !empty($this->table_element_date)) {
774 $datefieldname = $this->table_element_date;
776 if (empty($datefieldname)) {
777 return 'Error this object has no date field defined';
779 $sql .=
" AND (".$datefieldname.
" <= '".$this->
db->idate($date_end).
"' OR ".$datefieldname.
" IS NULL)";
785 'tablename' => $tablename,
786 'datefieldname' => $datefieldname,
787 'dates' => $date_start,
788 'datee' => $date_end,
789 'fk_projet' => $projectkey,
792 $reshook = $hookmanager->executeHooks(
'getElementList', $parameters);
794 $sql = $hookmanager->resPrint;
796 $sql .= $hookmanager->resPrint;
804 dol_syslog(get_class($this).
"::get_element_list", LOG_DEBUG);
805 $result = $this->
db->query($sql);
807 $nump = $this->
db->num_rows($result);
811 $obj = $this->
db->fetch_object($result);
813 $elements[$i] = $obj->rowid.(empty($obj->fk_user) ?
'' :
'_'.$obj->fk_user);
817 $this->
db->free($result);
834 public function delete($user, $notrigger = 0)
836 global $langs, $conf;
837 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
847 $this->error =
'ErrorFailToDeleteLinkedContact';
849 $this->
db->rollback();
855 $listoftables = array(
856 'propal'=>
'fk_projet',
'commande'=>
'fk_projet',
'facture'=>
'fk_projet',
857 'supplier_proposal'=>
'fk_projet',
'commande_fournisseur'=>
'fk_projet',
'facture_fourn'=>
'fk_projet',
858 'expensereport_det'=>
'fk_projet',
'contrat'=>
'fk_projet',
859 'fichinter'=>
'fk_projet',
860 'don'=>array(
'field'=>
'fk_projet',
'module'=>
'don'),
861 'actioncomm'=>
'fk_project',
862 'mrp_mo'=>
'fk_project',
863 'entrepot'=>
'fk_project'
865 foreach ($listoftables as $key => $value) {
866 if (is_array($value)) {
870 $fieldname = $value[
'field'];
874 $sql =
"UPDATE ".MAIN_DB_PREFIX.$key.
" SET ".$fieldname.
" = NULL where ".$fieldname.
" = ".((int) $this->
id);
878 $this->errors[] = $this->
db->lasterror();
886 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_project";
887 $sql .=
" WHERE fk_project = ".((int) $this->
id);
889 $result = $this->
db->query($sql);
892 $this->errors[] = $this->
db->lasterror();
908 $elements = array(
'categorie_project');
909 foreach ($elements as $table) {
911 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$table;
912 $sql .=
" WHERE fk_project = ".((int) $this->
id);
914 $result = $this->
db->query($sql);
917 $this->errors[] = $this->
db->lasterror();
924 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_extrafields";
925 $sql .=
" WHERE fk_object = ".((int) $this->
id);
929 $this->errors[] = $this->
db->lasterror();
936 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet";
937 $sql .=
" WHERE rowid=".((int) $this->
id);
941 $this->errors[] = $langs->trans(
"CantRemoveProject", $langs->transnoentitiesnoconv(
"ProjectOverview"));
951 if ($conf->project->dir_output) {
952 $dir = $conf->project->dir_output.
"/".$projectref;
953 if (file_exists($dir)) {
956 $this->errors[] =
'ErrorFailToDeleteDir';
977 foreach ($this->errors as $errmsg) {
978 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
979 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
981 dol_syslog(get_class($this).
"::delete ".$this->error, LOG_ERR);
982 $this->
db->rollback();
997 if ($this->
id <= 0) {
1001 if ($type ==
'agenda') {
1002 $sql =
"SELECT COUNT(id) as nb FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project = ".((int) $this->
id).
" AND entity IN (".
getEntity(
'agenda').
")";
1003 } elseif ($type ==
'expensereport') {
1004 $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 = ".((int) $this->
id);
1005 } elseif ($type ==
'project_task') {
1006 $sql =
"SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet = ".((int) $this->
id);
1007 } elseif ($type ==
'project_task_time') {
1008 $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 = ".((int) $this->
id);
1009 } elseif ($type ==
'stock_mouvement') {
1010 $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 = ".((int) $this->
id).
" AND ms.type_mouvement = 1";
1011 } elseif ($type ==
'loan') {
1012 $sql =
"SELECT COUNT(l.rowid) as nb FROM ".MAIN_DB_PREFIX.
"loan as l WHERE l.entity IN (".
getEntity(
'loan').
") AND l.fk_projet = ".((int) $this->
id);
1014 $sql =
"SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" = ".((int) $this->
id).
" AND entity IN (".
getEntity($type).
")";
1017 $result = $this->
db->query($sql);
1023 $obj = $this->
db->fetch_object($result);
1025 $this->
db->free($result);
1038 $countTasks = count($this->lines);
1041 foreach ($this->lines as $task) {
1042 if ($task->hasChildren() <= 0) {
1044 $ret = $task->delete($user);
1046 $this->errors[] = $this->
db->lasterror();
1053 if ($deleted && count($this->lines) < $countTasks) {
1054 if (count($this->lines)) {
1071 global $langs, $conf;
1075 if ($this->statut != 1) {
1077 if (preg_match(
'/^'.preg_quote($langs->trans(
"CopyOf").
' ').
'/', $this->title)) {
1078 $this->error = $langs->trans(
"ErrorFieldFormat", $langs->transnoentities(
"Label")).
'. '.$langs->trans(
'RemoveString', $langs->transnoentitiesnoconv(
"CopyOf"));
1084 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
1085 $sql .=
" SET fk_statut = 1";
1086 $sql .=
" WHERE rowid = ".((int) $this->
id);
1087 $sql .=
" AND entity = ".((int) $conf->entity);
1089 dol_syslog(get_class($this).
"::setValid", LOG_DEBUG);
1093 if (empty($notrigger)) {
1094 $result = $this->
call_trigger(
'PROJECT_VALIDATE', $user);
1103 $this->
db->commit();
1106 $this->
db->rollback();
1107 $this->error = join(
',', $this->errors);
1108 dol_syslog(get_class($this).
"::setValid ".$this->error, LOG_ERR);
1112 $this->
db->rollback();
1113 $this->error = $this->
db->lasterror();
1127 global $langs, $conf;
1133 if ($this->statut != self::STATUS_CLOSED) {
1136 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
1137 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", fk_user_close = ".((int) $user->id).
", date_close = '".$this->
db->idate($now).
"'";
1138 $sql .=
" WHERE rowid = ".((int) $this->
id);
1139 $sql .=
" AND fk_statut = ".self::STATUS_VALIDATED;
1141 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
1145 dol_syslog(get_class($this).
"::setClose", LOG_DEBUG);
1157 $this->
db->commit();
1160 $this->
db->rollback();
1161 $this->error = join(
',', $this->errors);
1162 dol_syslog(get_class($this).
"::setClose ".$this->error, LOG_ERR);
1166 $this->
db->rollback();
1167 $this->error = $this->
db->lasterror();
1183 return $this->
LibStatut(isset($this->statut) ? $this->statut : $this->status, $mode);
1199 $statustrans = array(
1205 $statusClass =
'status0';
1206 if (!empty($statustrans[$status])) {
1207 $statusClass = $statustrans[$status];
1210 return dolGetStatus($langs->transnoentitiesnoconv($this->statuts_long[$status]), $langs->transnoentitiesnoconv($this->statuts_short[$status]),
'', $statusClass, $mode);
1226 public function getNomUrl($withpicto = 0, $option =
'', $addlabel = 0, $moreinpopup =
'', $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1, $morecss =
'')
1228 global $conf, $langs, $user, $hookmanager;
1230 if (!empty($conf->dol_no_mouse_hover)) {
1235 if (!empty($conf->global->PROJECT_OPEN_ALWAYS_ON_TAB)) {
1236 $option = $conf->global->PROJECT_OPEN_ALWAYS_ON_TAB;
1240 if ($option !=
'nolink') {
1241 $label =
img_picto(
'', $this->picto,
'class="pictofixedwidth"').
' <u class="paddingrightonly">'.$langs->trans(
"Project").
'</u>';
1243 if (isset($this->status)) {
1244 $label .=
' '.$this->getLibStatut(5);
1246 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'Ref').
': </b>'.$this->ref;
1247 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'Label').
': </b>'.$this->title;
1248 if (isset($this->
public)) {
1249 $label .=
'<br><b>'.$langs->trans(
"Visibility").
":</b> ";
1250 $label .= ($this->
public ?
img_picto($langs->trans(
'SharedProject'),
'world',
'class="paddingrightonly"').$langs->trans(
"SharedProject") :
img_picto($langs->trans(
'PrivateProject'),
'private',
'class="paddingrightonly"').$langs->trans(
"PrivateProject"));
1252 if (!empty($this->thirdparty_name)) {
1253 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'ThirdParty').
': </b>'.$this->thirdparty_name;
1255 if (!empty($this->date_start)) {
1256 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'DateStart').
': </b>'.
dol_print_date($this->date_start,
'day');
1258 if (!empty($this->date_end)) {
1259 $label .= ($label ?
'<br>' :
'').
'<b>'.$langs->trans(
'DateEnd').
': </b>'.
dol_print_date($this->date_end,
'day');
1262 $label .=
'<br>'.$moreinpopup;
1266 if ($option !=
'nolink') {
1267 if (preg_match(
'/\.php$/', $option)) {
1269 } elseif ($option ==
'task') {
1270 $url = DOL_URL_ROOT.
'/projet/tasks.php?id='.$this->id;
1271 } elseif ($option ==
'preview') {
1272 $url = DOL_URL_ROOT.
'/projet/element.php?id='.$this->id;
1273 } elseif ($option ==
'eventorganization') {
1274 $url = DOL_URL_ROOT.
'/eventorganization/conferenceorbooth_list.php?projectid='.$this->id;
1276 $url = DOL_URL_ROOT.
'/projet/card.php?id='.$this->id;
1279 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1280 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1281 $add_save_lastsearch_values = 1;
1283 if ($add_save_lastsearch_values) {
1284 $url .=
'&save_lastsearch_values=1';
1289 if (empty($notooltip) && $user->hasRight(
'projet',
'lire')) {
1290 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1291 $label = $langs->trans(
"ShowProject");
1292 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1294 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
1295 $linkclose .=
' class="classfortooltip'.($morecss ?
' '.$morecss :
'').
'"';
1297 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1300 $picto =
'projectpub';
1301 if (!$this->
public) {
1305 $linkstart =
'<a href="'.$url.
'"';
1306 $linkstart .= $linkclose.
'>';
1309 $result .= $linkstart;
1311 $result .=
img_object(($notooltip ?
'' : $label), $picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip pictofixedwidth em088"'), 0, 0, $notooltip ? 0 : 1);
1313 if ($withpicto != 2) {
1314 $result .= $this->ref;
1316 $result .= $linkend;
1317 if ($withpicto != 2) {
1318 $result .= (($addlabel && $this->title) ? $sep.dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)) :
'');
1322 $hookmanager->initHooks(array(
'projectdao'));
1323 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
1324 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1326 $result = $hookmanager->resPrint;
1328 $result .= $hookmanager->resPrint;
1343 global $user, $langs, $conf;
1349 $this->
ref =
'SPECIMEN';
1350 $this->entity = $conf->entity;
1351 $this->specimen = 1;
1353 $this->date_c = $now;
1354 $this->date_m = $now;
1355 $this->date_start = $now;
1356 $this->date_end = $now + (3600 * 24 * 365);
1357 $this->note_public =
'SPECIMEN';
1358 $this->fk_ele = 20000;
1359 $this->opp_amount = 20000;
1360 $this->budget_amount = 10000;
1362 $this->usage_opportunity = 1;
1363 $this->usage_task = 1;
1364 $this->usage_bill_time = 1;
1365 $this->usage_organize_event = 1;
1394 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))) {
1396 } elseif ($this->
public && (($mode ==
'read' && !empty($user->rights->projet->lire)) || ($mode ==
'write' && !empty($user->rights->projet->creer)) || ($mode ==
'delete' && !empty($user->rights->projet->supprimer)))) {
1399 foreach (array(
'internal',
'external') as $source) {
1401 $num = count($userRole);
1404 while ($nblinks < $num) {
1405 if ($source ==
'internal' && $user->id == $userRole[$nblinks][
'id']) {
1406 if ($mode ==
'read' && $user->rights->projet->lire) {
1409 if ($mode ==
'write' && $user->rights->projet->creer) {
1412 if ($mode ==
'delete' && $user->rights->projet->supprimer) {
1416 if ($source ==
'external' && $user->socid > 0 && $user->socid == $userRole[$nblinks][
'socid']) {
1417 if ($mode ==
'read' && $user->rights->projet->lire) {
1420 if ($mode ==
'write' && $user->rights->projet->creer) {
1423 if ($mode ==
'delete' && $user->rights->projet->supprimer) {
1439 return ($userAccess ? $userAccess : -1);
1454 $projects = array();
1457 $sql =
"SELECT ".(($mode == 0 || $mode == 1) ?
"DISTINCT " :
"").
"p.rowid, p.ref";
1458 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
1460 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"element_contact as ec ON ec.element_id = p.rowid";
1461 } elseif ($mode == 1) {
1462 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact as ec";
1463 } elseif ($mode == 2) {
1466 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
1470 $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).
")";
1474 $listofprojectcontacttype = array();
1475 $sql2 =
"SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1476 $sql2 .=
" WHERE ctc.element = '".$this->db->escape($this->element).
"'";
1477 $sql2 .=
" AND ctc.source = 'internal'";
1480 while ($obj = $this->
db->fetch_object(
$resql)) {
1481 $listofprojectcontacttype[$obj->rowid] = $obj->code;
1486 if (count($listofprojectcontacttype) == 0) {
1487 $listofprojectcontacttype[0] =
'0';
1491 $sql .=
" AND ( p.public = 1";
1492 $sql .=
" OR ( ec.fk_c_type_contact IN (".$this->db->sanitize(join(
',', array_keys($listofprojectcontacttype))).
")";
1493 $sql .=
" AND ec.fk_socpeople = ".((int) $user->id).
")";
1495 } elseif ($mode == 1) {
1496 $sql .=
" AND ec.element_id = p.rowid";
1498 $sql .=
" ( ec.fk_c_type_contact IN (".$this->db->sanitize(join(
',', array_keys($listofprojectcontacttype))).
")";
1499 $sql .=
" AND ec.fk_socpeople = ".((int) $user->id).
")";
1501 } elseif ($mode == 2) {
1510 $num = $this->
db->num_rows(
$resql);
1513 $row = $this->
db->fetch_row(
$resql);
1514 $projects[$row[0]] = $row[1];
1525 $result = implode(
',', $temp);
1550 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)
1552 global $langs, $conf;
1556 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);
1560 $clone_project =
new Project($this->
db);
1562 $clone_project->context[
'createfromclone'] =
'createfromclone';
1567 $clone_project->fetch($fromid);
1568 $clone_project->fetch_optionals();
1569 if ($newthirdpartyid > 0) {
1570 $clone_project->socid = $newthirdpartyid;
1572 $clone_project->fetch_thirdparty();
1574 $orign_dt_start = $clone_project->date_start;
1575 $orign_project_ref = $clone_project->ref;
1577 $clone_project->id = 0;
1579 $clone_project->date_start = $now;
1580 if (!(empty($clone_project->date_end))) {
1581 $clone_project->date_end = $clone_project->date_end + ($now - $orign_dt_start);
1585 $clone_project->date_c = $now;
1588 $clone_project->note_private =
'';
1589 $clone_project->note_public =
'';
1594 $obj = empty($conf->global->PROJECT_ADDON) ?
'mod_project_simple' : $conf->global->PROJECT_ADDON;
1596 $file =
''; $classname =
''; $filefound = 0;
1597 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1598 foreach ($dirmodels as $reldir) {
1599 $file =
dol_buildpath($reldir.
"core/modules/project/".$obj.
'.php', 0);
1600 if (file_exists($file)) {
1603 $modProject =
new $obj;
1604 $defaultref = $modProject->getNextValue(is_object($clone_project->thirdparty) ? $clone_project->thirdparty :
null, $clone_project);
1608 if (is_numeric($defaultref) && $defaultref <= 0) {
1612 $clone_project->ref = $defaultref;
1613 $clone_project->title = $langs->trans(
"CopyOf").
' '.$clone_project->title;
1616 $result = $clone_project->create($user, $notrigger);
1620 $this->error .= $clone_project->error;
1626 $clone_project_id = $clone_project->id;
1630 $clone_project->note_private =
'';
1631 $clone_project->note_public =
'';
1634 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
1636 $this->error .= $clone_project->error;
1638 $this->
db->rollback();
1640 $this->
db->commit();
1644 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
1646 $this->error .= $clone_project->error;
1648 $this->
db->rollback();
1650 $this->
db->commit();
1655 if ($clone_contact) {
1656 $origin_project =
new Project($this->
db);
1657 $origin_project->fetch($fromid);
1659 foreach (array(
'internal',
'external') as $source) {
1660 $tab = $origin_project->liste_contact(-1, $source);
1661 if (is_array($tab) && count($tab)>0) {
1662 foreach ($tab as $contacttoadd) {
1663 $clone_project->add_contact($contacttoadd[
'id'], $contacttoadd[
'code'], $contacttoadd[
'source'], $notrigger);
1664 if ($clone_project->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
1665 $langs->load(
"errors");
1666 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
1669 if ($clone_project->error !=
'') {
1670 $this->error .= $clone_project->error;
1675 } elseif ($tab < 0) {
1676 $this->error .= $origin_project->error;
1683 if ($clone_project_file) {
1684 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1689 if (
dol_mkdir($clone_project_dir) >= 0) {
1690 $filearray =
dol_dir_list($ori_project_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
1691 foreach ($filearray as $key => $file) {
1692 $rescopy =
dol_copy($ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name'], 0, 1);
1693 if (is_numeric($rescopy) && $rescopy < 0) {
1694 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name']);
1699 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
1706 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
1708 $taskstatic =
new Task($this->
db);
1712 if ($user->socid > 0) {
1713 $socid = $user->socid;
1716 $tasksarray = $taskstatic->getTasksArray(0, 0, $fromid, $socid, 0);
1718 $tab_conv_child_parent = array();
1721 foreach ($tasksarray as $tasktoclone) {
1722 $result_clone = $taskstatic->createFromClone($user, $tasktoclone->id, $clone_project_id, $tasktoclone->fk_parent, $move_date,
true,
false, $clone_task_file,
true,
false);
1723 if ($result_clone <= 0) {
1724 $this->error .= $taskstatic->error;
1727 $new_task_id = $result_clone;
1728 $taskstatic->fetch($tasktoclone->id);
1732 if (($taskstatic->hasChildren()) && !array_key_exists($tasktoclone->id, $tab_conv_child_parent)) {
1733 $tab_conv_child_parent[$tasktoclone->id] = $new_task_id;
1739 $tasksarray = $taskstatic->getTasksArray(0, 0, $clone_project_id, $socid, 0);
1740 foreach ($tasksarray as $task_cloned) {
1741 $taskstatic->fetch($task_cloned->id);
1742 if ($taskstatic->fk_task_parent != 0) {
1743 $taskstatic->fk_task_parent = $tab_conv_child_parent[$taskstatic->fk_task_parent];
1745 $res = $taskstatic->update($user, $notrigger);
1746 if ($result_clone <= 0) {
1747 $this->error .= $taskstatic->error;
1754 unset($clone_project->context[
'createfromclone']);
1757 $this->
db->commit();
1758 return $clone_project_id;
1760 $this->
db->rollback();
1761 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
1775 global $user, $langs, $conf;
1780 $taskstatic =
new Task($this->
db);
1784 if ($user->socid > 0) {
1785 $socid = $user->socid;
1788 $tasksarray = $taskstatic->getTasksArray(0, 0, $this->
id, $socid, 0);
1790 foreach ($tasksarray as $tasktoshiftdate) {
1793 if ((!empty($tasktoshiftdate->date_start)) || (!empty($tasktoshiftdate->date_end))) {
1796 $task =
new Task($this->
db);
1797 $result = $task->fetch($tasktoshiftdate->id);
1800 $this->error .= $task->error;
1806 if (!empty($tasktoshiftdate->date_start)) {
1807 $task->date_start = $this->date_start + ($tasktoshiftdate->date_start - $old_project_dt_start);
1811 if (!empty($tasktoshiftdate->date_end)) {
1812 $task->date_end = $this->date_start + ($tasktoshiftdate->date_end - $old_project_dt_start);
1816 $result = $task->update($user);
1819 $this->error .= $task->error;
1841 $sql =
"UPDATE ".MAIN_DB_PREFIX.$tableName;
1843 if ($tableName ==
"actioncomm") {
1844 $sql .=
" SET fk_project=".$this->id;
1845 $sql .=
" WHERE id=".((int) $elementSelectId);
1846 } elseif ($tableName ==
"entrepot") {
1847 $sql .=
" SET fk_project=".$this->id;
1848 $sql .=
" WHERE rowid=".((int) $elementSelectId);
1850 $sql .=
" SET fk_projet=".$this->id;
1851 $sql .=
" WHERE rowid=".((int) $elementSelectId);
1854 dol_syslog(get_class($this).
"::update_element", LOG_DEBUG);
1857 $this->error = $this->
db->lasterror();
1874 public function remove_element($tableName, $elementSelectId, $projectfield =
'fk_projet')
1877 $sql =
"UPDATE ".MAIN_DB_PREFIX.$tableName;
1879 if ($tableName ==
"actioncomm") {
1880 $sql .=
" SET fk_project=NULL";
1881 $sql .=
" WHERE id=".((int) $elementSelectId);
1883 $sql .=
" SET ".$projectfield.
"=NULL";
1884 $sql .=
" WHERE rowid=".((int) $elementSelectId);
1887 dol_syslog(get_class($this).
"::remove_element", LOG_DEBUG);
1890 $this->error = $this->
db->lasterror();
1907 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
1909 global $conf, $langs;
1911 $langs->load(
"projects");
1914 $modele =
'baleine';
1916 if ($this->model_pdf) {
1917 $modele = $this->model_pdf;
1918 } elseif (!empty($conf->global->PROJECT_ADDON_PDF)) {
1919 $modele = $conf->global->PROJECT_ADDON_PDF;
1923 $modelpath =
"core/modules/project/doc/";
1925 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
1942 $this->weekWorkLoad = array();
1943 $this->weekWorkLoadPerTask = array();
1945 if (empty($datestart)) {
1949 $sql =
"SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task";
1950 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
1951 $sql .=
" WHERE ptt.fk_task = pt.rowid";
1952 $sql .=
" AND pt.fk_projet = ".((int) $this->
id);
1953 $sql .=
" AND (ptt.task_date >= '".$this->db->idate($datestart).
"' ";
1954 $sql .=
" AND ptt.task_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'w') - 1).
"')";
1956 $sql .=
" AND ptt.fk_task=".((int) $taskid);
1958 if (is_numeric($userid)) {
1959 $sql .=
" AND ptt.fk_user=".((int) $userid);
1965 $daylareadyfound = array();
1967 $num = $this->
db->num_rows(
$resql);
1971 $obj = $this->
db->fetch_object(
$resql);
1972 $day = $this->
db->jdate($obj->task_date);
1973 if (empty($daylareadyfound[$day])) {
1974 $this->weekWorkLoad[$day] = $obj->task_duration;
1975 $this->weekWorkLoadPerTask[$day][$obj->fk_task] = $obj->task_duration;
1977 $this->weekWorkLoad[$day] += $obj->task_duration;
1978 $this->weekWorkLoadPerTask[$day][$obj->fk_task] += $obj->task_duration;
1980 $daylareadyfound[$day] = 1;
1986 $this->error =
"Error ".$this->db->lasterror();
1987 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
2005 $this->monthWorkLoad = array();
2006 $this->monthWorkLoadPerTask = array();
2008 if (empty($datestart)) {
2012 $sql =
"SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task";
2013 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet_task_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
2014 $sql .=
" WHERE ptt.fk_task = pt.rowid";
2015 $sql .=
" AND pt.fk_projet = ".((int) $this->
id);
2016 $sql .=
" AND (ptt.task_date >= '".$this->db->idate($datestart).
"' ";
2017 $sql .=
" AND ptt.task_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'm') - 1).
"')";
2019 $sql .=
" AND ptt.fk_task=".((int) $taskid);
2021 if (is_numeric($userid)) {
2022 $sql .=
" AND ptt.fk_user=".((int) $userid);
2028 $weekalreadyfound = array();
2030 $num = $this->
db->num_rows(
$resql);
2034 $obj = $this->
db->fetch_object(
$resql);
2035 if (!empty($obj->task_date)) {
2036 $date = explode(
'-', $obj->task_date);
2039 if (empty($weekalreadyfound[$week_number])) {
2040 $this->monthWorkLoad[$week_number] = $obj->task_duration;
2041 $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] = $obj->task_duration;
2043 $this->monthWorkLoad[$week_number] += $obj->task_duration;
2044 $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] += $obj->task_duration;
2046 $weekalreadyfound[$week_number] = 1;
2052 $this->error =
"Error ".$this->db->lasterror();
2053 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
2069 global $conf, $langs;
2074 $projectsListId =
null;
2075 if (empty($user->rights->projet->all->lire)) {
2079 $sql =
"SELECT p.rowid, p.fk_statut as status, p.fk_opp_status, p.datee as datee";
2080 $sql .=
" FROM (".MAIN_DB_PREFIX.
"projet as p";
2082 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
2085 $sql .=
" WHERE p.fk_statut = 1";
2086 $sql .=
" AND p.entity IN (".getEntity(
'project').
')';
2087 if (!empty($projectsListId)) {
2088 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2098 $project_static =
new Project($this->
db);
2101 $response->warning_delay = $conf->project->warning_delay / 60 / 60 / 24;
2102 $response->label = $langs->trans(
"OpenedProjects");
2103 $response->labelShort = $langs->trans(
"Opened");
2104 if ($user->rights->projet->all->lire) {
2105 $response->url = DOL_URL_ROOT.
'/projet/list.php?search_status=1&mainmenu=project';
2107 $response->url = DOL_URL_ROOT.
'/projet/list.php?search_project_user=-1&search_status=1&mainmenu=project';
2109 $response->img =
img_object(
'',
"projectpub");
2112 while ($obj = $this->
db->fetch_object(
$resql)) {
2113 $response->nbtodo++;
2115 $project_static->statut = $obj->status;
2116 $project_static->opp_status = $obj->fk_opp_status;
2117 $project_static->date_end = $this->
db->jdate($obj->datee);
2119 if ($project_static->hasDelay()) {
2120 $response->nbtodolate++;
2126 $this->error = $this->
db->error();
2161 $this->nb = array();
2163 $sql =
"SELECT count(p.rowid) as nb";
2164 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2166 $sql .=
" p.entity IN (".getEntity(
'project').
")";
2167 if (empty($user->rights->projet->all->lire)) {
2169 $sql .=
"AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2174 while ($obj = $this->
db->fetch_object(
$resql)) {
2175 $this->nb[
"projects"] = $obj->nb;
2181 $this->error = $this->
db->error();
2196 if (!($this->statut == self::STATUS_VALIDATED)) {
2199 if (!$this->date_end) {
2205 return ($this->date_end) < ($now - $conf->project->warning_delay);
2217 $sql =
'SELECT c.rowid, datec as datec, tms as datem,';
2218 $sql .=
' date_close as datecloture,';
2219 $sql .=
' fk_user_creat as fk_user_author, fk_user_close as fk_use_cloture';
2220 $sql .=
' FROM '.MAIN_DB_PREFIX.
'projet as c';
2221 $sql .=
' WHERE c.rowid = '.((int) $id);
2222 $result = $this->
db->query($sql);
2224 if ($this->
db->num_rows($result)) {
2225 $obj = $this->
db->fetch_object($result);
2226 $this->
id = $obj->rowid;
2227 if ($obj->fk_user_author) {
2228 $cuser =
new User($this->
db);
2229 $cuser->fetch($obj->fk_user_author);
2230 $this->user_creation = $cuser;
2233 if ($obj->fk_user_cloture) {
2234 $cluser =
new User($this->
db);
2235 $cluser->fetch($obj->fk_user_cloture);
2236 $this->user_cloture = $cluser;
2239 $this->date_creation = $this->
db->jdate($obj->datec);
2240 $this->date_modification = $this->
db->jdate($obj->datem);
2241 $this->date_cloture = $this->
db->jdate($obj->datecloture);
2244 $this->
db->free($result);
2262 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2263 return parent::setCategoriesCommon($categories, Categorie::TYPE_PROJECT);
2276 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
2277 $taskstatic =
new Task($this->
db);
2279 $this->lines = $taskstatic->getTasksArray(0, $user, $this->
id, 0, 0,
'',
'-1',
'', 0, 0, array(), 0, array(), 0, $loadRoleMode);