protected function _preCalcData() { $taskList = $this->obj->getAllowedTaskList(null, 1); foreach ($taskList as $item) { $tmpTask = new CTask(); $tmpTask->load($item['task_id']); if ($tmpTask->task_dynamic == 1) { $tmpTask->updateDynamics(true); $tmpTask->store(); } } }
/** * @todo Parent store could be partially used */ public function store(CAppUI $AppUI = null) { global $AppUI; $perms = $AppUI->acl(); $stored = false; $this->w2PTrimAll(); if (!$this->task_owner) { $this->task_owner = $AppUI->user_id; } $importing_tasks = false; $this->_error = $this->check(); if (count($this->_error)) { return $this->_error; } $this->task_target_budget = filterCurrency($this->task_target_budget); $q = new w2p_Database_Query(); $this->task_updated = $q->dbfnNowWithTZ(); if ($this->task_id && $perms->checkModuleItem('tasks', 'edit', $this->task_id)) { // Load and globalize the old, not yet updated task object // e.g. we need some info later to calculate the shifting time for depending tasks // see function update_dep_dates global $oTsk; $oTsk = new CTask(); $oTsk->load($this->task_id); if ($this->task_start_date == '') { $this->task_start_date = '0000-00-00 00:00:00'; } if ($this->task_end_date == '') { $this->task_end_date = '0000-00-00 00:00:00'; } if ($msg = parent::store()) { return $msg; } // if task_status changed, then update subtasks if ($this->task_status != $oTsk->task_status) { $this->updateSubTasksStatus($this->task_status); } // Moving this task to another project? if ($this->task_project != $oTsk->task_project) { $this->updateSubTasksProject($this->task_project); } if ($this->task_dynamic == 1) { $this->updateDynamics(true); } if ($msg = parent::store()) { return $msg; } // Milestone or task end date, or dynamic status has changed, // shift the dates of the tasks that depend on this task if ($this->task_end_date != $oTsk->task_end_date || $this->task_dynamic != $oTsk->task_dynamic || $this->task_milestone == '1') { $this->shiftDependentTasks(); } if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addUpdate('task_updated', "'" . $q->dbfnNowWithTZ() . "'", false, true); $q->addWhere('task_id = ' . (int) $this->task_id); $q->exec(); $q->clear(); } $stored = true; } if (0 == $this->task_id && $perms->checkModuleItem('tasks', 'add')) { $this->task_created = $q->dbfnNowWithTZ(); if ($this->task_start_date == '') { $this->task_start_date = '0000-00-00 00:00:00'; } if ($this->task_end_date == '') { $this->task_end_date = '0000-00-00 00:00:00'; } if ($msg = parent::store()) { return $msg; } $q->clear(); if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addUpdate('task_updated', "'" . $q->dbfnNowWithTZ() . "'", false, true); $q->addWhere('task_id = ' . (int) $this->task_id); $q->exec(); $q->clear(); } else { // importing tasks do not update dynamics $importing_tasks = true; } $stored = true; } $last_task_data = $this->getLastTaskData($this->task_project); CProject::updateTaskCache($this->task_project, $last_task_data['task_id'], $last_task_data['last_date'], $this->getTaskCount($this->task_project)); $this->pushDependencies($this->task_id, $this->task_end_date); //split out related departments and store them seperatly. $q->setDelete('task_departments'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); if (!empty($this->task_departments)) { $departments = explode(',', $this->task_departments); foreach ($departments as $department) { $q->addTable('task_departments'); $q->addInsert('task_id', $this->task_id); $q->addInsert('department_id', $department); $q->exec(); $q->clear(); } } //split out related contacts and store them seperatly. $q->setDelete('task_contacts'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); if ($this->task_contacts) { foreach ($this->task_contacts as $contact) { if ($contact) { $q->addTable('task_contacts'); $q->addInsert('task_id', $this->task_id); $q->addInsert('contact_id', $contact); $q->exec(); $q->clear(); } } } // if is child update parent task if ($this->task_parent && $this->task_parent != $this->task_id) { if (!$importing_tasks) { $this->updateDynamics(true); } $pTask = new CTask(); $pTask->load($this->task_parent); $pTask->updateDynamics(); if ($oTsk->task_parent != $this->task_parent) { $old_parent = new CTask(); $old_parent->load($oTsk->task_parent); $old_parent->updateDynamics(); } } // update dependencies if (!empty($this->task_id)) { $this->updateDependencies($this->getDependencies(), $this->task_parent); } return $stored; }
/** * @todo Parent store could be partially used */ function store() { global $AppUI; $q = new DBQuery(); $this->dPTrimAll(); $importing_tasks = false; $msg = $this->check(); if ($msg) { $return_msg = array(get_class($this) . '::store-check', 'failed', '-'); if (is_array($msg)) { return array_merge($return_msg, $msg); } else { array_push($return_msg, $msg); return $return_msg; } } if ($this->task_id) { addHistory('tasks', $this->task_id, 'update', $this->task_name, $this->task_project); $this->_action = 'updated'; // Load and globalize the old, not yet updated task object // e.g. we need some info later to calculate the shifting time for depending tasks // see function update_dep_dates global $oTsk; $oTsk = new CTask(); $oTsk->peek($this->task_id); // if task_status changed, then update subtasks if ($this->task_status != $oTsk->task_status) { $this->updateSubTasksStatus($this->task_status); } // Moving this task to another project? if ($this->task_project != $oTsk->task_project) { $this->updateSubTasksProject($this->task_project); } if ($this->task_dynamic == 1) { $this->updateDynamics(true); } // shiftDependentTasks needs this done first $this->check(); $ret = db_updateObject('tasks', $this, 'task_id', false); // Milestone or task end date, or dynamic status has changed, // shift the dates of the tasks that depend on this task if ($this->task_end_date != $oTsk->task_end_date || $this->task_dynamic != $oTsk->task_dynamic || $this->task_milestone == '1') { $this->shiftDependentTasks(); } } else { $this->_action = 'added'; if ($this->task_start_date == '') { $this->task_start_date = '0000-00-00 00:00:00'; } if ($this->task_end_date == '') { $this->task_end_date = '0000-00-00 00:00:00'; } $ret = db_insertObject('tasks', $this, 'task_id'); addHistory('tasks', $this->task_id, 'add', $this->task_name, $this->task_project); if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addWhere('task_id = ' . $this->task_id); $q->exec(); $q->clear(); } else { // importing tasks do not update dynamics $importing_tasks = true; } // insert entry in user tasks $q->addTable('user_tasks'); $q->addInsert('user_id', $AppUI->user_id); $q->addInsert('task_id', $this->task_id); $q->addInsert('user_type', '0'); $q->exec(); $q->clear(); } //split out related departments and store them seperatly. $q->setDelete('task_departments'); $q->addWhere('task_id=' . $this->task_id); $q->exec(); $q->clear(); // print_r($this->task_departments); if (!empty($this->task_departments)) { $departments = explode(',', $this->task_departments); foreach ($departments as $department) { $q->addTable('task_departments'); $q->addInsert('task_id', $this->task_id); $q->addInsert('department_id', $department); $q->exec(); $q->clear(); } } //split out related contacts and store them seperatly. $q->setDelete('task_contacts'); $q->addWhere('task_id=' . $this->task_id); $q->exec(); $q->clear(); if (!empty($this->task_contacts)) { $contacts = explode(',', $this->task_contacts); foreach ($contacts as $contact) { $q->addTable('task_contacts'); $q->addInsert('task_id', $this->task_id); $q->addInsert('contact_id', $contact); $q->exec(); $q->clear(); } } // if is child update parent task if ($this->task_parent != $this->task_id) { if (!$importing_tasks) { $this->updateDynamics(true); } $pTask = new CTask(); $pTask->load($this->task_parent); $pTask->updateDynamics(); if ($oTsk->task_parent != $this->task_parent) { $old_parent = new CTask(); $old_parent->load($oTsk->task_parent); $old_parent->updateDynamics(); } } // update dependencies if (!empty($this->task_id)) { $this->updateDependencies($this->getDependencies()); } else { // print_r($this); } if (!$ret) { return get_class($this) . '::store failed <br />' . db_error(); } else { return NULL; } }
/** * @todo Parent store could be partially used */ public function store(CAppUI $AppUI = null) { global $AppUI; $q = new DBQuery(); $this->w2PTrimAll(); $importing_tasks = false; $errorMsgArray = $this->check(); if (count($errorMsgArray) > 0) { return $errorMsgArray; } if ($this->task_id) { addHistory('tasks', $this->task_id, 'update', $this->task_name, $this->task_project); // Load and globalize the old, not yet updated task object // e.g. we need some info later to calculate the shifting time for depending tasks // see function update_dep_dates global $oTsk; $oTsk = new CTask(); $oTsk->peek($this->task_id); $this->task_updated = $q->dbfnNow(); if ($this->task_start_date == '') { $this->task_start_date = '0000-00-00 00:00:00'; } if ($this->task_end_date == '') { $this->task_end_date = '0000-00-00 00:00:00'; } $ret = $q->updateObject('tasks', $this, 'task_id'); $q->clear(); $this->_action = 'updated'; // if task_status changed, then update subtasks if ($this->task_status != $oTsk->task_status) { $this->updateSubTasksStatus($this->task_status); } // Moving this task to another project? if ($this->task_project != $oTsk->task_project) { $this->updateSubTasksProject($this->task_project); } if ($this->task_dynamic == 1) { $this->updateDynamics(true); } // shiftDependentTasks needs this done first $this->check(); $ret = $q->updateObject('tasks', $this, 'task_id', false); $q->clear(); // Milestone or task end date, or dynamic status has changed, // shift the dates of the tasks that depend on this task if ($this->task_end_date != $oTsk->task_end_date || $this->task_dynamic != $oTsk->task_dynamic || $this->task_milestone == '1') { $this->shiftDependentTasks(); } if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addUpdate('task_updated', $this->dbfnNow(), false, true); $q->addWhere('task_id = ' . (int) $this->task_id); $q->exec(); $q->clear(); } } else { $this->_action = 'added'; $this->task_updated = $q->dbfnNow(); $this->task_created = $q->dbfnNow(); if ($this->task_start_date == '') { $this->task_start_date = '0000-00-00 00:00:00'; } if ($this->task_end_date == '') { $this->task_end_date = '0000-00-00 00:00:00'; } $ret = $q->insertObject('tasks', $this, 'task_id'); $this->task_id = db_insert_id(); $q->clear(); addHistory('tasks', $this->task_id, 'add', $this->task_name, $this->task_project); if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addUpdate('task_updated', $q->dbfnNow(), false, true); $q->addWhere('task_id = ' . (int) $this->task_id); $q->exec(); $q->clear(); } else { // importing tasks do not update dynamics $importing_tasks = true; } } CProject::updateTaskCount($this->task_project, $this->getTaskCount($this->task_project)); $this->pushDependencies($this->task_id, $this->task_end_date); //split out related departments and store them seperatly. $q->setDelete('task_departments'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); // print_r($this->task_departments); if (!empty($this->task_departments)) { $departments = explode(',', $this->task_departments); foreach ($departments as $department) { $q->addTable('task_departments'); $q->addInsert('task_id', $this->task_id); $q->addInsert('department_id', $department); $q->exec(); $q->clear(); } } //split out related contacts and store them seperatly. $q->setDelete('task_contacts'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); if (!empty($this->task_contacts)) { $contacts = explode(',', $this->task_contacts); foreach ($contacts as $contact) { $q->addTable('task_contacts'); $q->addInsert('task_id', $this->task_id); $q->addInsert('contact_id', $contact); $q->exec(); $q->clear(); } } // if is child update parent task if ($this->task_parent != $this->task_id) { if (!$importing_tasks) { $this->updateDynamics(true); } $pTask = new CTask(); $pTask->load($this->task_parent); $pTask->updateDynamics(); if ($oTsk->task_parent != $this->task_parent) { $old_parent = new CTask(); $old_parent->load($oTsk->task_parent); $old_parent->updateDynamics(); } } // update dependencies if (!empty($this->task_id)) { $this->updateDependencies($this->getDependencies()); } else { print_r($this); } if (!$ret) { return false; } else { return true; } }
/** * Post Request Handler * * This method is called when a request is a POST * * @return array */ public function executePost() { /** * @todo Remove this once we figure out how to reference vars in file * that is autoloaded */ global $tracking_dynamics; $valid = $this->hasRequiredParameters($this->requiredParams); if ($valid instanceof Frapi_Error) { return $valid; } $username = $this->getParam('username'); $password = $this->getParam('password'); $project_id = $this->getParam('project_id', self::TYPE_INT); $hassign = $this->getParam('hassign'); $hdependencies = $this->getParam('hdependencies'); $notify = $this->getParam('task_notify'); $comment = $this->getParam('email_comment'); $task_id = $this->getParam('task_id'); $adjustStartDate = $this->getParam('set_task_start_date'); $task = new CTask(); // Attempt to login as user, a little bit of a hack as we currently // require the $_POST['login'] var to be set as well as a global AppUI $AppUI = new CAppUI(); $GLOBALS['AppUI'] = $AppUI; $_POST['login'] = '******'; if (!$AppUI->login($username, $password)) { throw new Frapi_Error('INVALID_LOGIN'); } $post_data = array('task_id' => $this->getParam('task_id'), 'task_name' => $this->getParam('task_name'), 'task_status' => $this->getParam('task_status'), 'task_percent_complete' => $this->getParam('task_percent_complete'), 'task_milestone' => $this->getParam('task_milestone'), 'task_owner' => $this->getParam('task_owner'), 'task_access' => $this->getParam('task_access'), 'task_related_url' => $this->getParam('task_related_url'), 'task_parent' => $this->getParam('task_parent'), 'task_type' => $this->getParam('task_type'), 'task_target_budget' => $this->getParam('task_target_budget'), 'task_description' => $this->getParam('task_description'), 'task_start_date' => $this->getParam('task_start_date'), 'task_end_date' => $this->getParam('task_end_date'), 'task_duration' => $this->getParam('task_duration'), 'task_duration_type' => $this->getParam('task_duration_type'), 'task_dynamic' => $this->getParam('task_dynamic'), 'task_allow_other_user_tasklogs' => $this->getParam('task_allow_other_user_tasklogs'), 'task_project' => $this->getParam('task_project'), 'task_priority' => $this->getParam('task_priority')); // Include any files for handling module-specific requirements foreach (findTabModules('tasks', 'addedit') as $mod) { $fname = W2P_BASE_DIR . '/modules/' . $mod . '/tasks_dosql.addedit.php'; if (file_exists($fname)) { require_once $fname; } } // Find the task if we are set $task_end_date = null; if ($task_id) { $task->load($task_id); $task_end_date = new w2p_Utilities_Date($task->task_end_date); } $task = new CTask(); if (!$task->bind($post_data)) { throw new Frapi_Error('SAVE_ERROR', $task->getError()); } if ($task->task_dynamic != 1) { $task_dynamic_delay = $this->getParam('task_dynamic_nodelay') ? $this->getParam('task_dynamic_nodelay') : '0'; if (in_array($task->task_dynamic, $tracking_dynamics)) { $task->task_dynamic = $task_dynamic_delay ? 21 : 31; } else { $task->task_dynamic = $task_dynamic_delay ? 11 : 0; } } // Let's check if task_dynamic is unchecked if (!$this->getParam('task_dynamic')) { $task->task_dynamic = false; } // Make sure task milestone is set or reset as appropriate if ($this->getParam('task_milestone')) { $task->task_milestone = false; } //format hperc_assign user_id=percentage_assignment;user_id=percentage_assignment;user_id=percentage_assignment; $tmp_ar = explode(';', $this->getParam('hperc_assign')); $i_cmp = sizeof($tmp_ar); $hperc_assign_ar = array(); for ($i = 0; $i < $i_cmp; $i++) { $tmp = explode('=', $tmp_ar[$i]); if (count($tmp) > 1) { $hperc_assign_ar[$tmp[0]] = $tmp[1]; } elseif ($tmp[0] != '') { $hperc_assign_ar[$tmp[0]] = 100; } } // let's check if there are some assigned departments to task $task->task_departments = implode(',', $this->getParam('dept_ids', self::TYPE_ARRAY)); // convert dates to SQL format first if ($task->task_start_date) { $date = new w2p_Utilities_Date($task->task_start_date); $task->task_start_date = $date->format(FMT_DATETIME_MYSQL); } $end_date = null; if ($task->task_end_date) { if (strpos($task->task_end_date, '2400') !== false) { $task->task_end_date = str_replace('2400', '2359', $task->task_end_date); } $end_date = new w2p_Utilities_Date($task->task_end_date); $task->task_end_date = $end_date->format(FMT_DATETIME_MYSQL); } $error_array = $task->store($AppUI); // Return all the validation messages if ($error_array !== true) { $error_message = ''; foreach ($error_array as $error) { $error_message .= $error . '. '; } throw new Frapi_Error('SAVE_ERROR', $error_message); } $task_parent = $this->getParam('task_parent') ? $this->getParam('task_parent', SELF::TYPE_INT) : 0; $old_task_parent = $this->getParam('old_task_parent') ? $this->getParam('old_task_parent', SELF::TYPE_INT) : 0; if ($task_parent != $old_task_parent) { $oldTask = new CTask(); $oldTask->load($old_task_parent); $oldTask->updateDynamics(false); } // How to handle custom fields? Do we support it in api? // Now add any task reminders // If there wasn't a task, but there is one now, and // that task date is set, we need to set a reminder. if (empty($task_end_date) || !empty($end_date) && $task_end_date->dateDiff($end_date)) { $task->addReminder(); } if (isset($hassign)) { $task->updateAssigned($hassign, $hperc_assign_ar); } if (isset($hdependencies)) { // && !empty($hdependencies)) { // there are dependencies set! // backup initial start and end dates $tsd = new w2p_Utilities_Date($task->task_start_date); $ted = new w2p_Utilities_Date($task->task_end_date); // updating the table recording the // dependency relations with this task $task->updateDependencies($hdependencies, $task_parent); // we will reset the task's start date based upon dependencies // and shift the end date appropriately if ($adjustStartDate && !is_null($hdependencies)) { // load already stored task data for this task $tempTask = new CTask(); $tempTask->load($task->task_id); // shift new start date to the last dependency end date $nsd = new w2p_Utilities_Date($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 w2p_Utilities_Date(); $ned->copy($nsd); if (empty($task->task_start_date)) { // appropriately calculated end date via start+duration $ned->addDuration($task->task_duration, $task->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(); $task->task_start_date = $nsd->format(FMT_DATETIME_MYSQL); $task->task_end_date = $ned->format(FMT_DATETIME_MYSQL); $q = new w2p_Database_Query(); $q->addTable('tasks', 't'); $q->addUpdate('task_start_date', $task->task_start_date); $q->addUpdate('task_end_date', $task->task_end_date); $q->addWhere('task_id = ' . (int) $task->task_id); $q->addWhere('task_dynamic <> 1'); $q->exec(); $q->clear(); } $task->pushDependencies($task->task_id, $task->task_end_date); } //$task = (array)$task; $task->load($task_id); unset($task->_query, $task->_error, $task->_tbl_prefix, $task->_tbl, $task->_tbl_key, $task->_tbl_module); $this->data['task'] = $task; $this->data['success'] = true; return $this->toArray(); }
$myTask = new CTask(); CProject::updateTaskCount($taskRecount, $myTask->getTaskCount($taskRecount)); } //$obj->task_project if (is_array($result)) { $AppUI->setMsg($result, UI_MSG_ERROR, true); $AppUI->holdObject($obj); $AppUI->redirect('m=tasks&a=addedit'); } if ($result) { $task_parent = (int) w2PgetParam($_POST, 'task_parent', 0); $old_task_parent = (int) w2PgetParam($_POST, 'old_task_parent', 0); if ($task_parent != $old_task_parent) { $oldTask = new CTask(); $oldTask->load($old_task_parent); $oldTask->updateDynamics(false); } $custom_fields = new CustomFields($m, 'addedit', $obj->task_id, 'edit'); $custom_fields->bind($_POST); $sql = $custom_fields->store($obj->task_id); // Store Custom Fields // Now add any task reminders // If there wasn't a task, but there is one now, and // that task date is set, we need to set a reminder. if (empty($task_end_date) || !empty($end_date) && $task_end_date->dateDiff($end_date)) { $obj->addReminder(); } $AppUI->setMsg($task_id ? 'Task updated' : 'Task added', UI_MSG_OK); if (isset($hassign)) { $obj->updateAssigned($hassign, $hperc_assign_ar); }
protected function hook_postStore() { // TODO $oTsk is a global set by store() and is the task before update. // Using it here as a global is probably a bad idea, but the only way until the old task is stored somewhere // else than a global variable... global $oTsk; $q = $this->_query; /* * TODO: I don't like that we have to run an update immediately after the store * but I don't have a better solution at the moment. * ~ caseydk 2012 Aug 04 */ if (!$this->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $this->task_id); $q->addUpdate('task_updated', "'" . $q->dbfnNowWithTZ() . "'", false, true); $q->addWhere('task_id = ' . (int) $this->task_id); $q->exec(); $q->clear(); } // update dependencies if (!empty($this->task_id)) { $this->updateDependencies($this->getDependencies(), $this->task_parent); } $this->pushDependencies($this->task_id, $this->task_end_date); //split out related departments and store them seperatly. $q->setDelete('task_departments'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); if (!empty($this->task_departments)) { $departments = explode(',', $this->task_departments); foreach ($departments as $department) { $q->addTable('task_departments'); $q->addInsert('task_id', $this->task_id); $q->addInsert('department_id', $department); $q->exec(); $q->clear(); } } //split out related contacts and store them seperatly. $q->setDelete('task_contacts'); $q->addWhere('task_id=' . (int) $this->task_id); $q->exec(); $q->clear(); if ($this->task_contacts && is_array($this->task_contacts)) { foreach ($this->task_contacts as $contact) { if ($contact) { $q->addTable('task_contacts'); $q->addInsert('task_id', $this->task_id); $q->addInsert('contact_id', $contact); $q->exec(); $q->clear(); } } } // if is child update parent task if ($this->task_parent != $this->task_id) { if (!$this->importing_tasks) { $this->updateDynamics(); } if ($oTsk->task_parent != $this->task_parent) { $old_parent = new CTask(); $old_parent->overrideDatabase($this->_query); $old_parent->load($oTsk->task_parent); $old_parent->updateDynamics(); } } $this->_updatePathEnumeration(); $this->updateDynamics(); $last_task_data = $this->getLastTaskData($this->task_project); CProject::updateTaskCache($this->task_project, $this->task_id, $last_task_data['last_date'], $this->getTaskCount($this->task_project)); parent::hook_postStore(); }
/** * Import tasks from another project * * @param int Project ID of the tasks come from. * @return bool * * @todo - this entire thing has nothing to do with projects.. it should move to the CTask class - dkc 25 Nov 2012 * @todo - why are we returning either an array or a boolean? You make my head hurt. - dkc 25 Nov 2012 * * @todo - we should decide if we want to include the contacts associated with each task * @todo - we should decide if we want to include the files associated with each task * @todo - we should decide if we want to include the links associated with each task * * Of the three - contacts, files, and links - I can see a case made for * all three. Imagine you have a task which requires a particular form to * be filled out (Files) but there's also documentation you need about it * (Links) and once the task is underway, you need to let some people * know (Contacts). - dkc 25 Nov 2012 * */ public function importTasks($from_project_id, $to_project_id, $project_start_date) { $errors = array(); $old_new_task_mapping = array(); $old_dependencies = array(); $old_parents = array(); $project_start_date = new w2p_Utilities_Date($project_start_date); $newTask = new w2p_Actions_BulkTasks(); $task_list = $newTask->loadAll('task_start_date', "task_represents_project = 0 AND task_project = " . $from_project_id); $first_task = array_shift($task_list); /** * This gets the first (earliest) task start date and figures out * how much we have to shift all the tasks by. */ $original_start_date = new w2p_Utilities_Date($first_task['task_start_date']); $timeOffset = $original_start_date->dateDiff($project_start_date); array_unshift($task_list, $first_task); foreach ($task_list as $orig_task) { $orig_id = $orig_task['task_id']; $new_start_date = new w2p_Utilities_Date($orig_task['task_start_date']); $new_start_date->addDays($timeOffset); $new_end_date = new w2p_Utilities_Date($orig_task['task_end_date']); $new_end_date->addDays($timeOffset); $old_parents[$orig_id] = $orig_task['task_parent']; $orig_task['task_id'] = 0; $orig_task['task_parent'] = 0; $orig_task['task_project'] = $to_project_id; $orig_task['task_sequence'] = 0; $orig_task['task_path_enumeration'] = ''; $orig_task['task_hours_worked'] = 0; // This is necessary because we're using bind() and it shifts by timezone $orig_task['task_start_date'] = $this->_AppUI->formatTZAwareTime($new_start_date->format(FMT_DATETIME_MYSQL), '%Y-%m-%d %T'); $orig_task['task_end_date'] = $this->_AppUI->formatTZAwareTime($new_end_date->format(FMT_DATETIME_MYSQL), '%Y-%m-%d %T'); $_newTask = new w2p_Actions_BulkTasks(); $_newTask->bind($orig_task); $_newTask->store(); $task_map[$orig_id] = $_newTask->task_id; $old_dependencies[$orig_id] = array_keys($_newTask->getDependentTaskList($orig_id)); $old_new_task_mapping[$orig_id] = $_newTask->task_id; } if (count($errors)) { $this->_error = $errors; foreach ($old_new_task_mapping as $new_id) { $newTask->task_id = $new_id; $newTask->delete(); } } else { $q = $this->_getQuery(); /* This makes sure we have all the dependencies mapped out. */ foreach ($old_dependencies as $from => $to_array) { foreach ($to_array as $to) { $q->addTable('task_dependencies'); $q->addInsert('dependencies_req_task_id', $old_new_task_mapping[$from]); $q->addInsert('dependencies_task_id', $old_new_task_mapping[$to]); $q->exec(); $q->clear(); } } /* This makes sure all the parents are connected properly. */ foreach ($old_parents as $old_child => $old_parent) { if ($old_child == $old_parent) { /** Remember, this means skip the rest of the loop. */ continue; } $q->addTable('tasks'); $q->addUpdate('task_parent', $old_new_task_mapping[$old_parent]); $q->addWhere('task_id = ' . $old_new_task_mapping[$old_child]); $q->exec(); $q->clear(); } /* This copies the task assigness to the new tasks. */ foreach ($old_new_task_mapping as $old_id => $new_id) { $newTask->task_id = $old_id; $newTask->copyAssignedUsers($new_id); } } $_task = new CTask(); $task_list = $_task->loadAll('task_parent, task_id', "task_project = " . $to_project_id); foreach ($task_list as $key => $data) { $_task->load($key); $_task->_updatePathEnumeration(); if (!$_task->task_parent) { $q->addTable('tasks'); $q->addUpdate('task_parent', $_task->task_id); $q->addUpdate('task_updated', "'" . $q->dbfnNowWithTZ() . "'", false, true); $q->addWhere('task_id = ' . (int) $_task->task_id); $q->exec(); $q->clear(); } } $_task->updateDynamics(); $last_task_data = $this->getLastTaskData($to_project_id); CProject::updateTaskCache($to_project_id, $last_task_data['task_id'], $last_task_data['last_date'], $this->getTaskCount($to_project_id)); return $errors; }
/** * @todo Parent store could be partially used */ function store() { global $AppUI; $importing_tasks = false; $msg = $this->check(); if ($msg) { $return_msg = array(get_class($this) . '::store-check', 'failed', '-'); if (is_array($msg)) { return array_merge($return_msg, $msg); } else { array_push($return_msg, $msg); return $return_msg; } } if ($this->task_id) { addHistory('tasks', $this->task_id, 'update', $this->task_name, $this->task_project); $this->_action = 'updated'; // Load the old task from disk $oTsk = new CTask(); $oTsk->load($this->task_id); // if task_status changed, then update subtasks if ($this->task_status != $oTsk->task_status) { $this->updateSubTasksStatus($this->task_status); } // Moving this task to another project? if ($this->task_project != $oTsk->task_project) { $this->updateSubTasksProject($this->task_project); } if ($this->task_dynamic == '1') { $this->updateDynamics(true); } // shiftDependentTasks needs this done first $ret = db_updateObject('tasks', $this, 'task_id', false); // Milestone or task end date, or dynamic status has changed, // shift the dates of the tasks that depend on this task if ($this->task_end_date != $oTsk->task_end_date || $this->task_dynamic != $oTsk->task_dynamic || $this->task_milestone == '1') { $this->shiftDependentTasks(); } } else { $this->_action = 'added'; $ret = db_insertObject('tasks', $this, 'task_id'); addHistory('tasks', $this->task_id, 'add', $this->task_name, $this->task_project); if (!$this->task_parent) { $sql = "UPDATE tasks SET task_parent = {$this->task_id} WHERE task_id = {$this->task_id}"; db_exec($sql); } else { // importing tasks do not update dynamics $importing_tasks = true; } // insert entry in user tasks $sql = "INSERT INTO user_tasks (user_id, task_id, user_type) VALUES ({$AppUI->user_id}, {$this->task_id}, -1)"; db_exec($sql); } //split out related departments and store them seperatly. $sql = 'DELETE FROM task_departments WHERE task_id=' . $this->task_id; db_exec($sql); // print_r($this->task_departments); if (!empty($this->task_departments)) { $departments = explode(',', $this->task_departments); foreach ($departments as $department) { $sql = 'INSERT INTO task_departments (task_id, department_id) values (' . $this->task_id . ', ' . $department . ')'; db_exec($sql); } } //split out related contacts and store them seperatly. $sql = 'DELETE FROM task_contacts WHERE task_id=' . $this->task_id; db_exec($sql); if (!empty($this->task_contacts)) { $contacts = explode(',', $this->task_contacts); foreach ($contacts as $contact) { $sql = 'INSERT INTO task_contacts (task_id, contact_id) values (' . $this->task_id . ', ' . $contact . ')'; db_exec($sql); } } if (!$importing_tasks && $this->task_parent != $this->task_id) { $this->updateDynamics(); } // if is child update parent task if ($this->task_parent != $this->task_id) { $pTask = new CTask(); $pTask->load($this->task_parent); $pTask->updateDynamics(true); } // update dependencies if (!empty($this->task_id)) { $this->updateDependencies($this->getDependencies()); } else { print_r($this); } if (!$ret) { return get_class($this) . "::store failed <br />" . db_error(); } else { return NULL; } }
} elseif (!($bulk_task_dependency == $upd_task->task_id)) { $upd_task->task_dynamic = 31; $upd_task->store(); $q = new w2p_Database_Query(); $q->addTable('task_dependencies'); $q->addReplace('dependencies_task_id', $upd_task->task_id); $q->addReplace('dependencies_req_task_id', $bulk_task_dependency); $q->exec(); //Lets recalc the dependency $dep_task = new CTask(); $dep_task->load($bulk_task_dependency); if ($dep_task->task_id) { $dep_task->shiftDependentTasks(); } } $upd_task->updateDynamics(); } } //Action: Assign User if (isset($_POST['bulk_task_hperc_assign']) && $bulk_task_hperc_assign != '') { //format hperc_assign user_id=percentage_assignment;user_id=percentage_assignment;user_id=percentage_assignment; $bulk_task_assign = ','; $tmp_ar = explode(';', $bulk_task_hperc_assign); $hperc_assign_ar = array(); for ($i = 0, $i_cmp = sizeof($tmp_ar); $i < $i_cmp; $i++) { $tmp = explode('=', $tmp_ar[$i]); if (count($tmp) > 1) { $hperc_assign_ar[$tmp[0]] = $tmp[1]; $bulk_task_assign .= $tmp[0] . ','; } else { $hperc_assign_ar[$tmp[0]] = 100;
/** * Updates the variable information on the task. * * @param int $notUsed not used * @param int $task_id that task id of task this task log is for * * @return void * * @access protected */ protected function updateTaskSummary($notUsed = null, $task_id) { $task = new CTask(); $task->overrideDatabase($this->_query); $task->load($task_id); $q = $this->_getQuery(); if ($this->_perms->checkModuleItem('tasks', 'edit', $task_id)) { if ($this->task_log_percent_complete <= 100) { $q->addQuery('task_log_percent_complete, task_log_date'); $q->addTable('task_log'); $q->addWhere('task_log_task = ' . (int) $task_id); $q->addOrder('task_log_date DESC, task_log_id DESC'); $q->setLimit(1); $results = $q->loadHash(); $percentComplete = $results['task_log_percent_complete']; } else { $percentComplete = 100; } $old_end_date = new w2p_Utilities_Date($task->task_end_date); $new_end_date = new w2p_Utilities_Date($this->task_log_task_end_date); $new_end_date->setHour($old_end_date->getHour()); $new_end_date->setMinute($old_end_date->getMinute()); $task_end_date = $new_end_date->format(FMT_DATETIME_MYSQL); /* * We're using a database update here instead of store() because a * bunch of other things happen when you call store().. like the * processing of contacts, departments, etc. */ $q = $this->_getQuery(); $q->addTable('tasks'); $q->addUpdate('task_percent_complete', $percentComplete); $q->addUpdate('task_end_date', $task_end_date); $q->addWhere('task_id = ' . (int) $task_id); $success = $q->exec(); if (!$success) { $this->_AppUI->setMsg($task->getError(), UI_MSG_ERROR, true); } $task->pushDependencies($task_id, $task_end_date); } $q->addQuery('SUM(task_log_hours)'); $q->addTable('task_log'); $q->addWhere('task_log_task = ' . (int) $task_id); $totalHours = $q->loadResult(); $task->updateHoursWorked2($task_id, $totalHours); $task->updateDynamics(); }