Project Management - Create Project from Template

Hi, i started to modify the controller.php file in modules/AM_ProjectTemplates
in order to

  1. allow users to use “1 Day” Project Task where date end = date start
  2. allow users to use Project Tasks with the same order_number value, so that Tasks would start in the same date
  3. i explicit the duration_unit=“Days” because in my istance, if i select duration = 1 Day, the system created Tasks that started in a day and ended in the follower.

i didn’t consider “Finish to Start” or “Start to Start” directive.

Is there anyone who want to contribute?


<?php


if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class AM_ProjectTemplatesController extends SugarController {

    function action_create_project(){

        global $current_user, $db;

        $project_name = $_POST['p_name'];
        $template_id = $_POST['template_id'];
        $project_start = $_POST['start_date'];
        //Get project start date
        $dateformat = $current_user->getPreference('datef');
        $startdate = DateTime::createFromFormat($dateformat, $project_start);
        $start = $startdate->format('Y-m-d');

        $duration_unit = 'Days';


        //$GLOBALS['log']->fatal("name:". $project_name." id:".$template_id);

        //Get the project template
        $template = new AM_ProjectTemplates();
        $template->retrieve($template_id);


        //create project from template
        $project = new Project();
        $project->name = $project_name;
        $project->estimated_start_date = $start;
        $project->status = $template->status;
        $project->priority = $template->priority;
        $project->description = $template->description;
        $project->assigned_user_id = $template->assigned_user_id;
        $project->save();

        $template->load_relationship('am_projecttemplates_project_1');
        $template->am_projecttemplates_project_1->add($project->id);

		/* #LS - check if there is more than one task with same order_number => this means each should have the same date_start */
		/* se il nuovo ordine non è superiore all'ordine precedente, allora non incrementare date_start */
		
        //Get related project template tasks. Using sql query so that the results can be ordered.
        $get_tasks = "SELECT * FROM am_tasktemplates
                        WHERE id
                        IN (
                            SELECT am_tasktemplates_am_projecttemplatesam_tasktemplates_idb
                            FROM am_tasktemplates_am_projecttemplates_c
                            WHERE am_tasktemplates_am_projecttemplatesam_projecttemplates_ida = '".$template_id."'
                            AND deleted =0
                        )
                        AND deleted =0
                        ORDER BY am_tasktemplates.order_number ASC";
        $tasks = $db->query($get_tasks);
        //Create new project tasks from the template tasks
        $count=1;
        while($row = $db->fetchByAssoc($tasks))
        {
            $project_task = new ProjectTask();
            $project_task->name = $row['name'];
            $project_task->status = $row['status'];
            $project_task->priority = $row['priority'];
            $project_task->percent_complete = $row['percent_complete'];
            $project_task->predecessors = $row['predecessors']; 
            $project_task->milestone_flag = $row['milestone_flag'];
            $project_task->relationship_type = $row['relationship_type'];
            $project_task->task_number = $row['task_number'];
            $project_task->order_number = $row['order_number'];
            $project_task->estimated_effort = $row['estimated_effort'];
            $project_task->utilization = $row['utilization'];
            $project_task->assigned_user_id = $row['assigned_user_id'];
            $project_task->description = $row['description'];
            $project_task->duration = $row['duration'];
			/* #LS - set duration_unit as default = "Days" */
			$project_task->duration_unit = $duration_unit;
			
            $project_task->project_task_id = $count;
            //Flag to prevent after save logichook running when project_tasks are created (see custom/modules/ProjectTask/updateProject.php)
            $project_task->set_project_end_date = 0;

            if($count == '1'){
                $project_task->date_start = $start;
               
				/* #LS - if duration = 1 Day then: Date Finish = Date Start */
				if ($row['duration']== 1){
					$project_task->date_finish = $start;
					$enddate = $startdate;
				}//if
				else{
					$project_task->date_finish = $end;
					$enddate = $startdate->modify('+'.$row['duration'].' '.$duration_unit);
					
				}
				$end = $enddate->format('Y-m-d');
				
				/* #LS - oldorder */
				$oldorder = $project_task->order_number;
				
                $enddate_array[$count] = $end;
				$startdate_array[$count] = $start;
                $GLOBALS['log']->fatal("Data Inizio: ".$start." DATA FINE: ".$end."<BR>");
            }
            else {
				
				/* #LS - if the order_number hasn't been increased, so it's still the same as in previous */
                if ($oldorder == $project_task->order_number){
					$id_start_date = $count - 1;
					//$GLOBALS['log']->fatal("id_start_date=".$id_start_date." enddate_array[".$id_start_date."]:". $enddate_array[$id_start_date]);
					
					
					$startdate = DateTime::createFromFormat('Y-m-d', $startdate_array[$id_start_date]);
					
					$start = $startdate->format('Y-m-d');
					$project_task->date_start = $start;
					
					$enddate = $startdate->modify('+'.$row['duration'].' '.$duration_unit);
					$end = $enddate->format('Y-m-d');
					/* #LS - if duration = 1 Days Then: Date Finish = Date Start */
					if ($row['duration']== 1)
						$project_task->date_finish = $start;
					else
						$project_task->date_finish = $end;
					$enddate = $end;
					$enddate_array[$count] = $end;
					$startdate_array[$count] = $start;	
					$oldorder=$project_task->order_number;
					$GLOBALS['log']->fatal("Data Inizio: ".$start." DATA FINE: ".$end."<BR>");
				}//if oldorder not increased
				
				else{
					
					
				$id_start_date = $count - 1;
                $startdate = DateTime::createFromFormat('Y-m-d', $enddate_array[$id_start_date]);
                //$GLOBALS['log']->fatal("DATE:". $enddate_array[$id_start_date]);
                $start = $startdate->format('Y-m-d');
                $project_task->date_start = $start;
                
				$enddate = $startdate->modify('+'.$row['duration'].' '.$duration_unit);
                $end = $enddate->format('Y-m-d');
                /* #LS - if duration = 1 Days Then: Date Finish = Date Start */
				if ($row['duration']== 1)
					$project_task->date_finish = $start;
				else
					$project_task->date_finish = $end;
                $enddate = $end;
                $enddate_array[$count] = $end;
				$startdate_array[$count] = $start;
				
				$oldorder=$project_task->order_number;
				}//else order_number increased
				$GLOBALS['log']->fatal("Data Inizio: ".$start." DATA FINE: ".$end."<BR>");
            }
            $project_task->save();
            //link tasks to the newly created project
            $project_task->load_relationship('projects');
            $project_task->projects->add($project->id);
            //Add assigned users from each task to the project resourses subpanel
            $project->load_relationship('project_users_1');
            $project->project_users_1->add($row['assigned_user_id']);
            $count++;
        }
        //set project end date to the same as end date of the last task
        $project->estimated_end_date = $end;
        $project->save();


        //redirect to new project
        SugarApplication::appendErrorMessage('New project created.');
        $params = array(
            'module'=> 'Project',
            'action'=>'DetailView',
            'record' => $project->id,
        );
        SugarApplication::redirect('index.php?' . http_build_query($params));
    }

}

