/** Import tasks from another project * * @param int Project ID of the tasks come from. * @return bool **/ function importTasks($from_project_id, $scale_project = false) { // Load the original $origProject = new CProject(); $origProject->load($from_project_id); $q = new DBQuery(); $q->addTable('tasks'); $q->addQuery('task_id'); $q->addWhere('task_project =' . $from_project_id); $sql = $q->prepare(); $q->clear(); $tasks = array_flip(db_loadColumn($sql)); //Pristine Start and End Dates of Source and Destination Projects $origStartDate = new CDate($origProject->project_start_date); $origEndDate = new CDate($origProject->project_end_date); $destStartDate = new CDate($this->project_start_date); $destEndDate = new CDate($this->project_end_date); $dateOffset = $destStartDate->dateDiff($origStartDate); //Check that we have enough information to scale properly //(i.e. no information is missing or "zero") if (empty($origProject->project_start_date) || empty($origProject->project_end_date) || empty($this->project_start_date) || empty($this->project_end_date) || $origProject->project_start_date == '0000-00-00 00:00:00' || $origProject->project_end_date == '0000-00-00 00:00:00' || $this->project_start_date == '0000-00-00 00:00:00' || $this->project_end_date == '0000-00-00 00:00:00') { $scale_project = false; } if ($scale_project) { //get ratio for scaling, protect from division by 0 $ratio = (abs($destEndDate->dateDiff($destStartDate)) + 1) / (abs($origEndDate->dateDiff($origStartDate)) + 1); } // Old dependencies array from imported tasks $deps = array(); // New dependencies array for new copies of imported tasks $newDeps = array(); // Old2New task ID array $taskXref = array(); // New task ID to old parent array $nid2op = array(); // Copy each task into this project and get their deps foreach ($tasks as $orig => $void) { $objTask = new CTask(); $objTask->load($orig); // Grab the old parent id $oldParent = (int) $objTask->task_parent; $deps[$orig] = $objTask->getDependencies(); $destTask = $objTask->copy($this->project_id, 0); $nid2op[$destTask->task_id] = $oldParent; $tasks[$orig] = $destTask; $taskXref[$orig] = (int) $destTask->task_id; } // Build new dependencies array foreach ($deps as $odkey => $od) { $ndt = ''; $ndkey = $taskXref[$odkey]; $odep = explode(',', $od); foreach ($odep as $odt) { $ndt = $ndt . $taskXref[$odt] . ','; } $ndt = rtrim($ndt, ','); $newDeps[$ndkey] = $ndt; } $q->addTable('tasks'); $q->addQuery('task_id'); $q->addWhere('task_project =' . $this->project_id); $tasks = $q->loadColumn(); // Update dates based on new project's start date. $origDate = new CDate($origProject->project_start_date); $origStartHour = new CDate($this->project_start_date); $destDate = new CDate($this->project_start_date); foreach ($tasks as $task_id) { $newTask = new CTask(); $newTask->load($task_id); if (in_array($task_id, $taskXref)) { $task_date_vars = array('task_start_date', 'task_end_date'); //Adjust task dates based on calculated offsets foreach ($task_date_vars as $my_date) { if (!empty($newTask->{$my_date}) && $newTask->{$my_date} != '0000-00-00 00:00:00') { $origDate->setDate($newTask->{$my_date}); $origStartHour->setDate($newTask->{$my_date}); $origStartHour->setTime(intval(dPgetConfig('cal_day_start'))); $destDate->setDate($newTask->{$my_date}); $destDate->addDays($dateOffset); if ($scale_project) { $offsetAdd = round($origDate->dateDiff($origStartDate) * $ratio) - $origDate->dateDiff($origStartDate); $destDate->addDays($offsetAdd); $hours_in = $origStartHour->calcDuration($origDate); $offsetAddHours = round($hours_in * $ratio) - $hours_in; if ($offsetAddHours % dPgetConfig('daily_working_hours')) { $destDate->addDuration($offsetAddHours); } } $destDate = $destDate->next_working_day(); $newTask->{$my_date} = $destDate->format(FMT_DATETIME_MYSQL); } } //Adjust durration to scale if ($scale_project) { $newTask->task_duration = round($newTask->task_duration * $ratio, 2); } $newTask->task_parent = $taskXref[$nid2op[$newTask->task_id]]; $newTask->store(); $newTask->updateDependencies($newDeps[$task_id]); } // end check if imported task $newTask->store(); } // end Fix record integrity }
function update_dep_dates($task_id) { global $tracking_dynamics; $q = new DBQuery(); $newTask = new CTask(); $newTask->load($task_id); // Do not update tasks that are not tracking dependencies if (!in_array($newTask->task_dynamic, $tracking_dynamics)) { return; } // load original task dates and calculate task time span $tsd = new CDate($newTask->task_start_date); $ted = new CDate($newTask->task_end_date); $duration = $tsd->calcDuration($ted); // reset start date $nsd = new CDate($newTask->get_deps_max_end_date($newTask)); // prefer Wed 8:00 over Tue 16:00 as start date $nsd = $nsd->next_working_day(); $new_start_date = $nsd->format(FMT_DATETIME_MYSQL); // Add task time span to End Date again $ned = new CDate(); $ned->copy($nsd); $ned->addDuration($duration, '1'); // make sure one didn't land on a non-working day $ned = $ned->next_working_day(true); // prefer tue 16:00 over wed 8:00 as an end date $ned = $ned->prev_working_day(); $new_end_date = $ned->format(FMT_DATETIME_MYSQL); // update the db $q->addTable('tasks'); $q->addUpdate('task_start_date', $new_start_date); $q->addUpdate('task_end_date', $new_end_date); $q->addWhere('task_dynamic <> 1 AND task_id = ' . $task_id); $q->exec(); $q->clear(); if ($newTask->task_parent != $newTask->task_id) { $newTask->updateDynamics(); } return; }
// load already stored task data for this task $tempTask = new CTask(); $tempTask->load($obj->task_id); // shift new start date to the last dependency end date $nsd = new CDate($tempTask->get_deps_max_end_date($tempTask)); // prefer Wed 8:00 over Tue 16:00 as start date $nsd = $nsd->next_working_day(); // prepare the creation of the end date $ned = new CDate(); $ned->copy($nsd); if (empty($obj->task_start_date)) { // appropriately calculated end date via start+duration $ned->addDuration($obj->task_duration, $obj->task_duration_type); } else { // calc task time span start - end $d = $tsd->calcDuration($ted); // Re-add (keep) task time span for end date. // This is independent from $obj->task_duration. // The value returned by Date::Duration() is always in hours ('1') $ned->addDuration($d, '1'); } // prefer tue 16:00 over wed 8:00 as an end date $ned = $ned->prev_working_day(); $obj->task_start_date = $nsd->format(FMT_DATETIME_MYSQL); $obj->task_end_date = $ned->format(FMT_DATETIME_MYSQL); $q = new DBQuery(); $q->addTable('tasks', 't'); $q->addUpdate('task_start_date', $obj->task_start_date); $q->addUpdate('task_end_date', $obj->task_end_date); $q->addWhere('task_id = ' . (int) $obj->task_id); $q->addWhere('task_dynamic <> 1');