diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 7852e985c04f8..c4f5559fa7632 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -68,6 +68,7 @@ $date_start_event = dol_mktime(GETPOST('date_start_eventhour', 'int'), GETPOST('date_start_eventmin', 'int'), GETPOST('date_start_eventsec', 'int'), GETPOST('date_start_eventmonth', 'int'), GETPOST('date_start_eventday', 'int'), GETPOST('date_start_eventyear', 'int')); $date_end_event = dol_mktime(GETPOST('date_end_eventhour', 'int'), GETPOST('date_end_eventmin', 'int'), GETPOST('date_end_eventsec', 'int'), GETPOST('date_end_eventmonth', 'int'), GETPOST('date_end_eventday', 'int'), GETPOST('date_end_eventyear', 'int')); $location = GETPOST('location', 'alphanohtml'); +$fk_project = GETPOST('fk_project', 'int'); $mine = GETPOST('mode') == 'mine' ? 1 : 0; @@ -205,6 +206,7 @@ $db->begin(); $object->ref = GETPOST('ref', 'alphanohtml'); + $object->fk_project = GETPOST('fk_project', 'int'); $object->title = GETPOST('title', 'alphanohtml'); $object->socid = GETPOST('socid', 'int'); $object->description = GETPOST('description', 'restricthtml'); // Do not use 'alpha' here, we want field as it is @@ -304,6 +306,7 @@ $old_start_date = $object->date_start; $object->ref = GETPOST('ref', 'alpha'); + $object->fk_project = GETPOST('fk_project', 'int'); $object->title = GETPOST('title', 'alphanohtml'); // Do not use 'alpha' here, we want field as it is $object->statut = GETPOST('status', 'int'); $object->socid = GETPOST('socid', 'int'); @@ -603,6 +606,14 @@ // Label print ''.$langs->trans("Label").''; + // Parent + if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) { + print ''.$langs->trans("Parent").''; + print img_picto('', 'project', 'class="pictofixedwidth"'); + $formproject->select_projects(-1, '', 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', ''); + print ''; + } + // Usage (opp, task, bill time, ...) if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) { print ''; @@ -970,6 +981,14 @@ function change_percent() print ajax_combobox('status'); print ''; + // Parent + if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) { + print ''.$langs->trans("Parent").''; + print img_picto('', 'project', 'class="pictofixedwidth"'); + $formproject->select_projects(-1, $object->fk_project, 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', ''); + print ''; + } + // Usage if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) { print ''; @@ -1246,6 +1265,14 @@ function set_usage_event() { if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) { $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); } + // Parent + if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) { + if (!empty($object->fk_project) && $object->fk_project) { + $parent = new Project($db); + $parent->fetch($object->fk_project); + $morehtmlref .= $langs->trans("Child of").' '.$parent->getNomUrl(1, 'project').' '.$parent->title; + } + } $morehtmlref .= ''; // Define a complementary filter for search of next/prev ref. @@ -1618,6 +1645,41 @@ function change_percent() print '
'; print ''; // ancre + if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) { + /* + * Sub-projects (children) + */ + $children = $object->getChildren(); + if ($children) { + print ''; + print '
'; + print '
'.$langs->trans('Sub-projects').'
'; + print '
'; + + print '
'; + print ''; + print ''; + print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1); + print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1); + print getTitleFieldOfList('Status', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1); + print ''; + print "\n"; + + $subproject = new Project($db); + foreach ($children as $child) { + $subproject->fetch($child->rowid); + print ''; + print ''; + print ''; + print ''; + print ''; + } + + print '
'.$subproject->getNomUrl(1, 'project').''.$child->title.''.$subproject->getLibStatut(5).'
'; + print '
'; + } + } + /* * Generated documents */ diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 076dae11a0090..ac13af7d25a9a 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -82,6 +82,11 @@ class Project extends CommonObject */ protected $table_ref_field = 'ref'; + /** + * @var int parent project + */ + public $fk_project; + /** * @var string description */ @@ -291,6 +296,7 @@ class Project extends CommonObject */ public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'fk_project' =>array('type'=>'integer', 'label'=>'Parent', 'enabled'=>1, 'visible'=>1, 'notnull'=>0, 'position'=>12), 'ref' =>array('type'=>'varchar(50)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>15, 'searchall'=>1), 'title' =>array('type'=>'varchar(255)', 'label'=>'ProjectLabel', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>17, 'showoncombobox'=>2, 'searchall'=>1), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>3, 'notnull'=>1, 'position'=>19), @@ -426,6 +432,7 @@ public function create($user, $notrigger = 0) $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet ("; $sql .= "ref"; + $sql .= ", fk_project"; $sql .= ", title"; $sql .= ", description"; $sql .= ", fk_soc"; @@ -458,6 +465,7 @@ public function create($user, $notrigger = 0) $sql .= ", ip"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($this->ref)."'"; + $sql .= ", ".($this->fk_project ? ((int) $this->fk_project) : "null"); $sql .= ", '".$this->db->escape($this->title)."'"; $sql .= ", '".$this->db->escape($this->description)."'"; $sql .= ", ".($this->socid > 0 ? $this->socid : "null"); @@ -570,6 +578,7 @@ public function update($user, $notrigger = 0) $sql = "UPDATE ".MAIN_DB_PREFIX."projet SET"; $sql .= " ref='".$this->db->escape($this->ref)."'"; + $sql .= ", fk_project=".($this->fk_project ? ((int) $this->fk_project) : "null"); $sql .= ", title = '".$this->db->escape($this->title)."'"; $sql .= ", description = '".$this->db->escape($this->description)."'"; $sql .= ", fk_soc = ".($this->socid > 0 ? $this->socid : "null"); @@ -680,7 +689,7 @@ public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '') return -1; } - $sql = "SELECT rowid, entity, ref, title, description, public, datec, opp_amount, budget_amount,"; + $sql = "SELECT rowid, entity, fk_project, ref, title, description, public, datec, opp_amount, budget_amount,"; $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,"; $sql .= " note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, email_msgid,"; $sql .= " accept_conference_suggestions, accept_booth_suggestions, price_registration, price_booth, max_attendees, date_start_event, date_end_event, location, extraparams"; @@ -709,6 +718,7 @@ public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '') $this->id = $obj->rowid; $this->entity = $obj->entity; $this->ref = $obj->ref; + $this->fk_project = $obj->fk_project; $this->title = $obj->title; $this->description = $obj->description; $this->date_c = $this->db->jdate($obj->datec); @@ -2480,4 +2490,31 @@ public function getKanbanView($option = '', $arraydata = null) $return .= '
'; return $return; } + + /** + * Return array of sub-projects of the current project + * + * @return array Children of this project as objects with rowid & title as members + */ + public function getChildren() + { + $children = []; + $sql = 'SELECT rowid,title'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'projet'; + $sql .= ' WHERE fk_project = '.((int) $this->id); + $sql .= ' ORDER BY title'; + $result = $this->db->query($sql); + if ($result) { + $n = $this->db->num_rows($result); + while ($n) { + $children[] = $this->db->fetch_object($result); + $n--; + } + $this->db->free($result); + } else { + dol_print_error($this->db); + } + + return $children; + } }