Hi,

i went on a little bit, i assumed order_number as tree level, and i considered tasks of the same duration in each order_number,

<?php


if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class AM_ProjectTemplatesController extends SugarController {

    function action_create_project(){

        global $current_user, $db;

        $project_name = $_POST['p_name'];
        $template_id = $_POST['template_id'];
        $project_start = $_POST['start_date'];
        //Get project start date
        $dateformat = $current_user->getPreference('datef');
        $startdate = DateTime::createFromFormat($dateformat, $project_start);
        $start = $startdate->format('Y-m-d');

        $duration_unit = 'Days';


        //$GLOBALS['log']->fatal("name:". $project_name." id:".$template_id);

        //Get the project template
        $template = new AM_ProjectTemplates();
        $template->retrieve($template_id);


        //create project from template
        $project = new Project();
        $project->name = $project_name;
        $project->estimated_start_date = $start;
        $project->status = $template->status;
        $project->priority = $template->priority;
        $project->description = $template->description;
        $project->assigned_user_id = $template->assigned_user_id;
        $project->save();

        $template->load_relationship('am_projecttemplates_project_1');
        $template->am_projecttemplates_project_1->add($project->id);

		/* #LS - check if there is more than one task with same order_number => this means each should have the same date_start */
		/* se il nuovo ordine non è superiore all'ordine precedente, allora non incrementare date_start */
		
        //Get related project template tasks. Using sql query so that the results can be ordered.
        $get_tasks = "SELECT * FROM am_tasktemplates
                        WHERE id
                        IN (
                            SELECT am_tasktemplates_am_projecttemplatesam_tasktemplates_idb
                            FROM am_tasktemplates_am_projecttemplates_c
                            WHERE am_tasktemplates_am_projecttemplatesam_projecttemplates_ida = '".$template_id."'
                            AND deleted =0
                        )
                        AND deleted =0
                        ORDER BY am_tasktemplates.order_number ASC";
        $tasks = $db->query($get_tasks);
        //Create new project tasks from the template tasks
        $count=1;
        while($row = $db->fetchByAssoc($tasks))
        {
            $project_task = new ProjectTask();
            $project_task->name = $row['name'];
            $project_task->status = $row['status'];
            $project_task->priority = $row['priority'];
            $project_task->percent_complete = $row['percent_complete'];
            $project_task->predecessors = $row['predecessors']; 
            $project_task->milestone_flag = $row['milestone_flag'];
            $project_task->relationship_type = $row['relationship_type'];
            $project_task->task_number = $row['task_number'];
            $project_task->order_number = $row['order_number'];
            $project_task->estimated_effort = $row['estimated_effort'];
            $project_task->utilization = $row['utilization'];
            $project_task->assigned_user_id = $row['assigned_user_id'];
            $project_task->description = $row['description'];
            $project_task->duration = $row['duration'];
			/* #LS - set duration_unit as default = "Days" */
			$project_task->duration_unit = $duration_unit;
			
            $project_task->project_task_id = $count;
            //Flag to prevent after save logichook running when project_tasks are created (see custom/modules/ProjectTask/updateProject.php)
            $project_task->set_project_end_date = 0;

            if($count == '1'){
                $project_task->date_start = $start;
               
				/* #LS - if duration = 1 Day then: Date Finish = Date Start */
				if ($row['duration']== 1){
					$project_task->date_finish = $start;
					$enddate = $startdate;
				}//if
				else{
					$project_task->date_finish = $end;
					$enddate = $startdate->modify('+'.$row['duration'].' '.$duration_unit);
					
				}
				$end = $enddate->format('Y-m-d');
				
				/* #LS - oldorder */
				$oldorder = $project_task->order_number;
				
                $enddate_array[$count] = $end;
				$startdate_array[$count] = $start;
                $GLOBALS['log']->fatal("Data Inizio: ".$start." DATA FINE: ".$end."<BR>");
            }
            else { /* Next steps */
				$id_start_date = $count - 1;
				
                if ($oldorder == $project_task->order_number){	/* #LS - if the order_number hasn't been increased, so it's still the same as in previous */	
					$startdate = DateTime::createFromFormat('Y-m-d', $startdate_array[$id_start_date]);				
				}//if oldorder not increased
				
				else{ 											/* #LS - else the order_number has been increased */
					
					$startdate = DateTime::createFromFormat('Y-m-d', $enddate_array[$id_start_date]);
					$startdate = $startdate->modify('+1'.$duration_unit);
				}//else order_number increased
				
				
				$start = $startdate->format('Y-m-d');
				$project_task->date_start = $start;
				
				
				
				
				/* #LS - if duration = 1 Days Then: Date Finish = Date Start */
				if ($row['duration']== 1){
					$project_task->date_finish = $start;
					$enddate = $startdate;
					$end = $enddate->format('Y-m-d');
				}
				else{
					
					$shift=$row['duration']-1;
					$enddate = $startdate->modify('+'.$shift.' '.$duration_unit);
					$end = $enddate->format('Y-m-d');
					$project_task->date_finish = $end;
				}
				
				//$enddate = $end;
				$enddate_array[$count] = $end;
				$startdate_array[$count] = $start;	
				$oldorder=$project_task->order_number;
				$GLOBALS['log']->fatal("Data Inizio: ".$start." DATA FINE: ".$end."<BR>");
					
            }
            $project_task->save();
            //link tasks to the newly created project
            $project_task->load_relationship('projects');
            $project_task->projects->add($project->id);
            //Add assigned users from each task to the project resourses subpanel
            $project->load_relationship('project_users_1');
            $project->project_users_1->add($row['assigned_user_id']);
            $count++;
        }
        //set project end date to the same as end date of the last task
        $project->estimated_end_date = $end;
        $project->save();


        //redirect to new project
        SugarApplication::appendErrorMessage('New project created.');
        $params = array(
            'module'=> 'Project',
            'action'=>'DetailView',
            'record' => $project->id,
        );
        SugarApplication::redirect('index.php?' . http_build_query($params));
    }

}

This gave me starting from this:


that represents this flow:


this kind of results (Gantt view)

1 Like

Looks very nice. You achieved this just by adding the above code?