34require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
44 public $element =
'project';
49 public $table_element =
'projet';
54 public $table_element_line =
'projet_task';
59 public $table_element_date;
64 public $fk_element =
'fk_projet';
69 public $picto =
'project';
116 public $date_start_event;
121 public $date_end_event;
141 public $thirdparty_name;
146 public $user_author_id;
151 public $fk_user_close;
161 public $budget_amount;
166 public $usage_opportunity;
176 public $usage_bill_time;
181 public $usage_organize_event;
186 public $accept_conference_suggestions;
191 public $accept_booth_suggestions;
196 public $price_registration;
206 public $max_attendees;
222 public $opp_status_code;
227 public $fk_opp_status;
242 public $opp_weighted_amount;
252 public $weekWorkLoad;
256 public $weekWorkLoadPerTask;
261 public $monthWorkLoad;
266 public $monthWorkLoadPerTask;
344 public $fields = array(
345 'rowid' => array(
'type' =>
'integer',
'label' =>
'ID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
346 'fk_project' => array(
'type' =>
'integer',
'label' =>
'Parent',
'enabled' => 1,
'visible' => -1,
'notnull' => 0,
'position' => 12),
347 'ref' => array(
'type' =>
'varchar(50)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => 1,
'showoncombobox' => 1,
'position' => 15,
'searchall' => 1),
348 'title' => array(
'type' =>
'varchar(255)',
'label' =>
'ProjectLabel',
'enabled' => 1,
'visible' => 1,
'notnull' => 1,
'position' => 17,
'showoncombobox' => 2,
'searchall' => 1,
'csslist' =>
'tdoverflowmax250'),
349 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => 3,
'notnull' => 1,
'position' => 19),
350 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' => 1,
'visible' => 0,
'position' => 20),
351 'dateo' => array(
'type' =>
'date',
'label' =>
'DateStart',
'enabled' => 1,
'visible' => -1,
'position' => 30),
352 'datee' => array(
'type' =>
'date',
'label' =>
'DateEnd',
'enabled' => 1,
'visible' => 1,
'position' => 35),
353 'description' => array(
'type' =>
'text',
'label' =>
'Description',
'enabled' => 1,
'visible' => 3,
'position' => 55,
'searchall' => 1),
354 'public' => array(
'type' =>
'integer',
'label' =>
'Visibility',
'enabled' => 1,
'visible' => -1,
'position' => 65),
355 'fk_opp_status' => array(
'type' =>
'integer:CLeadStatus:core/class/cleadstatus.class.php',
'label' =>
'OpportunityStatusShort',
'enabled' =>
'getDolGlobalString("PROJECT_USE_OPPORTUNITIES")',
'visible' => 1,
'position' => 75),
356 'opp_percent' => array(
'type' =>
'double(5,2)',
'label' =>
'OpportunityProbabilityShort',
'enabled' =>
'getDolGlobalString("PROJECT_USE_OPPORTUNITIES")',
'visible' => 1,
'position' => 80),
357 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 85,
'searchall' => 1),
358 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 90,
'searchall' => 1),
359 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'ModelPdf',
'enabled' => 1,
'visible' => 0,
'position' => 95),
360 'date_close' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => 0,
'position' => 105),
361 'fk_user_close' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserClosing',
'enabled' => 1,
'visible' => 0,
'position' => 110),
362 'opp_amount' => array(
'type' =>
'double(24,8)',
'label' =>
'OpportunityAmountShort',
'enabled' => 1,
'visible' =>
'getDolGlobalString("PROJECT_USE_OPPORTUNITIES")',
'position' => 115),
363 'budget_amount' => array(
'type' =>
'double(24,8)',
'label' =>
'Budget',
'enabled' => 1,
'visible' => -1,
'position' => 119),
364 'usage_opportunity' => array(
'type' =>
'integer',
'label' =>
'UsageOpportunity',
'enabled' => 1,
'visible' => -1,
'position' => 130),
365 'usage_task' => array(
'type' =>
'integer',
'label' =>
'UsageTasks',
'enabled' => 1,
'visible' => -1,
'position' => 135),
366 'usage_bill_time' => array(
'type' =>
'integer',
'label' =>
'UsageBillTimeShort',
'enabled' => 1,
'visible' => -1,
'position' => 140),
367 'usage_organize_event' => array(
'type' =>
'integer',
'label' =>
'UsageOrganizeEvent',
'enabled' => 1,
'visible' => -1,
'position' => 145),
369 'date_start_event' => array(
'type' =>
'date',
'label' =>
'DateStartEvent',
'enabled' =>
"isModEnabled('eventorganization')",
'visible' => 1,
'position' => 200),
370 'date_end_event' => array(
'type' =>
'date',
'label' =>
'DateEndEvent',
'enabled' =>
"isModEnabled('eventorganization')",
'visible' => 1,
'position' => 201),
371 'location' => array(
'type' =>
'text',
'label' =>
'Location',
'enabled' => 1,
'visible' => 3,
'position' => 202,
'searchall' => 1),
372 'accept_conference_suggestions' => array(
'type' =>
'integer',
'label' =>
'AllowUnknownPeopleSuggestConf',
'enabled' => 1,
'visible' => -1,
'position' => 210),
373 'accept_booth_suggestions' => array(
'type' =>
'integer',
'label' =>
'AllowUnknownPeopleSuggestBooth',
'enabled' => 1,
'visible' => -1,
'position' => 211),
374 'price_registration' => array(
'type' =>
'double(24,8)',
'label' =>
'PriceOfRegistration',
'enabled' => 1,
'visible' => -1,
'position' => 212),
375 'price_booth' => array(
'type' =>
'double(24,8)',
'label' =>
'PriceOfBooth',
'enabled' => 1,
'visible' => -1,
'position' => 215),
376 'max_attendees' => array(
'type' =>
'integer',
'label' =>
'MaxNbOfAttendees',
'enabled' => 1,
'visible' => -1,
'position' => 215),
378 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreationShort',
'enabled' => 1,
'visible' => -2,
'position' => 400),
379 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModificationShort',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 405),
380 'fk_user_creat' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserCreation',
'enabled' => 1,
'visible' => 0,
'notnull' => 1,
'position' => 410),
381 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModification',
'enabled' => 1,
'visible' => 0,
'position' => 415),
382 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -1,
'position' => 420),
383 'email_msgid' => array(
'type' =>
'varchar(255)',
'label' =>
'EmailMsgID',
'enabled' => 1,
'visible' => -1,
'position' => 450,
'help' =>
'EmailMsgIDWhenSourceisEmail',
'csslist' =>
'tdoverflowmax125'),
384 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'alias' =>
'status',
'enabled' => 1,
'visible' => 1,
'notnull' => 1,
'position' => 500,
'arrayofkeyval' => array(0 =>
'Draft', 1 =>
'Validated', 2 =>
'Closed')),
415 $this->ismultientitymanaged = 1;
416 $this->isextrafieldmanaged = 1;
418 $this->labelStatusShort = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
419 $this->labelStatus = array(0 =>
'Draft', 1 =>
'Opened', 2 =>
'Closed');
424 $this->fields[
'rowid'][
'visible'] = 0;
428 $this->fields[
'fk_opp_status'][
'enabled'] = 0;
429 $this->fields[
'opp_percent'][
'enabled'] = 0;
430 $this->fields[
'opp_amount'][
'enabled'] = 0;
431 $this->fields[
'usage_opportunity'][
'enabled'] = 0;
435 $this->fields[
'usage_bill_time'][
'visible'] = 0;
436 $this->fields[
'usage_task'][
'visible'] = 0;
439 if (empty($conf->eventorganization->enabled)) {
440 $this->fields[
'usage_organize_event'][
'visible'] = 0;
441 $this->fields[
'accept_conference_suggestions'][
'enabled'] = 0;
442 $this->fields[
'accept_booth_suggestions'][
'enabled'] = 0;
443 $this->fields[
'price_registration'][
'enabled'] = 0;
444 $this->fields[
'price_booth'][
'enabled'] = 0;
445 $this->fields[
'max_attendees'][
'enabled'] = 0;
456 public function create($user, $notrigger = 0)
464 $this->note_private =
dol_substr($this->note_private, 0, 65535);
465 $this->note_public =
dol_substr($this->note_public, 0, 65535);
468 if (!trim($this->
ref)) {
469 $this->error =
'ErrorFieldsRequired';
470 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
474 $this->error =
'ErrorFieldsRequired';
475 dol_syslog(get_class($this).
"::create error -1 thirdparty not defined and option PROJECT_THIRDPARTY_REQUIRED is set", LOG_ERR);
482 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"projet (";
484 $sql .=
", fk_project";
486 $sql .=
", description";
488 $sql .=
", fk_user_creat";
489 $sql .=
", fk_statut";
490 $sql .=
", fk_opp_status";
491 $sql .=
", opp_percent";
496 $sql .=
", opp_amount";
497 $sql .=
", budget_amount";
498 $sql .=
", usage_opportunity";
499 $sql .=
", usage_task";
500 $sql .=
", usage_bill_time";
501 $sql .=
", usage_organize_event";
502 $sql .=
", accept_conference_suggestions";
503 $sql .=
", accept_booth_suggestions";
504 $sql .=
", price_registration";
505 $sql .=
", price_booth";
506 $sql .=
", max_attendees";
507 $sql .=
", date_start_event";
508 $sql .=
", date_end_event";
509 $sql .=
", location";
510 $sql .=
", email_msgid";
511 $sql .=
", note_private";
512 $sql .=
", note_public";
515 $sql .=
") VALUES (";
516 $sql .=
"'".$this->db->escape($this->
ref).
"'";
517 $sql .=
", ".($this->fk_project ? ((int) $this->fk_project) :
"null");
518 $sql .=
", '".$this->db->escape($this->title).
"'";
519 $sql .=
", '".$this->db->escape($this->
description).
"'";
520 $sql .=
", ".($this->socid > 0 ? $this->socid :
"null");
521 $sql .=
", ".((int) $user->id);
522 $sql .=
", ".(is_numeric($this->
status) ? ((int) $this->
status) :
'0');
523 $sql .=
", ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? ((
int) $this->opp_status) :
'NULL');
524 $sql .=
", ".(is_numeric($this->opp_percent) ? ((int) $this->opp_percent) :
'NULL');
525 $sql .=
", ".($this->public ? 1 : 0);
526 $sql .=
", '".$this->db->idate($now).
"'";
527 $sql .=
", ".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
528 $sql .=
", ".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
529 $sql .=
", ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
'null');
530 $sql .=
", ".(strcmp((
string) $this->budget_amount,
'') ?
price2num($this->budget_amount) :
'null');
531 $sql .=
", ".($this->usage_opportunity ? 1 : 0);
532 $sql .=
", ".($this->usage_task ? 1 : 0);
533 $sql .=
", ".($this->usage_bill_time ? 1 : 0);
534 $sql .=
", ".($this->usage_organize_event ? 1 : 0);
535 $sql .=
", ".($this->accept_conference_suggestions ? 1 : 0);
536 $sql .=
", ".($this->accept_booth_suggestions ? 1 : 0);
537 $sql .=
", ".(strcmp((
string) $this->price_registration,
'') ?
price2num($this->price_registration) :
'null');
538 $sql .=
", ".(strcmp((
string) $this->price_booth,
'') ?
price2num($this->price_booth) :
'null');
539 $sql .=
", ".(strcmp((
string) $this->max_attendees,
'') ? ((
int) $this->max_attendees) :
'null');
540 $sql .=
", ".($this->date_start_event !=
'' ?
"'".$this->db->idate($this->date_start_event).
"'" :
'null');
541 $sql .=
", ".($this->date_end_event !=
'' ?
"'".$this->db->idate($this->date_end_event).
"'" :
'null');
542 $sql .=
", ".($this->location ?
"'".$this->db->escape($this->location).
"'" :
'null');
543 $sql .=
", ".($this->email_msgid ?
"'".$this->db->escape($this->email_msgid).
"'" :
'null');
544 $sql .=
", ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
'null');
545 $sql .=
", ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
'null');
546 $sql .=
", ".setEntity($this);
547 $sql .=
", ".(!isset($this->ip) ?
'NULL' :
"'".$this->db->escape($this->ip).
"'");
550 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
551 $resql = $this->db->query($sql);
553 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"projet");
558 $result = $this->call_trigger(
'PROJECT_CREATE', $user);
565 $this->error = $this->db->lasterror();
588 $this->db->rollback();
600 public function update($user, $notrigger = 0)
602 global $langs, $conf;
607 $this->title = trim($this->title);
609 if ($this->opp_amount < 0) {
610 $this->opp_amount =
'';
612 if ($this->opp_percent < 0) {
613 $this->opp_percent =
'';
615 if ($this->date_end && $this->date_end < $this->date_start) {
616 $langs->load(
"errors");
617 $this->error = $langs->trans(
"ErrorStartDateGreaterEnd");
618 $this->errors[] = $this->error;
619 $this->db->rollback();
620 dol_syslog(get_class($this).
"::update error -3 ".$this->error, LOG_ERR);
624 $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
629 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet SET";
630 $sql .=
" ref='".$this->db->escape($this->
ref).
"'";
631 $sql .=
", fk_project=".($this->fk_project ? ((int) $this->fk_project) :
"null");
632 $sql .=
", title = '".$this->db->escape($this->title).
"'";
633 $sql .=
", description = '".$this->db->escape($this->
description).
"'";
634 $sql .=
", fk_soc = ".($this->socid > 0 ? $this->socid :
"null");
635 $sql .=
", fk_statut = ".((int) $this->
status);
636 $sql .=
", fk_opp_status = ".((is_numeric($this->opp_status) && $this->opp_status > 0) ? $this->opp_status :
'null');
637 $sql .=
", opp_percent = ".((is_numeric($this->opp_percent) && $this->opp_percent !=
'') ? $this->opp_percent :
'null');
638 $sql .=
", public = ".($this->public ? 1 : 0);
639 $sql .=
", datec = ".($this->date_c !=
'' ?
"'".$this->db->idate($this->date_c).
"'" :
'null');
640 $sql .=
", dateo = ".($this->date_start !=
'' ?
"'".$this->db->idate($this->date_start).
"'" :
'null');
641 $sql .=
", datee = ".($this->date_end !=
'' ?
"'".$this->db->idate($this->date_end).
"'" :
'null');
642 $sql .=
", date_close = ".($this->date_close !=
'' ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
643 $sql .=
", note_public = ".($this->note_public ?
"'".$this->db->escape($this->note_public).
"'" :
"null");
644 $sql .=
", note_private = ".($this->note_private ?
"'".$this->db->escape($this->note_private).
"'" :
"null");
645 $sql .=
", fk_user_close = ".($this->fk_user_close > 0 ? $this->fk_user_close :
"null");
646 $sql .=
", opp_amount = ".(strcmp($this->opp_amount,
'') ?
price2num($this->opp_amount) :
"null");
647 $sql .=
", budget_amount = ".(strcmp($this->budget_amount,
'') ?
price2num($this->budget_amount) :
"null");
648 $sql .=
", fk_user_modif = ".((int) $user->id);
649 $sql .=
", usage_opportunity = ".($this->usage_opportunity ? 1 : 0);
650 $sql .=
", usage_task = ".($this->usage_task ? 1 : 0);
651 $sql .=
", usage_bill_time = ".($this->usage_bill_time ? 1 : 0);
652 $sql .=
", usage_organize_event = ".($this->usage_organize_event ? 1 : 0);
653 $sql .=
", accept_conference_suggestions = ".($this->accept_conference_suggestions ? 1 : 0);
654 $sql .=
", accept_booth_suggestions = ".($this->accept_booth_suggestions ? 1 : 0);
655 $sql .=
", price_registration = ".(isset($this->price_registration) && strcmp($this->price_registration,
'') ?
price2num($this->price_registration) :
"null");
656 $sql .=
", price_booth = ".(isset($this->price_booth) && strcmp((
string) $this->price_booth,
'') ?
price2num($this->price_booth) :
"null");
657 $sql .=
", max_attendees = ".(strcmp((
string) $this->max_attendees,
'') ? (
int) $this->max_attendees :
"null");
658 $sql .=
", date_start_event = ".($this->date_start_event !=
'' ?
"'".$this->db->idate($this->date_start_event).
"'" :
'null');
659 $sql .=
", date_end_event = ".($this->date_end_event !=
'' ?
"'".$this->db->idate($this->date_end_event).
"'" :
'null');
660 $sql .=
", location = '".$this->db->escape($this->location).
"'";
661 $sql .=
", entity = ".((int) $this->entity);
662 $sql .=
" WHERE rowid = ".((int) $this->
id);
664 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
665 $resql = $this->db->query($sql);
675 if (!$error && !$notrigger) {
677 $result = $this->call_trigger(
'PROJECT_MODIFY', $user);
684 if (!$error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref)) {
686 if ($conf->project->dir_output) {
689 if (file_exists($olddir)) {
690 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
691 $res = @rename($olddir, $newdir);
693 $langs->load(
"errors");
694 $this->error = $langs->trans(
'ErrorFailToRenameDir', $olddir, $newdir);
704 $this->db->rollback();
708 $this->error = $this->db->lasterror();
709 $this->errors[] = $this->error;
710 $this->db->rollback();
711 if ($this->db->lasterrno() ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
716 dol_syslog(get_class($this).
"::update error ".$result.
" ".$this->error, LOG_ERR);
719 dol_syslog(get_class($this).
"::update ref null");
735 public function fetch($id, $ref =
'', $ref_ext =
'', $email_msgid =
'')
737 if (empty($id) && empty($ref) && empty($ref_ext) && empty($email_msgid)) {
738 dol_syslog(get_class($this).
"::fetch Bad parameters", LOG_WARNING);
742 $sql =
"SELECT rowid, entity, fk_project, ref, title, description, public, datec, opp_amount, budget_amount,";
743 $sql .=
" tms, dateo as date_start, datee as date_end, date_close, fk_soc, fk_user_creat, fk_user_modif, fk_user_close, fk_statut as status, fk_opp_status, opp_percent,";
744 $sql .=
" note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, email_msgid,";
745 $sql .=
" accept_conference_suggestions, accept_booth_suggestions, price_registration, price_booth, max_attendees, date_start_event, date_end_event, location, extraparams";
746 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet";
748 $sql .=
" WHERE rowid = ".((int) $id);
750 $sql .=
" WHERE entity IN (".getEntity(
'project').
")";
752 $sql .=
" AND ref = '".$this->db->escape($ref).
"'";
753 } elseif (!empty($ref_ext)) {
754 $sql .=
" AND ref_ext = '".$this->db->escape($ref_ext).
"'";
756 $sql .=
" AND email_msgid = '".$this->db->escape($email_msgid).
"'";
760 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
761 $resql = $this->db->query($sql);
763 $num_rows = $this->db->num_rows($resql);
766 $obj = $this->db->fetch_object($resql);
768 $this->
id = $obj->rowid;
769 $this->entity = $obj->entity;
770 $this->
ref = $obj->ref;
771 $this->fk_project = $obj->fk_project;
772 $this->title = $obj->title;
774 $this->date_c = $this->db->jdate($obj->datec);
775 $this->datec = $this->db->jdate($obj->datec);
776 $this->date_m = $this->db->jdate($obj->tms);
777 $this->datem = $this->db->jdate($obj->tms);
778 $this->date_start = $this->db->jdate($obj->date_start);
779 $this->date_end = $this->db->jdate($obj->date_end);
780 $this->date_close = $this->db->jdate($obj->date_close);
781 $this->note_private = $obj->note_private;
782 $this->note_public = $obj->note_public;
783 $this->socid = $obj->fk_soc;
784 $this->user_author_id = $obj->fk_user_creat;
785 $this->user_modification_id = $obj->fk_user_modif;
786 $this->user_closing_id = $obj->fk_user_close;
787 $this->
public = $obj->public;
788 $this->statut = $obj->status;
789 $this->
status = $obj->status;
790 $this->opp_status = $obj->fk_opp_status;
791 $this->opp_amount = $obj->opp_amount;
792 $this->opp_percent = $obj->opp_percent;
793 $this->budget_amount = $obj->budget_amount;
794 $this->model_pdf = $obj->model_pdf;
795 $this->usage_opportunity = (int) $obj->usage_opportunity;
796 $this->usage_task = (int) $obj->usage_task;
797 $this->usage_bill_time = (int) $obj->usage_bill_time;
798 $this->usage_organize_event = (int) $obj->usage_organize_event;
799 $this->accept_conference_suggestions = (int) $obj->accept_conference_suggestions;
800 $this->accept_booth_suggestions = (int) $obj->accept_booth_suggestions;
801 $this->price_registration = $obj->price_registration;
802 $this->price_booth = $obj->price_booth;
803 $this->max_attendees = $obj->max_attendees;
804 $this->date_start_event = $this->db->jdate($obj->date_start_event);
805 $this->date_end_event = $this->db->jdate($obj->date_end_event);
806 $this->location = $obj->location;
807 $this->email_msgid = $obj->email_msgid;
808 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
810 $this->db->free($resql);
819 $this->db->free($resql);
823 $this->error = $this->db->lasterror();
824 $this->errors[] = $this->db->lasterror();
841 if ($fetched ===
false) {
842 $res = $this->
fetch($id);
848 if ($fetched ===
true) {
849 if ($key ==
'__PROJECT_ID__') {
850 $substitution = ($this->
id > 0 ? $this->id :
'');
851 } elseif ($key ==
'__PROJECT_REF__') {
852 $substitution = $this->ref;
853 } elseif ($key ==
'__PROJECT_NAME__') {
854 $substitution = $this->title;
858 return (
string) $substitution;
873 public function get_element_list($type, $tablename, $datefieldname =
'', $date_start =
null, $date_end =
null, $projectkey =
'fk_projet')
881 if ($this->
id <= 0) {
887 if ($type ==
'agenda') {
888 $sql =
"SELECT id as rowid FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project IN (".$this->db->sanitize((
string) $ids).
") AND entity IN (".
getEntity(
'agenda').
")";
889 } elseif ($type ==
'expensereport') {
890 $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((
string) $ids).
")";
891 } elseif ($type ==
'project_task') {
892 $sql =
"SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet IN (".$this->db->sanitize((
string) $ids).
")";
893 } elseif ($type ==
'element_time') {
894 $sql =
"SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet IN (".$this->db->sanitize((
string) $ids).
")";
895 } elseif ($type ==
'stocktransfer_stocktransfer') {
896 $sql =
"SELECT ms.rowid, ms.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX.
"stocktransfer_stocktransfer 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((
string) $ids).
") AND ms.type_mouvement = 1";
897 } elseif ($type ==
'loan') {
898 $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((
string) $ids).
")";
900 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" IN (".$this->db->sanitize((
string) $ids).
") AND entity IN (".
getEntity($type).
")";
903 if (
isDolTms($date_start) && $type ==
'loan') {
904 $sql .=
" AND (dateend > '".$this->db->idate((
int) $date_start).
"' OR dateend IS NULL)";
905 } elseif (
isDolTms($date_start) && ($type !=
'project_task')) {
906 if (empty($datefieldname) && !empty($this->table_element_date)) {
907 $datefieldname = $this->table_element_date;
909 if (empty($datefieldname)) {
910 return 'Error this object has no date field defined';
912 $sql .=
" AND (".$datefieldname.
" >= '".$this->db->idate((
int) $date_start).
"' OR ".$datefieldname.
" IS NULL)";
915 if (
isDolTms($date_end) && $type ==
'loan') {
916 $sql .=
" AND (datestart < '".$this->db->idate((
int) $date_end).
"' OR datestart IS NULL)";
917 } elseif (
isDolTms($date_end) && ($type !=
'project_task')) {
918 if (empty($datefieldname) && !empty($this->table_element_date)) {
919 $datefieldname = $this->table_element_date;
921 if (empty($datefieldname)) {
922 return 'Error this object has no date field defined';
924 $sql .=
" AND (".$datefieldname.
" <= '".$this->db->idate((
int) $date_end).
"' OR ".$datefieldname.
" IS NULL)";
930 'tablename' => $tablename,
931 'datefieldname' => $datefieldname,
932 'dates' => $date_start,
933 'datee' => $date_end,
934 'fk_projet' => $projectkey,
937 $reshook = $hookmanager->executeHooks(
'getElementList', $parameters);
939 $sql = $hookmanager->resPrint;
941 $sql .= $hookmanager->resPrint;
949 dol_syslog(get_class($this).
"::get_element_list", LOG_DEBUG);
950 $result = $this->db->query($sql);
952 $nump = $this->db->num_rows($result);
956 $obj = $this->db->fetch_object($result);
958 $elements[$i] = $obj->rowid.(empty($obj->fk_user) ?
'' :
'_'.$obj->fk_user);
962 $this->db->free($result);
980 public function delete($user, $notrigger = 0)
982 global $langs, $conf;
983 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
993 $this->error =
'ErrorFailToDeleteLinkedContact';
995 $this->db->rollback();
1001 $listoftables = array(
1002 'propal' =>
'fk_projet',
1003 'commande' =>
'fk_projet',
1004 'facture' =>
'fk_projet',
1005 'supplier_proposal' =>
'fk_projet',
1006 'commande_fournisseur' =>
'fk_projet',
1007 'facture_fourn' =>
'fk_projet',
1008 'expensereport_det' =>
'fk_projet',
1009 'contrat' =>
'fk_projet',
1010 'fichinter' =>
'fk_projet',
1011 'don' => array(
'field' =>
'fk_projet',
'module' =>
'don'),
1012 'actioncomm' =>
'fk_project',
1013 'mrp_mo' => array(
'field' =>
'fk_project',
'module' =>
'mrp'),
1014 'entrepot' =>
'fk_project',
1016 foreach ($listoftables as $key => $value) {
1017 if (is_array($value)) {
1021 $fieldname = $value[
'field'];
1023 $fieldname = $value;
1025 $sql =
"UPDATE ".MAIN_DB_PREFIX.$key.
" SET ".$fieldname.
" = NULL where ".$fieldname.
" = ".((int) $this->
id);
1027 $resql = $this->db->query($sql);
1029 $this->errors[] = $this->db->lasterror();
1037 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_project";
1038 $sql .=
" WHERE fk_project = ".((int) $this->
id);
1040 $result = $this->db->query($sql);
1043 $this->errors[] = $this->db->lasterror();
1059 $elements = array(
'categorie_project');
1060 foreach ($elements as $table) {
1062 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$table;
1063 $sql .=
" WHERE fk_project = ".((int) $this->
id);
1065 $result = $this->db->query($sql);
1068 $this->errors[] = $this->db->lasterror();
1075 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet_extrafields";
1076 $sql .=
" WHERE fk_object = ".((int) $this->
id);
1078 $resql = $this->db->query($sql);
1080 $this->errors[] = $this->db->lasterror();
1087 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"projet";
1088 $sql .=
" WHERE rowid=".((int) $this->
id);
1090 $resql = $this->db->query($sql);
1092 $this->errors[] = $langs->trans(
"CantRemoveProject", $langs->transnoentitiesnoconv(
"ProjectOverview"));
1099 if (empty($error)) {
1102 if ($conf->project->dir_output && !empty($projectref)) {
1103 $dir = $conf->project->dir_output.
"/".$projectref;
1104 if (file_exists($dir)) {
1107 $this->errors[] =
'ErrorFailToDeleteDir';
1115 $result = $this->call_trigger(
'PROJECT_DELETE', $user);
1124 if (empty($error)) {
1125 $this->db->commit();
1128 foreach ($this->errors as $errmsg) {
1129 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
1130 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1132 dol_syslog(get_class($this).
"::delete ".$this->error, LOG_ERR);
1133 $this->db->rollback();
1148 if ($this->
id <= 0) {
1152 if ($type ==
'agenda') {
1153 $sql =
"SELECT COUNT(id) as nb FROM ".MAIN_DB_PREFIX.
"actioncomm WHERE fk_project = ".((int) $this->
id).
" AND entity IN (".
getEntity(
'agenda').
")";
1154 } elseif ($type ==
'expensereport') {
1155 $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);
1156 } elseif ($type ==
'project_task') {
1157 $sql =
"SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX.
"projet_task as pt WHERE pt.fk_projet = ".((int) $this->
id);
1158 } elseif ($type ==
'element_time') {
1159 $sql =
"SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX.
"projet_task as pt, ".MAIN_DB_PREFIX.
"element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet = ".((int) $this->
id);
1160 } elseif ($type ==
'stock_mouvement') {
1161 $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";
1162 } elseif ($type ==
'loan') {
1163 $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);
1165 $sql =
"SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.$tablename.
" WHERE ".$projectkey.
" = ".((int) $this->
id).
" AND entity IN (".
getEntity($type).
")";
1168 $result = $this->db->query($sql);
1174 $obj = $this->db->fetch_object($result);
1176 $this->db->free($result);
1189 $countTasks = count($this->lines);
1192 foreach ($this->lines as $task) {
1193 if ($task->hasChildren() <= 0) {
1195 $ret = $task->delete($user);
1197 $this->errors[] = $this->db->lasterror();
1204 if ($deleted && count($this->lines) < $countTasks) {
1205 if (count($this->lines)) {
1227 if ($this->
status == self::STATUS_VALIDATED) {
1228 dol_syslog(get_class($this).
"::validate action abandoned: already validated", LOG_WARNING);
1233 if (preg_match(
'/^'.preg_quote($langs->trans(
"CopyOf").
' ',
'/').
'/', $this->title)) {
1234 $this->error = $langs->trans(
"ErrorFieldFormat", $langs->transnoentities(
"Label")).
'. '.$langs->trans(
'RemoveString', $langs->transnoentitiesnoconv(
"CopyOf"));
1240 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
1241 $sql .=
" SET fk_statut = ".self::STATUS_VALIDATED;
1242 $sql .=
" WHERE rowid = ".((int) $this->
id);
1245 dol_syslog(get_class($this).
"::setValid", LOG_DEBUG);
1246 $resql = $this->db->query($sql);
1249 if (empty($notrigger)) {
1250 $result = $this->call_trigger(
'PROJECT_VALIDATE', $user);
1260 $this->db->commit();
1263 $this->db->rollback();
1264 $this->error = implode(
',', $this->errors);
1265 dol_syslog(get_class($this).
"::setValid ".$this->error, LOG_ERR);
1269 $this->db->rollback();
1270 $this->error = $this->db->lasterror();
1287 if ($this->
status != self::STATUS_CLOSED) {
1290 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"projet";
1291 $sql .=
" SET fk_statut = ".self::STATUS_CLOSED.
", fk_user_close = ".((int) $user->id).
", date_close = '".$this->db->idate($now).
"'";
1292 $sql .=
" WHERE rowid = ".((int) $this->
id);
1293 $sql .=
" AND fk_statut = ".self::STATUS_VALIDATED;
1299 dol_syslog(get_class($this).
"::setClose", LOG_DEBUG);
1300 $resql = $this->db->query($sql);
1303 $result = $this->call_trigger(
'PROJECT_CLOSE', $user);
1311 $this->db->commit();
1314 $this->db->rollback();
1315 $this->error = implode(
',', $this->errors);
1316 dol_syslog(get_class($this).
"::setClose ".$this->error, LOG_ERR);
1320 $this->db->rollback();
1321 $this->error = $this->db->lasterror();
1353 if (is_null($status)) {
1357 $statustrans = array(
1363 $statusClass =
'status0';
1364 if (!empty($statustrans[$status])) {
1365 $statusClass = $statustrans[$status];
1368 return dolGetStatus($langs->transnoentitiesnoconv($this->labelStatus[$status]), $langs->transnoentitiesnoconv($this->labelStatusShort[$status]),
'', $statusClass, $mode);
1379 global $conf, $langs;
1381 $langs->load(
'projects');
1382 $option = $params[
'option'] ??
'';
1383 $moreinpopup = $params[
'moreinpopup'] ??
'';
1386 if ($option !=
'nolink') {
1387 $datas[
'picto'] =
img_picto(
'', $this->picto,
'class="pictofixedwidth"').
' <u class="paddingrightonly">'.$langs->trans(
"Project").
'</u>';
1389 if (isset($this->
status)) {
1390 $datas[
'picto'] .=
' '.$this->getLibStatut(5);
1392 $datas[
'ref'] = (isset($datas[
'picto']) ?
'<br>' :
'').
'<b>'.$langs->trans(
'Ref').
': </b>'.$this->ref;
1393 $datas[
'label'] =
'<br><b>'.$langs->trans(
'Label').
': </b>'.$this->title;
1394 if (isset($this->
public)) {
1395 $datas[
'visibility'] =
'<br><b>'.$langs->trans(
"Visibility").
":</b> ";
1396 $datas[
'visibility'] .= ($this->
public ?
img_picto($langs->trans(
'SharedProject'),
'world',
'class="pictofixedwidth"').$langs->trans(
"SharedProject") :
img_picto($langs->trans(
'PrivateProject'),
'private',
'class="pictofixedwidth"').$langs->trans(
"PrivateProject"));
1398 if (!empty($this->thirdparty_name)) {
1399 $datas[
'thirdparty'] =
'<br><b>'.$langs->trans(
'ThirdParty').
': </b>'.$this->thirdparty_name;
1401 if (!empty($this->date_start)) {
1402 $datas[
'datestart'] =
'<br><b>'.$langs->trans(
'DateStart').
': </b>'.
dol_print_date($this->date_start,
'day');
1404 if (!empty($this->date_end)) {
1405 $datas[
'dateend'] =
'<br><b>'.$langs->trans(
'DateEnd').
': </b>'.
dol_print_date($this->date_end,
'day');
1408 $datas[
'moreinpopup'] =
'<br>'.$moreinpopup;
1428 public function getNomUrl($withpicto = 0, $option =
'', $addlabel = 0, $moreinpopup =
'', $sep =
' - ', $notooltip = 0, $save_lastsearch_value = -1, $morecss =
'', $save_pageforbacktolist =
'')
1430 global $conf, $langs, $user, $hookmanager;
1432 if (!empty($conf->dol_no_mouse_hover)) {
1442 'objecttype' => $this->element,
1443 'moreinpopup' => $moreinpopup,
1444 'option' => $option,
1446 $classfortooltip =
'classfortooltip';
1449 $classfortooltip =
'classforajaxtooltip';
1450 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1457 if ($option !=
'nolink') {
1458 if (preg_match(
'/\.php$/', $option)) {
1460 } elseif ($option ==
'task') {
1461 $url = DOL_URL_ROOT.
'/projet/tasks.php?id='.$this->id;
1462 } elseif ($option ==
'preview') {
1463 $url = DOL_URL_ROOT.
'/projet/element.php?id='.$this->id;
1464 } elseif ($option ==
'eventorganization') {
1465 $url = DOL_URL_ROOT.
'/eventorganization/conferenceorbooth_list.php?projectid='.$this->id;
1467 $url = DOL_URL_ROOT.
'/projet/card.php?id='.$this->id;
1470 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1471 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1472 $add_save_lastsearch_values = 1;
1474 if ($add_save_lastsearch_values) {
1475 $url .=
'&save_lastsearch_values=1';
1477 $add_save_backpagefor = ($save_pageforbacktolist ? 1 : 0);
1478 if ($add_save_backpagefor) {
1479 $url .=
"&save_pageforbacktolist=".urlencode($save_pageforbacktolist);
1484 if (empty($notooltip) && $user->hasRight(
'projet',
'lire')) {
1486 $label = $langs->trans(
"ShowProject");
1487 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1489 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1490 $linkclose .= $dataparams.
' class="'.$classfortooltip.($morecss ?
' '.$morecss :
'').
'"';
1492 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1495 $picto =
'projectpub';
1496 if (!$this->
public) {
1500 $linkstart =
'<a href="'.$url.
'"';
1501 $linkstart .= $linkclose.
'>';
1504 $result .= $linkstart;
1506 $result .=
img_object(($notooltip ?
'' : $label), $picto,
'class="pictofixedwidth em088"', 0, 0, $notooltip ? 0 : 1);
1508 if ($withpicto != 2) {
1509 if ($addlabel >= 0) {
1510 $result .= $this->ref;
1512 $result .= $this->title;
1515 $result .= $linkend;
1516 if ($withpicto != 2) {
1517 $result .= (($addlabel > 0 && $this->title) ?
'<span class="opacitymedium">'.$sep.dol_trunc($this->title, ($addlabel > 1 ? $addlabel : 0)).
'</span>' :
'');
1521 $hookmanager->initHooks(array(
'projectdao'));
1522 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1523 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1525 $result = $hookmanager->resPrint;
1527 $result .= $hookmanager->resPrint;
1542 global $user, $langs, $conf;
1548 $this->
ref =
'SPECIMEN';
1549 $this->entity = $conf->entity;
1550 $this->specimen = 1;
1552 $this->date_c = $now;
1553 $this->date_m = $now;
1554 $this->date_start = $now;
1555 $this->date_end = $now + (3600 * 24 * 365);
1556 $this->note_public =
'SPECIMEN';
1557 $this->note_private =
'Private Note';
1558 $this->fk_project = 0;
1559 $this->opp_amount = 20000;
1560 $this->budget_amount = 10000;
1562 $this->usage_opportunity = 1;
1563 $this->usage_task = 1;
1564 $this->usage_bill_time = 1;
1565 $this->usage_organize_event = 1;
1596 if (($mode ==
'read' && $user->hasRight(
'projet',
'all',
'lire')) || ($mode ==
'write' && $user->hasRight(
'projet',
'all',
'creer')) || ($mode ==
'delete' && $user->hasRight(
'projet',
'all',
'supprimer'))) {
1598 } elseif ($this->
public && (($mode ==
'read' && $user->hasRight(
'projet',
'lire')) || ($mode ==
'write' && $user->hasRight(
'projet',
'creer')) || ($mode ==
'delete' && $user->hasRight(
'projet',
'supprimer')))) {
1601 foreach (array(
'internal',
'external') as $source) {
1603 $num = count($userRole);
1606 while ($nblinks < $num) {
1607 if ($source ==
'internal' && $user->id == $userRole[$nblinks][
'id']) {
1608 if ($mode ==
'read' && $user->hasRight(
'projet',
'lire')) {
1611 if ($mode ==
'write' && $user->hasRight(
'projet',
'creer')) {
1614 if ($mode ==
'delete' && $user->hasRight(
'projet',
'supprimer')) {
1618 if ($source ==
'external' && $user->socid > 0 && $user->socid == $userRole[$nblinks][
'socid']) {
1619 if ($mode ==
'read' && $user->hasRight(
'projet',
'lire')) {
1622 if ($mode ==
'write' && $user->hasRight(
'projet',
'creer')) {
1625 if ($mode ==
'delete' && $user->hasRight(
'projet',
'supprimer')) {
1641 return ($userAccess ? $userAccess : -1);
1656 $projects = array();
1660 $listofprojectcontacttype = array();
1661 $sql2 =
"SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1662 $sql2 .=
" WHERE ctc.element = '".$this->db->escape($this->element).
"'";
1663 $sql2 .=
" AND ctc.source = 'internal'";
1664 $resql = $this->db->query($sql2);
1666 while ($obj = $this->db->fetch_object($resql)) {
1667 $listofprojectcontacttype[$obj->rowid] = $obj->code;
1672 if (count($listofprojectcontacttype) == 0) {
1673 $listofprojectcontacttype[0] =
'0';
1677 $sql =
"SELECT p.rowid, p.ref";
1678 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
1679 $sql .=
" WHERE p.entity IN (".getEntity(
'project').
")";
1682 $sql .=
" AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).
")";
1686 $sql .=
" AND (p.public = 1";
1687 $sql .=
" OR EXISTS (SELECT ec.rowid FROM ".MAIN_DB_PREFIX.
"element_contact as ec";
1688 $sql .=
" WHERE ec.element_id = p.rowid AND ec.fk_c_type_contact IN (".$this->db->sanitize(implode(
',', array_keys($listofprojectcontacttype))).
")";
1689 $sql .=
" AND ec.fk_socpeople = ".((int) $fuser->id).
")";
1691 } elseif ($mode == 1) {
1692 $sql .=
" AND EXISTS (SELECT ec.rowid FROM ".MAIN_DB_PREFIX.
"element_contact as ec";
1693 $sql .=
" WHERE ec.element_id = p.rowid AND ec.fk_c_type_contact IN (".$this->db->sanitize(implode(
',', array_keys($listofprojectcontacttype))).
")";
1694 $sql .=
" AND ec.fk_socpeople = ".((int) $fuser->id).
")";
1702 if ($errormessage) {
1703 $this->errors[] = $errormessage;
1704 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
1708 $resql = $this->db->query($sql);
1710 $num = $this->db->num_rows($resql);
1713 $row = $this->db->fetch_row($resql);
1714 $projects[$row[0]] = $row[1];
1719 $this->db->free($resql);
1725 $result = implode(
',', $temp);
1750 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)
1752 global $langs, $conf;
1755 $clone_project_id = 0;
1757 dol_syslog(
"createFromClone clone_contact=".json_encode($clone_contact).
" clone_task=".json_encode($clone_task).
" clone_project_file=".json_encode($clone_project_file).
" clone_note=".json_encode($clone_note).
" move_date=".json_encode($move_date), LOG_DEBUG);
1761 $clone_project =
new Project($this->db);
1763 $clone_project->context[
'createfromclone'] =
'createfromclone';
1768 $clone_project->fetch($fromid);
1769 $clone_project->fetch_optionals();
1770 $clone_project->socid = ($newthirdpartyid > 0 ? $newthirdpartyid : 0);
1771 $clone_project->fetch_thirdparty();
1773 $orign_dt_start = $clone_project->date_start;
1774 $orign_project_ref = $clone_project->ref;
1776 $clone_project->id = 0;
1778 $clone_project->date_start = $now;
1779 if (!empty($clone_project->date_end)) {
1780 if (!empty($orign_dt_start)) {
1781 $clone_project->date_end += ($now - (int) $orign_dt_start);
1782 } elseif (!empty($clone_project->date_c)) {
1783 $clone_project->date_end += ($now - (int) $clone_project->date_c);
1788 $clone_project->date_c = $now;
1791 $clone_project->note_private =
'';
1792 $clone_project->note_public =
'';
1802 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
1803 foreach ($dirmodels as $reldir) {
1804 $file =
dol_buildpath($reldir.
"core/modules/project/".$obj.
'.php', 0);
1805 if (file_exists($file)) {
1808 $modProject =
new $obj();
1809 '@phan-var-force ModeleNumRefProjects $modProject';
1810 $defaultref = $modProject->getNextValue(is_object($clone_project->thirdparty) ? $clone_project->thirdparty :
null, $clone_project);
1814 if (is_numeric($defaultref) && $defaultref <= 0) {
1818 $clone_project->ref = $defaultref;
1819 $clone_project->title = $langs->trans(
"CopyOf").
' '.$clone_project->title;
1822 $result = $clone_project->create($user, $notrigger);
1826 $this->error .= $clone_project->error;
1832 $clone_project_id = $clone_project->id;
1836 $clone_project->note_private =
'';
1837 $clone_project->note_public =
'';
1840 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_public, ENT_QUOTES | ENT_HTML5),
'_public');
1842 $this->error .= $clone_project->error;
1844 $this->db->rollback();
1846 $this->db->commit();
1850 $res = $clone_project->update_note(
dol_html_entity_decode($clone_project->note_private, ENT_QUOTES | ENT_HTML5),
'_private');
1852 $this->error .= $clone_project->error;
1854 $this->db->rollback();
1856 $this->db->commit();
1861 if ($clone_contact) {
1862 $origin_project =
new Project($this->db);
1863 $origin_project->fetch($fromid);
1865 foreach (array(
'internal',
'external') as $source) {
1866 $tab = $origin_project->liste_contact(-1, $source);
1867 if (is_array($tab) && count($tab) > 0) {
1868 foreach ($tab as $contacttoadd) {
1869 $clone_project->add_contact($contacttoadd[
'id'], $contacttoadd[
'code'], $contacttoadd[
'source'], $notrigger);
1870 if ($clone_project->error ==
'DB_ERROR_RECORD_ALREADY_EXISTS') {
1871 $langs->load(
"errors");
1872 $this->error .= $langs->trans(
"ErrorThisContactIsAlreadyDefinedAsThisType");
1875 if ($clone_project->error !=
'') {
1876 $this->error .= $clone_project->error;
1881 } elseif ($tab < 0) {
1882 $this->error .= $origin_project->error;
1889 if ($clone_project_file) {
1890 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1895 if (
dol_mkdir($clone_project_dir) >= 0) {
1896 $filearray =
dol_dir_list($ori_project_dir,
"files", 0,
'',
'(\.meta|_preview.*\.png)$',
'', SORT_ASC, 1);
1897 foreach ($filearray as $key => $file) {
1898 $rescopy =
dol_copy($ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name'],
'0', 1);
1899 if (is_numeric($rescopy) && $rescopy < 0) {
1900 $this->error .= $langs->trans(
"ErrorFailToCopyFile", $ori_project_dir.
'/'.$file[
'name'], $clone_project_dir.
'/'.$file[
'name']);
1905 $this->error .= $langs->trans(
'ErrorInternalErrorDetected').
':dol_mkdir';
1912 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
1914 $taskstatic =
new Task($this->db);
1918 if ($user->socid > 0) {
1919 $socid = $user->socid;
1922 $tasksarray = $taskstatic->getTasksArray(
null,
null, $fromid, $socid, 0);
1924 $tab_conv_child_parent = array();
1928 foreach ($tasksarray as $tasktoclone) {
1929 $result_clone = $taskstatic->createFromClone($user, $tasktoclone->id, $clone_project_id, $tasktoclone->fk_task_parent, $move_date,
true,
false, $clone_task_file,
true,
false);
1930 if ($result_clone <= 0) {
1931 $this->error .= $taskstatic->error;
1934 $new_task_id = $result_clone;
1935 $taskstatic->fetch($tasktoclone->id);
1939 if (($taskstatic->hasChildren()) && !array_key_exists($tasktoclone->id, $tab_conv_child_parent)) {
1940 $tab_conv_child_parent[$tasktoclone->id] = $new_task_id;
1946 $tasksarray = $taskstatic->getTasksArray(
null,
null, $clone_project_id, $socid, 0);
1947 foreach ($tasksarray as $task_cloned) {
1948 $taskstatic->fetch($task_cloned->id);
1949 if ($taskstatic->fk_task_parent != 0) {
1950 $taskstatic->fk_task_parent = $tab_conv_child_parent[$taskstatic->fk_task_parent];
1952 $res = $taskstatic->update($user, $notrigger);
1953 if ($result_clone <= 0) {
1954 $this->error .= $taskstatic->error;
1961 unset($clone_project->context[
'createfromclone']);
1963 if (!$error && $clone_project_id != 0) {
1964 $this->db->commit();
1965 return $clone_project_id;
1967 $this->db->rollback();
1968 dol_syslog(get_class($this).
"::createFromClone nbError: ".$error.
" error : ".$this->error, LOG_ERR);
1982 global $user, $langs, $conf;
1987 $taskstatic =
new Task($this->db);
1991 if ($user->socid > 0) {
1992 $socid = $user->socid;
1995 $tasksarray = $taskstatic->getTasksArray(
null,
null, $this->
id, $socid, 0);
1997 foreach ($tasksarray as $tasktoshiftdate) {
2000 if ((!empty($tasktoshiftdate->date_start)) || (!empty($tasktoshiftdate->date_end))) {
2003 $task =
new Task($this->db);
2004 $result = $task->fetch($tasktoshiftdate->id);
2007 $this->error .= $task->error;
2015 if (!empty($tasktoshiftdate->date_start)) {
2016 $task->date_start = $this->date_start + ($tasktoshiftdate->date_start - $old_project_dt_start);
2020 if (!empty($tasktoshiftdate->date_end)) {
2021 $task->date_end = $this->date_start + ($tasktoshiftdate->date_end - $old_project_dt_start);
2025 $result = $task->update($user);
2028 $this->error .= $task->error;
2050 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->db->sanitize($tableName);
2052 if ($tableName ==
"actioncomm") {
2053 $sql .=
" SET fk_project=".$this->id;
2054 $sql .=
" WHERE id=".((int) $elementSelectId);
2055 } elseif (in_array($tableName, [
"entrepot",
"mrp_mo",
"stocktransfer_stocktransfer"])) {
2056 $sql .=
" SET fk_project=".$this->id;
2057 $sql .=
" WHERE rowid=".((int) $elementSelectId);
2059 $sql .=
" SET fk_projet=".$this->id;
2060 $sql .=
" WHERE rowid=".((int) $elementSelectId);
2063 dol_syslog(get_class($this).
"::update_element", LOG_DEBUG);
2064 $resql = $this->db->query($sql);
2066 $this->error = $this->db->lasterror();
2083 public function remove_element($tableName, $elementSelectId, $projectfield =
'fk_projet')
2086 $sql =
"UPDATE ".MAIN_DB_PREFIX.$this->db->sanitize($tableName);
2088 if ($tableName ==
"actioncomm") {
2089 $sql .=
" SET fk_project = NULL";
2090 $sql .=
" WHERE id = ".((int) $elementSelectId);
2091 $sql .=
" AND fk_project = ".((int) $this->
id);
2093 $sql .=
" SET ".$this->db->sanitize($projectfield).
" = NULL";
2094 $sql .=
" WHERE rowid = ".((int) $elementSelectId);
2095 $sql .=
" AND ".$this->db->sanitize($projectfield).
" = ".((int) $this->
id);
2098 dol_syslog(get_class($this).
"::remove_element", LOG_DEBUG);
2099 $resql = $this->db->query($sql);
2101 $this->error = $this->db->lasterror();
2118 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
2120 global $conf, $langs;
2122 $langs->load(
"projects");
2125 $modele =
'baleine';
2127 if ($this->model_pdf) {
2128 $modele = $this->model_pdf;
2134 $modelpath =
"core/modules/project/doc/";
2136 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
2151 $this->weekWorkLoad = array();
2152 $this->weekWorkLoadPerTask = array();
2154 if (empty($datestart)) {
2158 $sql =
"SELECT ptt.rowid as taskid, ptt.element_duration, ptt.element_date, ptt.element_datehour, ptt.fk_element";
2159 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
2160 $sql .=
" WHERE ptt.fk_element = pt.rowid";
2161 $sql .=
" AND ptt.elementtype = 'task'";
2162 $sql .=
" AND pt.fk_projet = ".((int) $this->
id);
2163 $sql .=
" AND (ptt.element_date >= '".$this->db->idate($datestart).
"' ";
2164 $sql .=
" AND ptt.element_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'w') - 1).
"')";
2166 $sql .=
" AND ptt.fk_element=".((int) $taskid);
2168 if (is_numeric($userid)) {
2169 $sql .=
" AND ptt.fk_user=".((int) $userid);
2173 $resql = $this->db->query($sql);
2175 $dayallreadyfound = array();
2177 $num = $this->db->num_rows($resql);
2181 $obj = $this->db->fetch_object($resql);
2182 $day = $this->db->jdate($obj->element_date);
2183 if (empty($dayallreadyfound[$day])) {
2184 $this->weekWorkLoad[$day] = $obj->element_duration;
2185 $this->weekWorkLoadPerTask[$day][$obj->fk_element] = $obj->element_duration;
2187 $this->weekWorkLoad[$day] += $obj->element_duration;
2188 $this->weekWorkLoadPerTask[$day][$obj->fk_element] += $obj->element_duration;
2190 $dayallreadyfound[$day] = 1;
2193 $this->db->free($resql);
2196 $this->error =
"Error ".$this->db->lasterror();
2197 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
2213 $this->monthWorkLoad = array();
2214 $this->monthWorkLoadPerTask = array();
2216 if (empty($datestart)) {
2220 $sql =
"SELECT ptt.rowid as taskid, ptt.element_duration, ptt.element_date, ptt.element_datehour, ptt.fk_element";
2221 $sql .=
" FROM ".MAIN_DB_PREFIX.
"element_time AS ptt, ".MAIN_DB_PREFIX.
"projet_task as pt";
2222 $sql .=
" WHERE ptt.fk_element = pt.rowid";
2223 $sql .=
" AND ptt.elementtype = 'task'";
2224 $sql .=
" AND pt.fk_projet = ".((int) $this->
id);
2225 $sql .=
" AND (ptt.element_date >= '".$this->db->idate($datestart).
"' ";
2226 $sql .=
" AND ptt.element_date <= '".$this->db->idate(
dol_time_plus_duree($datestart, 1,
'm') - 1).
"')";
2228 $sql .=
" AND ptt.fk_element=".((int) $taskid);
2230 if (is_numeric($userid)) {
2231 $sql .=
" AND ptt.fk_user=".((int) $userid);
2235 $resql = $this->db->query($sql);
2237 $weekalreadyfound = array();
2239 $num = $this->db->num_rows($resql);
2244 $obj = $this->db->fetch_object($resql);
2245 if (!empty($obj->element_date)) {
2246 $date = explode(
'-', $obj->element_date);
2247 $week_number =
getWeekNumber((
int) $date[2], (
int) $date[1], (
int) $date[0]);
2249 if (empty($weekalreadyfound[$week_number])) {
2250 $this->monthWorkLoad[$week_number] = $obj->element_duration;
2251 $this->monthWorkLoadPerTask[$week_number][$obj->fk_element] = $obj->element_duration;
2253 $this->monthWorkLoad[$week_number] += $obj->element_duration;
2254 if (!isset($this->monthWorkLoadPerTask[$week_number][$obj->fk_element])) {
2255 $this->monthWorkLoadPerTask[$week_number][$obj->fk_element] = 0;
2257 $this->monthWorkLoadPerTask[$week_number][$obj->fk_element] += $obj->element_duration;
2259 $weekalreadyfound[$week_number] = 1;
2262 $this->db->free($resql);
2265 $this->error =
"Error ".$this->db->lasterror();
2266 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
2281 global $conf, $langs;
2287 $response->warning_delay = $conf->project->warning_delay / 60 / 60 / 24;
2288 $response->label = $langs->trans(
"OpenedProjects");
2289 $response->labelShort = $langs->trans(
"Opened");
2290 $response->url = DOL_URL_ROOT.
'/projet/list.php?search_project_user=-1&search_status=1&mainmenu=project';
2291 $response->url_late = DOL_URL_ROOT.
'/projet/list.php?search_option=late&mainmenu=project';
2292 $response->img =
img_object(
'',
"projectpub");
2293 $response->nbtodo = 0;
2294 $response->nbtodolate = 0;
2296 $sql =
"SELECT p.rowid, p.fk_statut as status, p.fk_opp_status, p.datee as datee";
2297 $sql .=
" FROM (".MAIN_DB_PREFIX.
"projet as p";
2299 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s on p.fk_soc = s.rowid";
2302 $sql .=
" WHERE p.fk_statut = 1";
2303 $sql .=
" AND p.entity IN (".getEntity(
'project').
')';
2306 $projectsListId =
null;
2307 if (!$user->hasRight(
"projet",
"all",
"lire")) {
2308 $response->url = DOL_URL_ROOT.
'/projet/list.php?search_status=1&mainmenu=project';
2310 if (empty($projectsListId)) {
2314 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2323 $resql = $this->db->query($sql);
2325 $project_static =
new Project($this->db);
2329 while ($obj = $this->db->fetch_object($resql)) {
2330 $response->nbtodo++;
2332 $project_static->statut = $obj->status;
2333 $project_static->status = $obj->status;
2334 $project_static->opp_status = $obj->fk_opp_status;
2335 $project_static->date_end = $this->db->jdate($obj->datee);
2337 if ($project_static->hasDelay()) {
2338 $response->nbtodolate++;
2345 $this->error = $this->db->error();
2376 $this->nb = array();
2378 $sql =
"SELECT count(p.rowid) as nb";
2379 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
2381 $sql .=
" p.entity IN (".getEntity(
'project').
")";
2382 if (!$user->hasRight(
'projet',
'all',
'lire')) {
2384 $sql .=
"AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
2387 $resql = $this->db->query($sql);
2389 while ($obj = $this->db->fetch_object($resql)) {
2390 $this->nb[
"projects"] = $obj->nb;
2392 $this->db->free($resql);
2396 $this->error = $this->db->error();
2411 if (!($this->
status == self::STATUS_VALIDATED)) {
2414 if (!$this->date_end) {
2420 return ($this->date_end) < ($now - $conf->project->warning_delay);
2432 $sql =
'SELECT c.rowid, datec as datec, tms as datem,';
2433 $sql .=
' date_close as datecloture,';
2434 $sql .=
' fk_user_creat as fk_user_author, fk_user_close as fk_user_cloture';
2435 $sql .=
' FROM '.MAIN_DB_PREFIX.
'projet as c';
2436 $sql .=
' WHERE c.rowid = '.((int) $id);
2437 $result = $this->db->query($sql);
2439 if ($this->db->num_rows($result)) {
2440 $obj = $this->db->fetch_object($result);
2442 $this->
id = $obj->rowid;
2444 $this->user_creation_id = $obj->fk_user_author;
2445 $this->user_closing_id = $obj->fk_user_cloture;
2447 $this->date_creation = $this->db->jdate($obj->datec);
2448 $this->date_modification = $this->db->jdate($obj->datem);
2449 $this->date_cloture = $this->db->jdate($obj->datecloture);
2452 $this->db->free($result);
2470 require_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2471 return parent::setCategoriesCommon($categories, Categorie::TYPE_PROJECT);
2484 require_once DOL_DOCUMENT_ROOT.
'/projet/class/task.class.php';
2485 $taskstatic =
new Task($this->db);
2487 $this->lines = $taskstatic->getTasksArray(
null, $user, $this->
id, 0, 0,
'',
'-1',
'', 0, 0,
null, 0, array(), 0, $loadRoleMode);
2509 public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc =
"", $addr_bcc =
"", $deliveryreceipt = 0, $msgishtml = -1, $errors_to =
'', $moreinheader =
'')
2526 global $conf, $langs;
2528 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
2531 if (empty($conf->dol_optimize_smallscreen)) {
2538 $return =
'<div class="box-flex-item '.($size ==
'small' ?
'box-flex-item-small' :
'').
' box-flex-grow-zero '.($arraydata[
'mode'] ==
'kanbangroupby' ?
'kanban-draggable" data-itemid="'.$this->
id.
'" data-element="'.$this->element.
'" data-tableelement="'.$this->table_element.
'"' :
'"').
'>';
2539 $return .=
'<div class="info-box info-box-sm">';
2540 $return .=
'<span class="info-box-icon bg-infobox-action">';
2541 $return .=
img_picto(
'', $this->
public ?
'projectpub' : $this->picto);
2543 $return .=
'</span>';
2544 $return .=
'<div class="info-box-content">';
2545 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref);
2549 $return .=
'</span>';
2550 if ($selected >= 0) {
2551 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
2566 if (property_exists($this,
'thirdparty') && !is_null($this->thirdparty) && is_object($this->thirdparty) && $this->thirdparty instanceof
Societe && $this->thirdparty->id > 0) {
2567 $return .=
'<br><div class="info-box-ref tdoverflowmax125 inline-block valignmiddle">'.$this->thirdparty->getNomUrl(1);
2568 $return .=
'</div>';
2569 if (!empty($this->thirdparty->phone)) {
2570 $return .=
'<div class="inline-block valignmiddle">';
2571 $return .=
dol_print_phone($this->thirdparty->phone, $this->thirdparty->country_code, 0, $this->thirdparty->id,
'tel',
'hidenum',
'phone', $this->thirdparty->phone, 0,
'paddingleft paddingright');
2572 $return .=
'</div>';
2574 if (!empty($this->thirdparty->email)) {
2575 $return .=
'<div class="inline-block valignmiddle">';
2576 $return .=
dol_print_email($this->thirdparty->email, 0, $this->thirdparty->id,
'thirdparty', -1, 1, 2,
'paddingleft paddingright');
2577 $return .=
'</div>';
2580 if (!empty($arraydata[
'assignedusers'])) {
2582 if ($this->
public) {
2583 $return .=
img_picto($langs->trans(
'Visibility').
': '.$langs->trans(
'SharedProject'),
'world',
'class="paddingrightonly valignmiddle"');
2586 $return .=
img_picto($langs->trans(
'Visibility').
': '.$langs->trans(
'PrivateProject'),
'private',
'class="paddingrightonly valignmiddle"');
2590 $return .=
' <span class="small valignmiddle">'.$arraydata[
'assignedusers'].
'</span>';
2596 $return .=
'<br><div>';
2597 if ($this->usage_opportunity && $this->opp_status_code) {
2600 $return .=
'<div class="opacitymedium small marginrightonly inline-block" title="'.dol_escape_htmltag($langs->trans(
"OppStatus".$this->opp_status_code)).
'">'.round($this->opp_percent).
'%</div>';
2601 $return .=
' <div class="amount small marginrightonly inline-block">'.price($this->opp_amount).
'</div>';
2603 if (method_exists($this,
'getLibStatut')) {
2604 $return .=
'<div class="info-box-status small inline-block valignmiddle">'.$this->getLibStatut(3).
'</div>';
2606 $return .=
'</div>';
2608 $return .=
'</div>';
2609 $return .=
'</div>';
2610 $return .=
'</div>';
2623 $sql =
'SELECT rowid,title';
2624 $sql .=
' FROM '.MAIN_DB_PREFIX.
'projet';
2625 $sql .=
' WHERE fk_project = '.((int) $this->
id);
2626 $sql .=
' ORDER BY title';
2627 $result = $this->db->query($sql);
2629 $n = $this->db->num_rows($result);
2631 $children[] = $this->db->fetch_object($result);
2634 $this->db->free($result);
2649 global
$mysoc, $user, $langs;
2655 $errorsMsg = array();
2659 $firstDayOfWeekDate =
dol_mktime(0, 0, 0, $nowDate[
'mon'], $firstDayOfWeekTS[
'first_day'], $nowDate[
'year']);
2665 $startDate =
dol_print_date($lastWeekStartTS,
'%Y-%m-%d 00:00:00');
2670 CONCAT(u.firstname, ' ', u.lastname) AS name,
2671 u.email,u.weeklyhours,
2672 SUM(et.element_duration) AS total_seconds
2674 ".MAIN_DB_PREFIX.
"element_time AS et
2676 ".MAIN_DB_PREFIX.
"user AS u ON et.fk_user = u.rowid
2678 et.element_date BETWEEN '".$this->db->escape($startDate).
"' AND '".$this->db->escape($endDate).
"'
2679 AND et.elementtype = 'task'
2683 $resql = $this->db->query($sql);
2688 $reportContent =
"<span>Weekly time report from $startDate to $endDate </span><br><br>";
2689 $reportContent .=
'<table border="1" style="border-collapse: collapse;">';
2690 $reportContent .=
'<tr><th>'.$langs->trans(
"User").
'</th><th>Temps saisi (heures)</th><th>Temps travaillé par semaine (heures)</th></tr>';
2696 while ($obj = $this->db->fetch_object($resql)) {
2699 $weekendEnabled = 0;
2703 $weekendEnabled += 1;
2707 $weekendEnabled += 1;
2711 $weekendEnabled += 1;
2715 $weekendEnabled += 1;
2718 $dailyHours = $obj->weeklyhours / (7 - $weekendEnabled);
2721 $adjustedSeconds = $obj->total_seconds + ($numHolidays * $dailyHours * 3600);
2723 $totalHours = round($adjustedSeconds / 3600, 2);
2725 $reportContent .=
"<tr><td>{$obj->name}</td><td>{$totalHours}</td><td>".round($obj->weeklyhours, 2).
"</td></tr>";
2727 $reportContent .=
'</table>';
2729 require_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
2734 $subject =
'Rapport hebdomadaire des temps travaillés';
2738 $errormesg =
"Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
2742 $mail =
new CMailFile($subject, $to, $from, $reportContent, array(), array(), array(),
'',
'', 0, -1,
'',
'',
'',
'text/html');
2744 if ($mail->sendfile()) {
2748 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
2753 $actioncomm->type_code =
'AC_OTH_AUTO';
2754 $actioncomm->socid = $this->thirdparty->id;
2755 $actioncomm->contact_id = 0;
2757 $actioncomm->code =
'AC_EMAIL';
2758 $actioncomm->label =
'createWeeklyReportOK()';
2759 $actioncomm->fk_project = $this->id;
2760 $actioncomm->datep =
dol_now();
2761 $actioncomm->datef = $actioncomm->datep;
2762 $actioncomm->percentage = -1;
2763 $actioncomm->authorid = $user->id;
2764 $actioncomm->userownerid = $user->id;
2766 $actioncomm->email_msgid = $mail->msgid;
2767 $actioncomm->email_subject = $subject;
2768 $actioncomm->email_from = $from;
2769 $actioncomm->email_sender =
'';
2770 $actioncomm->email_to = $to;
2772 $actioncomm->errors_to = $errors_to;
2774 $actioncomm->elementtype =
'project_task';
2775 $actioncomm->fk_element = (int) $this->element;
2777 $actioncomm->create($user);
2779 $errormesg = $mail->error.
' : '.$to;
2783 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
2788 $actioncomm->type_code =
'AC_OTH_AUTO';
2789 $actioncomm->socid = $this->thirdparty->id;
2790 $actioncomm->contact_id = 0;
2792 $actioncomm->code =
'AC_EMAIL';
2793 $actioncomm->label =
'createWeeklyReportKO()';
2794 $actioncomm->note_private = $errormesg;
2795 $actioncomm->fk_project = $this->id;
2796 $actioncomm->datep =
dol_now();
2797 $actioncomm->datef = $actioncomm->datep;
2798 $actioncomm->authorid = $user->id;
2799 $actioncomm->userownerid = $user->id;
2801 $actioncomm->email_msgid = $mail->msgid;
2802 $actioncomm->email_from = $from;
2803 $actioncomm->email_sender =
'';
2804 $actioncomm->email_to = $to;
2806 $actioncomm->errors_to = $errors_to;
2808 $actioncomm->elementtype =
'project_task';
2809 $actioncomm->fk_element = (int) $this->element;
2811 $actioncomm->create($user);
2813 $this->db->commit();
2816 if (!empty($errormesg)) {
2817 $errorsMsg[] = $errormesg;
2821 $this->output .=
'Nb of emails sent : '.$nbMailSend;
2822 dol_syslog(__METHOD__.
" end - ".$this->output, LOG_INFO);
2825 $this->error =
'Nb of emails sent : '.$nbMailSend.
', '.(empty($errorsMsg) ? $error : implode(
', ', $errorsMsg));
2826 dol_syslog(__METHOD__.
" end - ".$this->error, LOG_INFO);
Class to manage agenda events (actions)
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
liste_contact($statusoflink=-1, $source='external', $list=0, $code='', $status=-1, $arrayoftcids=array())
Get array of all contacts for an object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
Class to manage Dolibarr database access.
Class to manage projects.
LibStatut($status, $mode=0)
Renvoi status label for a status.
getLibStatut($mode=0)
Return status label of object.
getElementCount($type, $tablename, $projectkey='fk_projet')
Return the count of a type of linked elements of this project.
getNomUrl($withpicto=0, $option='', $addlabel=0, $moreinpopup='', $sep=' - ', $notooltip=0, $save_lastsearch_value=-1, $morecss='', $save_pageforbacktolist='')
Return clickable name (with optional picto)
fetchAndSetSubstitution($id, $key, $fetched=false)
Fetch object and substitute key.
getChildren()
Return array of sub-projects of the current project.
setValid($user, $notrigger=0)
Validate a project.
createWeeklyReport()
Method for calculating weekly hours worked and generating a report.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
const STATUS_VALIDATED
Open/Validated status.
create($user, $notrigger=0)
Create a project into database.
const STATUS_CLOSED
Closed status.
const STATUS_DRAFT
Draft status.
loadTimeSpentMonth($datestart, $taskid=0, $userid=0)
Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of projec...
__construct($db)
Constructor.
fetch($id, $ref='', $ref_ext='', $email_msgid='')
Get object from database.
shiftTaskDate($old_project_dt_start)
Shift project task date from current date to delta.
hasDelay()
Is the project delayed?
remove_element($tableName, $elementSelectId, $projectfield='fk_projet')
Associate element to a project.
setCategories($categories)
Sets object to supplied categories.
update_element($tableName, $elementSelectId)
Associate element to a project.
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.
loadStateBoard()
Load indicators this->nb for the state board.
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
getLinesArray($user, $loadRoleMode=1)
Create an array of tasks of current project.
get_element_list($type, $tablename, $datefieldname='', $date_start=null, $date_end=null, $projectkey='fk_projet')
Return list of elements for type, linked to a project.
getKanbanView($option='', $arraydata=null, $size='')
Return clickable link of object (with eventually picto)
info($id)
Charge les information d'ordre info dans l'objet commande.
getProjectsAuthorizedForUser($fuser, $mode=0, $list=0, $socid=0, $filter='')
Return array of projects a user has permission on, is affected to, or all projects.
getTooltipContentArray($params)
getTooltipContentArray
sendEmail($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='', $moreinheader='')
Function sending an email to the current project with the text supplied in parameter.
initAsSpecimen()
Initialise an instance with random values.
setClose($user)
Close a project.
loadTimeSpent($datestart, $taskid=0, $userid=0)
Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of projec...
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Create an intervention document on disk using template defined into PROJECT_ADDON_PDF.
restrictedProjectArea(User $user, $mode='read')
Check if user has permission on current project.
deleteTasks($user)
Delete tasks with no children first, then task with children recursively.
update($user, $notrigger=0)
Update a project.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
dol_get_first_day_week($day, $month, $year, $gm=false)
Return first day of week for a date.
getWeekNumber($day, $month, $year)
Return week number.
num_public_holiday($timestampStart, $timestampEnd, $countryCodeOrId='', $lastday=0, $includesaturday=-1, $includesunday=-1, $includefriday=-1, $includemonday=-1)
Return the number of non working days including Friday, Saturday and Sunday (or not) between 2 dates ...
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0, $tz='')
Add a delay to a date.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_copy($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_html_entity_decode($a, $b, $c='UTF-8', $keepsomeentities=0)
Replace html_entity_decode functions to manage errors.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_print_email($email, $contactid=0, $socid=0, $addlink=0, $max=0, $showinvalid=2, $withpicto=0, $morecss='paddingrightonly')
Show EMail link formatted for HTML output.
dol_print_phone($phone, $countrycode='', $contactid=0, $socid=0, $addlink='', $separ=" ", $withpicto='', $titlealt='', $adddivfloat=0, $morecss='paddingright')
Format phone numbers according to country.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
isDolTms($timestamp)
isDolTms check if a timestamp is valid.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_substr($string, $start, $length=null, $stringencoding='', $trunconbytes=0)
Make a substring.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)