Index: application/controllers/TimeController.class.php =================================================================== --- application/controllers/TimeController.class.php (revision 0) +++ application/controllers/TimeController.class.php (revision 0) @@ -0,0 +1,229 @@ +addHelper('textile'); + $project = active_project(); + + tpl_assign('times', $project->getTimes()); + + $this->setSidebar(get_template_path('index_sidebar', 'time')); + } // index + + /** + * Show view time page + * + * @access public + * @param void + * @return null + */ + function view() { + $this->addHelper('textile'); + + $time = ProjectTimes::findById(get_id()); + if(!($time instanceof ProjectTime)) { + flash_error(lang('time dnx')); + $this->redirectTo('time', 'index'); + } // if + + if(!$time->canView(logged_user())) { + flash_error(lang('no access permissions')); + $this->redirectToReferer(get_url('time')); + } // if + + tpl_assign('time', $time); + } // view + + /** + * Process add time form + * + * @access public + * @param void + * @return null + */ + function add() { + $this->setTemplate('add_time'); + + if(!ProjectTime::canAdd(logged_user(), active_project())) { + flash_error(lang('no access permissions')); + $this->redirectToReferer(get_url('time')); + } // if + + $time_data = array_var($_POST, 'time'); + if(!is_array($time_data)) { + $user = logged_user(); + $time_data = array( + 'done_date' => DateTimeValueLib::now(), + 'is_billable' => true, + 'is_private' => true, + 'assigned_to' => logged_user()->getCompanyId() . ":" . logged_user()->getId() + ); // array + } // if + $time = new ProjectTime(); + tpl_assign('time_data', $time_data); + tpl_assign('time', $time); + + if(is_array(array_var($_POST, 'time'))) { + $time_data['done_date'] = DateTimeValueLib::make(0, 0, 0, array_var($_POST, 'time_done_date_month', 1), array_var($_POST, 'time_done_date_day', 1), array_var($_POST, 'time_done_date_year', 1970)); + + $assigned_to = explode(':', array_var($time_data, 'assigned_to', '')); + + $time->setFromAttributes($time_data); + if(!logged_user()->isMemberOfOwnerCompany()) $time->setIsPrivate(false); + + $time->setProjectId(active_project()->getId()); + $time->setAssignedToCompanyId(array_var($assigned_to, 0, 0)); + $time->setAssignedToUserId(array_var($assigned_to, 1, 0)); + + try { + DB::beginWork(); + + $time->save(); + ApplicationLogs::createLog($time, active_project(), ApplicationLogs::ACTION_ADD); + + DB::commit(); + + flash_success(lang('success add time', $time->getName())); + $this->redirectTo('time'); + + } catch(Exception $e) { + DB::rollback(); + tpl_assign('error', $e); + } // try + } // if + } // add + + /** + * Show and process edit time form + * + * @access public + * @param void + * @return null + */ + function edit() { + $this->setTemplate('add_time'); + + $time = ProjectTimes::findById(get_id()); + if(!($time instanceof ProjectTime)) { + flash_error(lang('time dnx')); + $this->redirectTo('time', 'index'); + } // if + + if(!$time->canEdit(logged_user())) { + flash_error(lang('no access permissions')); + $this->redirectToReferer(get_url('time')); + } + + $time_data = array_var($_POST, 'time'); + if(!is_array($time_data)) { + $time_data = array( + 'name' => $time->getName(), + 'hours' => $time->getHours(), + 'is_billable' => $time->getBillable(), + 'done_date' => $time->getDoneDate(), + 'description' => $time->getDescription(), + 'assigned_to' => $time->getAssignedToCompanyId() . ':' . $time->getAssignedToUserId(), + 'is_private' => $time->isPrivate(), + ); // array + } // if + + tpl_assign('time_data', $time_data); + tpl_assign('time', $time); + + if(is_array(array_var($_POST, 'time'))) { + $old_owner = $time->getAssignedTo(); // remember the old owner + $time_data['done_date'] = DateTimeValueLib::make(0, 0, 0, array_var($_POST, 'time_done_date_month', 1), array_var($_POST, 'time_done_date_day', 1), array_var($_POST, 'time_done_date_year', 1970)); + + $assigned_to = explode(':', array_var($time_data, 'assigned_to', '')); + + $old_is_private = $time->isPrivate(); + $time->setFromAttributes($time_data); + if(!logged_user()->isMemberOfOwnerCompany()) $time->setIsPrivate($old_is_private); + + $time->setProjectId(active_project()->getId()); + $time->setAssignedToCompanyId(array_var($assigned_to, 0, 0)); + $time->setAssignedToUserId(array_var($assigned_to, 1, 0)); + + try { + DB::beginWork(); + $time->save(); + + ApplicationLogs::createLog($time, active_project(), ApplicationLogs::ACTION_EDIT); + DB::commit(); + + flash_success(lang('success edit time', $time->getName())); + $this->redirectTo('time'); + + } catch(Exception $e) { + DB::rollback(); + tpl_assign('error', $e); + } // try + } // if + } // edit + + /** + * Delete single time + * + * @access public + * @param void + * @return null + */ + function delete() { + $time = ProjectTimes::findById(get_id()); + if(!($time instanceof ProjectTime)) { + flash_error(lang('time dnx')); + $this->redirectTo('time'); + } // if + + if(!$time->canDelete(logged_user())) { + flash_error(lang('no access permissions')); + $this->redirectToReferer(get_url('time')); + } // if + + try { + + DB::beginWork(); + $time->delete(); + ApplicationLogs::createLog($time, $time->getProject(), ApplicationLogs::ACTION_DELETE); + DB::commit(); + + flash_success(lang('success deleted time', $time->getName())); + } catch(Exception $e) { + DB::rollback(); + flash_error(lang('error delete time')); + } // try + + $this->redirectTo('time'); + } // delete + + } // TimeController + +?> \ No newline at end of file Index: application/helpers/project_website.php =================================================================== --- application/helpers/project_website.php (revision 104) +++ application/helpers/project_website.php (working copy) @@ -24,6 +24,7 @@ define('PROJECT_TAB_MESSAGES', 'messages'); define('PROJECT_TAB_TASKS', 'tasks'); define('PROJECT_TAB_MILESTONES', 'milestones'); + define('PROJECT_TAB_TIME', 'time'); define('PROJECT_TAB_FILES', 'files'); define('PROJECT_TAB_TAGS', 'tags'); define('PROJECT_TAB_FORMS', 'forms'); @@ -57,6 +58,11 @@ get_url('milestone') )); add_tabbed_navigation_item(new TabbedNavigationItem( + PROJECT_TAB_TIME, + lang('time'), + get_url('time') + )); + add_tabbed_navigation_item(new TabbedNavigationItem( PROJECT_TAB_FILES, lang('files'), get_url('files') Index: application/models/project_times/ProjectTime.class.php =================================================================== --- application/models/project_times/ProjectTime.class.php (revision 0) +++ application/models/project_times/ProjectTime.class.php (revision 0) @@ -0,0 +1,313 @@ +getProjectId()); + } // getProject + + /** + * Return assigned to object. It can be User, Company or nobady (NULL) + * + * @access public + * @param void + * @return ApplicationDataObject + */ + function getAssignedTo() { + if($this->getAssignedToUserId() > 0) { + return $this->getAssignedToUser(); + } elseif($this->getAssignedToCompanyId() > 0) { + return $this->getAssignedToCompany(); + } else { + return null; + } // if + } // getAssignedTo + + /** + * Return responsible company + * + * @access public + * @param void + * @return Company + */ + protected function getAssignedToCompany() { + return Companies::findById($this->getAssignedToCompanyId()); + } // getAssignedToCompany + + /** + * Return responsible user + * + * @access public + * @param void + * @return User + */ + protected function getAssignedToUser() { + return Users::findById($this->getAssignedToUserId()); + } // getAssignedToUser + + /** + * Returns true if this time log is made today + * + * @access public + * @param void + * @return boolean + */ + function isToday() { + $now = DateTimeValueLib::now(); + $created_on = $this->getDoneDate(); + + // getCreatedOn and similar functions can return NULL + if(!($created_on instanceof DateTimeValue)) return false; + + return $now->getDay() == $created_on->getDay() && + $now->getMonth() == $created_on->getMonth() && + $now->getYear() == $created_on->getYear(); + } // isToday + + /** + * Returnst true if this application log was made yesterday + * + * @param void + * @return boolean + */ + function isYesterday() { + $created_on = $this->getDoneDate(); + if(!($created_on instanceof DateTimeValue)) return false; + + $day_after = $created_on->advance(24 * 60 * 60, false); + $now = DateTimeValueLib::now(); + + return $now->getDay() == $day_after->getDay() && + $now->getMonth() == $day_after->getMonth() && + $now->getYear() == $day_after->getYear(); + } // isYesterday + + + // --------------------------------------------------- + // Permissions + // --------------------------------------------------- + + /** + * Returns true if specific user has CAN_MANAGE_TIME permission set to true + * + * @access public + * @param User $user + * @return boolean + */ + function canManage(User $user) { + return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_TIME); + } // canManage + + /** + * Returns true if $user can view this time + * + * @param User $user + * @return boolean + */ + function canView(User $user) { + if(!$user->isProjectUser($this->getProject())) return false; + if($user->isAdministrator()) return true; + if($this->isPrivate() && !$user->isMemberOfOwnerCompany()) return false; + return true; + } // canView + + /** + * Check if specific user can add new time to specific project + * + * @access public + * @param User $user + * @param Project $project + * @return boolean + */ + function canAdd(User $user, Project $project) { + if(!$user->isProjectUser($project)) return false; + if($user->isAdministrator()) return true; + return $user->getProjectPermission($project, ProjectUsers::CAN_MANAGE_TIME); + } // canAdd + + /** + * Check if specific user can edit this time + * + * @access public + * @param User $user + * @return boolean + */ + function canEdit(User $user) { + if(!$user->isProjectUser($this->getProject())) return false; + if($user->isAdministrator()) return true; + if($this->getCreatedById() == $user->getId()) return true; + return false; + } // canEdit + + /** + * Can chagne status of this time + * + * @access public + * @param User $user + * @return boolean + */ + function canChangeStatus(User $user) { + if($this->canEdit($user)) return true; + + // Additional check - is this time assigned to this user or its company + if($this->getAssignedTo() instanceof User) { + if($user->getId() == $this->getAssignedTo()->getObjectId()) return true; + } elseif($this->getAssignedTo() instanceof Company) { + if($user->getCompanyId() == $this->getAssignedTo()->getObjectId()) return true; + } // if + return false; + } // canChangeStatus + + /** + * Check if specific user can delete this time + * + * @access public + * @param User $user + * @return boolean + */ + function canDelete(User $user) { + if(!$user->isProjectUser($this->getProject())) return false; + if($user->isAdministrator()) return true; + return false; + } // canDelete + + // --------------------------------------------------- + // URL + // --------------------------------------------------- + + function getViewUrl() { + return get_url('time', 'view', array('id' => $this->getId(), 'active_project' => $this->getProjectId())); + } // getViewUrl + + /** + * Return edit time URL + * + * @access public + * @param void + * @return string + */ + function getEditUrl() { + return get_url('time', 'edit', array('id' => $this->getId(), 'active_project' => $this->getProjectId())); + } // getEditUrl + + /** + * Return delete time URL + * + * @access public + * @param void + * @return string + */ + function getDeleteUrl() { + return get_url('time', 'delete', array('id' => $this->getId(), 'active_project' => $this->getProjectId())); + } // getDeleteUrl + + /** + * Return complete time url + * + * @access public + * @param void + * @return string + */ + function getCompleteUrl() { + return get_url('time', 'complete', array('id' => $this->getId(), 'active_project' => $this->getProjectId())); + } // getCompleteUrl + + // --------------------------------------------------- + // System functions + // --------------------------------------------------- + + /** + * Validate before save + * + * @access public + * @param array $errors + * @return boolean + */ + function validate(&$errors) { + if(!$this->validatePresenceOf('name')) $errors[] = lang('time name required'); + #if(!$this->validatePresenceOf('done_date')) $errors[] = lang('time date required'); + #if(!$this->validatePresenceOf('hours')) $errors[] = lang('time hours required'); + } // validate + + /** + * Delete this object and reset all relationship. This function will not delete any of related objec + * + * @access public + * @param void + * @return boolean + */ + function delete() { + + try { + return parent::delete(); + } catch(Exception $e) { + throw $e; + } // try + + } // delete + + // --------------------------------------------------- + // ApplicationDataObject implementation + // --------------------------------------------------- + + /** + * Return object type name + * + * @param void + * @return string + */ + function getObjectTypeName() { + return lang('time'); + } // getObjectTypeName + + /** + * Return object URl + * + * @access public + * @param void + * @return string + */ + function getObjectUrl() { + return $this->getViewUrl(); + } // getObjectUrl + + } // ProjectTime + +?> Index: application/models/project_times/ProjectTimes.class.php =================================================================== --- application/models/project_times/ProjectTimes.class.php (revision 0) +++ application/models/project_times/ProjectTimes.class.php (revision 0) @@ -0,0 +1,49 @@ +getActiveProjects(); + if(!is_array($projects) || !count($projects)) { + return null; + } // if + + $project_ids = array(); + foreach($projects as $project) { + $project_ids[] = $project->getId(); + } // foreach + + return self::findAll(array( + 'conditions' => array('(`assigned_to_user_id` = ? OR (`assigned_to_user_id` = ? AND `assigned_to_company_id` = ?)) AND `project_id` IN (?)', $user->getId(), 0, 0, $project_ids), + 'order' => '`done_date`' + )); // findAll + } // getTimeByUser + + /** + * Return times that are assigned to the specific user and belongs to specific project + * + * @param User $user + * @param Project $project + * @return array + */ + static function getTimeByUserAndProject(User $user, Project $project) { + return self::findAll(array( + 'conditions' => array('(`assigned_to_user_id` = ? OR (`assigned_to_user_id` = ? AND `assigned_to_company_id` = ?)) AND `project_id` = ?', $user->getId(), 0, 0, $project->getId()), + 'order' => '`done_date`' + )); // findAll + } // getTimeByUserAndProject + + } // ProjectTimes + +?> Index: application/models/project_times/base/BaseProjectTime.class.php =================================================================== --- application/models/project_times/base/BaseProjectTime.class.php (revision 0) +++ application/models/project_times/base/BaseProjectTime.class.php (revision 0) @@ -0,0 +1,381 @@ +getColumnValue('id'); + } // getId() + + /** + * Set value of 'id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setId($value) { + return $this->setColumnValue('id', $value); + } // setId() + + /** + * Return value of 'project_id' field + * + * @access public + * @param void + * @return integer + */ + function getProjectId() { + return $this->getColumnValue('project_id'); + } // getProjectId() + + /** + * Set value of 'project_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setProjectId($value) { + return $this->setColumnValue('project_id', $value); + } // setProjectId() + + /** + * Return value of 'name' field + * + * @access public + * @param void + * @return string + */ + function getName() { + return $this->getColumnValue('name'); + } // getName() + + /** + * Set value of 'name' field + * + * @access public + * @param string $value + * @return boolean + */ + function setName($value) { + return $this->setColumnValue('name', $value); + } // setName() + + /** + * Return value of 'hours' field + * + * @access public + * @param void + * @return string + */ + function getHours() { + return $this->getColumnValue('hours'); + } // getHours() + + /** + * Set value of 'hours' field + * + * @access public + * @param string $value + * @return boolean + */ + function setHours($value) { + return $this->setColumnValue('hours', $value); + } // setHours() + + /** + * Return value of 'is_billable' field + * + * @access public + * @param void + * @return string + */ + function getBillable() { + return $this->getColumnValue('is_billable'); + } // getBillable() + + /** + * Set value of 'is_billable' field + * + * @access public + * @param string $value + * @return boolean + */ + function setBillable($value) { + return $this->setColumnValue('is_billable', $value); + } // setBillable() + + /** + * Return value of 'description' field + * + * @access public + * @param void + * @return string + */ + function getDescription() { + return $this->getColumnValue('description'); + } // getDescription() + + /** + * Set value of 'description' field + * + * @access public + * @param string $value + * @return boolean + */ + function setDescription($value) { + return $this->setColumnValue('description', $value); + } // setDescription() + + /** + * Return value of 'due_date' field + * + * @access public + * @param void + * @return DateTimeValue + */ + function getDoneDate() { + return $this->getColumnValue('done_date'); + } // getDoneDate() + + /** + * Set value of 'due_date' field + * + * @access public + * @param DateTimeValue $value + * @return boolean + */ + function setDueDate($value) { + return $this->setColumnValue('due_date', $value); + } // setDueDate() + + /** + * Return value of 'assigned_to_company_id' field + * + * @access public + * @param void + * @return integer + */ + function getAssignedToCompanyId() { + return $this->getColumnValue('assigned_to_company_id'); + } // getAssignedToCompanyId() + + /** + * Set value of 'assigned_to_company_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setAssignedToCompanyId($value) { + return $this->setColumnValue('assigned_to_company_id', $value); + } // setAssignedToCompanyId() + + /** + * Return value of 'assigned_to_user_id' field + * + * @access public + * @param void + * @return integer + */ + function getAssignedToUserId() { + return $this->getColumnValue('assigned_to_user_id'); + } // getAssignedToUserId() + + /** + * Set value of 'assigned_to_user_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setAssignedToUserId($value) { + return $this->setColumnValue('assigned_to_user_id', $value); + } // setAssignedToUserId() + + /** + * Return value of 'is_private' field + * + * @access public + * @param void + * @return boolean + */ + function getIsPrivate() { + return $this->getColumnValue('is_private'); + } // getIsPrivate() + + /** + * Set value of 'is_private' field + * + * @access public + * @param boolean $value + * @return boolean + */ + function setIsPrivate($value) { + return $this->setColumnValue('is_private', $value); + } // setIsPrivate() + + /** + * Return value of 'completed_on' field + * + * @access public + * @param void + * @return DateTimeValue + */ + function getCompletedOn() { + return $this->getColumnValue('completed_on'); + } // getCompletedOn() + + /** + * Set value of 'completed_on' field + * + * @access public + * @param DateTimeValue $value + * @return boolean + */ + function setCompletedOn($value) { + return $this->setColumnValue('completed_on', $value); + } // setCompletedOn() + + /** + * Return value of 'completed_by_id' field + * + * @access public + * @param void + * @return integer + */ + function getCompletedById() { + return $this->getColumnValue('completed_by_id'); + } // getCompletedById() + + /** + * Set value of 'completed_by_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setCompletedById($value) { + return $this->setColumnValue('completed_by_id', $value); + } // setCompletedById() + + /** + * Return value of 'created_on' field + * + * @access public + * @param void + * @return DateTimeValue + */ + function getCreatedOn() { + return $this->getColumnValue('created_on'); + } // getCreatedOn() + + /** + * Set value of 'created_on' field + * + * @access public + * @param DateTimeValue $value + * @return boolean + */ + function setCreatedOn($value) { + return $this->setColumnValue('created_on', $value); + } // setCreatedOn() + + /** + * Return value of 'created_by_id' field + * + * @access public + * @param void + * @return integer + */ + function getCreatedById() { + return $this->getColumnValue('created_by_id'); + } // getCreatedById() + + /** + * Set value of 'created_by_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setCreatedById($value) { + return $this->setColumnValue('created_by_id', $value); + } // setCreatedById() + + /** + * Return value of 'updated_on' field + * + * @access public + * @param void + * @return DateTimeValue + */ + function getUpdatedOn() { + return $this->getColumnValue('updated_on'); + } // getUpdatedOn() + + /** + * Set value of 'updated_on' field + * + * @access public + * @param DateTimeValue $value + * @return boolean + */ + function setUpdatedOn($value) { + return $this->setColumnValue('updated_on', $value); + } // setUpdatedOn() + + /** + * Return value of 'updated_by_id' field + * + * @access public + * @param void + * @return integer + */ + function getUpdatedById() { + return $this->getColumnValue('updated_by_id'); + } // getUpdatedById() + + /** + * Set value of 'updated_by_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setUpdatedById($value) { + return $this->setColumnValue('updated_by_id', $value); + } // setUpdatedById() + + + /** + * Return manager instance + * + * @access protected + * @param void + * @return ProjectTimes + */ + function manager() { + if(!($this->manager instanceof ProjectTimes)) $this->manager = ProjectTimes::instance(); + return $this->manager; + } // manager + + } // BaseProjectTime + +?> Index: application/models/project_times/base/BaseProjectTimes.class.php =================================================================== --- application/models/project_times/base/BaseProjectTimes.class.php (revision 0) +++ application/models/project_times/base/BaseProjectTimes.class.php (revision 0) @@ -0,0 +1,234 @@ + Column type map + * + * @var array + * @static + */ + static private $columns = array('id' => DATA_TYPE_INTEGER, 'project_id' => DATA_TYPE_INTEGER, 'name' => DATA_TYPE_STRING, 'description' => DATA_TYPE_STRING, 'done_date' => DATA_TYPE_DATETIME, 'hours' => DATA_TYPE_FLOAT, 'is_billable' => DATA_TYPE_BOOLEAN, 'assigned_to_company_id' => DATA_TYPE_INTEGER, 'assigned_to_user_id' => DATA_TYPE_INTEGER, 'is_private' => DATA_TYPE_BOOLEAN, 'created_on' => DATA_TYPE_DATETIME, 'created_by_id' => DATA_TYPE_INTEGER, 'updated_on' => DATA_TYPE_DATETIME, 'updated_by_id' => DATA_TYPE_INTEGER); + + /** + * Construct + * + * @return BaseProjectTimes + */ + function __construct() { + parent::__construct('ProjectTime', 'project_time', true); + } // __construct + + // ------------------------------------------------------- + // Description methods + // ------------------------------------------------------- + + /** + * Return array of object columns + * + * @access public + * @param void + * @return array + */ + function getColumns() { + return array_keys(self::$columns); + } // getColumns + + /** + * Return column type + * + * @access public + * @param string $column_name + * @return string + */ + function getColumnType($column_name) { + if(isset(self::$columns[$column_name])) { + return self::$columns[$column_name]; + } else { + return DATA_TYPE_STRING; + } // if + } // getColumnType + + /** + * Return array of PK columns. If only one column is PK returns its name as string + * + * @access public + * @param void + * @return array or string + */ + function getPkColumns() { + return 'id'; + } // getPkColumns + + /** + * Return name of first auto_incremenent column if it exists + * + * @access public + * @param void + * @return string + */ + function getAutoIncrementColumn() { + return 'id'; + } // getAutoIncrementColumn + + // ------------------------------------------------------- + // Finders + // ------------------------------------------------------- + + /** + * Do a SELECT query over database with specified arguments + * + * @access public + * @param array $arguments Array of query arguments. Fields: + * + * - one - select first row + * - conditions - additional conditions + * - order - order by string + * - offset - limit offset, valid only if limit is present + * - limit + * + * @return one or ProjectTimes objects + * @throws DBQueryError + */ + function find($arguments = null) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::find($arguments); + } else { + return ProjectTimes::instance()->find($arguments); + //$instance =& ProjectTimes::instance(); + //return $instance->find($arguments); + } // if + } // find + + /** + * Find all records + * + * @access public + * @param array $arguments + * @return one or ProjectTimes objects + */ + function findAll($arguments = null) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::findAll($arguments); + } else { + return ProjectTimes::instance()->findAll($arguments); + //$instance =& ProjectTimes::instance(); + //return $instance->findAll($arguments); + } // if + } // findAll + + /** + * Find one specific record + * + * @access public + * @param array $arguments + * @return ProjectTime + */ + function findOne($arguments = null) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::findOne($arguments); + } else { + return ProjectTimes::instance()->findOne($arguments); + //$instance =& ProjectTimes::instance(); + //return $instance->findOne($arguments); + } // if + } // findOne + + /** + * Return object by its PK value + * + * @access public + * @param mixed $id + * @param boolean $force_reload If true cache will be skipped and data will be loaded from database + * @return ProjectTime + */ + function findById($id, $force_reload = false) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::findById($id, $force_reload); + } else { + return ProjectTimes::instance()->findById($id, $force_reload); + //$instance =& ProjectTimes::instance(); + //return $instance->findById($id, $force_reload); + } // if + } // findById + + /** + * Return number of rows in this table + * + * @access public + * @param string $conditions Query conditions + * @return integer + */ + function count($condition = null) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::count($condition); + } else { + return ProjectTimes::instance()->count($condition); + //$instance =& ProjectTimes::instance(); + //return $instance->count($condition); + } // if + } // count + + /** + * Delete rows that match specific conditions. If $conditions is NULL all rows from table will be deleted + * + * @access public + * @param string $conditions Query conditions + * @return boolean + */ + function delete($condition = null) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::delete($condition); + } else { + return ProjectTimes::instance()->delete($condition); + //$instance =& ProjectTimes::instance(); + //return $instance->delete($condition); + } // if + } // delete + + /** + * This function will return paginated result. Result is an array where first element is + * array of returned object and second populated pagination object that can be used for + * obtaining and rendering pagination data using various helpers. + * + * Items and pagination array vars are indexed with 0 for items and 1 for pagination + * because you can't use associative indexing with list() construct + * + * @access public + * @param array $arguments Query argumens (@see find()) Limit and offset are ignored! + * @param integer $items_per_page Number of items per page + * @param integer $current_page Current page number + * @return array + */ + function paginate($arguments = null, $items_per_page = 10, $current_page = 1) { + if(isset($this) && instance_of($this, 'ProjectTimes')) { + return parent::paginate($arguments, $items_per_page, $current_page); + } else { + return ProjectTimes::instance()->paginate($arguments, $items_per_page, $current_page); + //$instance =& ProjectTimes::instance(); + //return $instance->paginate($arguments, $items_per_page, $current_page); + } // if + } // paginate + + /** + * Return manager instance + * + * @return ProjectTimes + */ + function instance() { + static $instance; + if(!instance_of($instance, 'ProjectTimes')) { + $instance = new ProjectTimes(); + } // if + return $instance; + } // instance + + } // ProjectTimes + +?> Index: application/models/projects/Project.class.php =================================================================== --- application/models/projects/Project.class.php (revision 104) +++ application/models/projects/Project.class.php (working copy) @@ -497,6 +497,47 @@ } // splitOpenMilestones // --------------------------------------------------- + // Time + // --------------------------------------------------- + + /** + * Return all times, don't filter them by is_private stamp based on users permissions + * + * @param void + * @return array + */ + function getAllTimes() { + if (is_null($this->all_times)) { + $this->all_times = ProjectTimes::findAll(array( + 'conditions' => array('`project_id` = ?', $this->getId()), + 'order' => 'done_date desc' + )); // findAll + } // if + return $this->all_times; + } // getAllTimes + + /** + * Return all project time + * + * @access public + * @param void + * @return array + */ + function getTimes() { + if (logged_user()->isMemberOfOwnerCompany()) + { + return $this->getAllTimes(); // member of owner company + } + if (is_null($this->times)) { + $this->times = ProjectTimes::findAll(array( + 'conditions' => array('`project_id` = ? AND `is_private` = ?', $this->getId(), 0), + 'order' => 'done_date desc' + )); // findAll + } // if + return $this->times; + } // getTimes + + // --------------------------------------------------- // Task lists // --------------------------------------------------- Index: application/views/time/add_time.php =================================================================== --- application/views/time/add_time.php (revision 0) +++ application/views/time/add_time.php (revision 0) @@ -0,0 +1,59 @@ +isNew() ? lang('add time') : lang('edit time')); + project_tabbed_navigation(PROJECT_TAB_TIME); + if($time->isNew()) { + project_crumbs(lang('add time')); + } else { + project_crumbs(lang('edit time')); + } + +?> +isNew()) { ?> +
Index: application/views/time/index.php =================================================================== --- application/views/time/index.php (revision 0) +++ application/views/time/index.php (revision 0) @@ -0,0 +1,71 @@ + + +| Date | +Name | +Details | +Hours | ++ |
|---|---|---|---|---|
| +getDoneDate()->getYear() > DateTimeValueLib::now()->getYear()) { ?> + getDoneDate(), null, 0) ?> + + getDoneDate(), 0) ?> + + | ++ getAssignedTo() instanceof ApplicationDataObject) { ?> + getAssignedTo()->getObjectName()) ?> + + | ++ getName()) ?> + | +getHours() ?> | ++canEdit(logged_user())) $options[] = '' . lang('edit') . ''; + if($time->canDelete(logged_user())) $options[] = '' . lang('delete') . ''; +?> + + + } ?> + | +