Project:Time Track
Version:6.x-1.1-beta2
Component:Miscellaneous
Category:feature request
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

For my uses, I would like the ability to manually submit time entries, ideally selecting a User, entering a Duration and a Description, and hitting Submit. Much like the way Basecamp does it, I would like to see this manual time entry form in both a Block form and a Table or List page. On the Table or List page, submitting one time entry would save and display that entry and immediately return a new line to submit the next entry. I'm not sure how I would like to handle Start time and End time values, as sometimes they are not necessary (I often prefix my description with "start:time - end:time :: ") yet your module works on the calculation of duration based on start and end time values.

If this is a possible feature we could work into this module, I would be happy to comp the interface. Let me know your thoughts, and once again, thank you for your work here.

-Steve

Comments

#1

Subscribing.
For me the shiny start/stop button doesn't reflect my way of tracking time.

cheers, Ronald

#2

That is indeed a need that I have been thinking about; I was envisioning to add this as a sub-module along with a couple other things I am working on. Stay tuned.

#3

I would like to extend the need for manual time entries.
When seriously working in a team there is a need to
* track times from the past
* move times from node to node
* track times for coworkers (with permission)

It also would be nice to track WHEN the time was tracked not only the duration itself. Date modul could maybe used for it.

I would like to see a serious attempt to timetracking in drupal.

At the moment i play around with Comment as Nodes to have CCK fields in comments, date module plus cck integer to have time and duration and views + views calc to sum durations per node. Comments are important to enter a note per time entry. Right now this is the closest way to my needs.

cheers, Ronald

#4

I am also interested in manual time entries as well.

#5

Mostly I would just like to have the ability to edit or delete time that was tracked. Sometimes I accidentally leave the tracker on for too long and then am unable to go back and fix it without going into the database and making the change there. I only wish I knew how to write the code to submit a patch for this.

#6

also interested.

#7

I'd say its more realistic to have time tracking done by a user inputting it rather than JS counting it. Most people bill out by the quarter-hour (15, 30, 45) anyway.

#8

Is this still a possibility? Is there anything being developed in this area?

I absolutely love the module, but I also absolutely need to be able to correct/change/delete time tracker values.

Unfortunately, the modules that allow for manual time entry by the end user don't allow for automatic JS time tracking, which is the major benefit of this module.

Can't we have both?

#9

subscribing.

#10

Well, I can't believe that after a couple years someone hasn't spoke up and tried to add in the functionality. I did it this afternoon. It may not be the best way to do it but it works for my case. Please keep in mind that I am using one node per time track. In other words, everytime the timer is started a new node is created. This is meant to be an exact blueprint but should be enough to get someone going on something a little more permanent. First I added the fields to the form:

This goes in the time_track_form_alter function

if (variable_get('time_track_type_'. $form['type']['#value'], 0)) {
  $nid = $form['#node']->nid;
  $uid = $form['#node']->uid;
  if($nid && uid) {
  $ongoing = time_track_get_ongoing($nid, $uid);
  $startTime = date('Y-m-d\TH:i:s', time_track_get_start_time($nid, $uid));
  $stopTime = date('Y-m-d\TH:i:s', time_track_get_stop_time($nid, $uid));
  }
 
$form['start_time'] = array(
  '#type' => 'date_popup',
  '#title' => t('Start'),
  '#default_value' => $startTime,
  '#weight' => 99,
);

$form['stop_time'] = array(
  '#type' => 'date_popup',
  '#title' => t('End'),
  '#default_value' => $stopTime,
  '#weight' => 100,
);

array_unshift($form['#validate'], 'time_track_form_validate');
  }

I added these functions to handle default values:

/**
* Returns the start tracked time
*/
function time_track_get_start_time($nid, $uid) {
  $startTime = "";
 
  if($nid && $uid) { 
  $result = db_fetch_object(db_query("SELECT log.start AS starttime FROM {time_track_log} log LEFT JOIN {time_track} tracker ON log.ttid = tracker.ttid  WHERE tracker.uid = ".$uid." AND tracker.nid = ".$nid));
 
  $startTime = $result->starttime;
  }
 
  return $startTime;
}
/**
* Returns the stop tracked time
*/
function time_track_get_stop_time($nid, $uid) {
  $stopTime = "";

  if($nid && $uid) { 
  $result = db_fetch_object(db_query("SELECT log.stop AS stoptime FROM {time_track_log} log LEFT JOIN {time_track} tracker ON log.ttid = tracker.ttid  WHERE tracker.uid = ".$uid." AND tracker.nid = ".$nid));
 
  $stopTime = $result->stoptime;
  }
   
  return $stopTime;
}

Then I added some extra validation, this was added to the end of time_track.module:

function time_track_form_validate($node, &$form) {
if(isset($form['values']['start_time']) && empty($form['values']['stop_time'])) {
form_set_error('time', t('If you enter a start time you must enter a stop time.'));
}
if(isset($form['values']['start_time']) && isset($form['values']['stop_time'])) {
if(strtotime($form['values']['start_time']) > strtotime($form['values']['stop_time'])) {
form_set_error('time', t('The stop time must be after the start time.'));
}
}

}

Finally I used hook_nodeapi to process my form

function time_track_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if (variable_get('time_track_type_'. $node->type, 0)) {
switch ($op) {
    case 'presave':
                        //allows updating
if($node->nid) {
if($node->start_time && $node->stop_time) {
$nid = $node->nid;
$uid = $node->uid;
$totaltime = strtotime($node->stop_time) - strtotime($node->start_time);
$result = db_query_range("SELECT * FROM {time_track} WHERE nid = %d AND uid = %d", $nid, $uid, 0, 1);
$tracker = db_fetch_object($result);
if (!$tracker)  { // If there is not time tracker we create one
db_query("INSERT INTO {time_track} SET nid = %d, uid = %d, time = %d", $nid, $uid, $totaltime);
$result = db_query_range("SELECT * FROM {time_track} WHERE nid = %d AND uid = %d", $nid, $uid, 0, 1);
$tracker = db_fetch_object($result);
db_query("INSERT INTO {time_track_log} SET start = %d, stop = %d, ttid = %d", strtotime($node->start_time), strtotime($node->stop_time), $tracker->ttid);
} else {

db_query("UPDATE {time_track} SET time = %d WHERE ttid = %d AND nid = %d", $totaltime, $tracker->ttid, $nid);
db_query("UPDATE {time_track_log} SET start = %d, stop = %d WHERE ttid = %d", strtotime($node->start_time), strtotime($node->stop_time), $tracker->ttid);
}
}
rules_invoke_event('time_track_stop', $nid);
}
break;
case 'insert':
                        //handles new time trackers
if($node->start_time && $node->stop_time) {
$nid = $node->nid;
$uid = $node->uid;
$totaltime = strtotime($node->stop_time) - strtotime($node->start_time);
$result = db_query_range("SELECT * FROM {time_track} WHERE nid = %d AND uid = %d", $nid, $uid, 0, 1);
    $tracker = db_fetch_object($result);
if (!$tracker)  { // If there is not time tracker we create one
db_query("INSERT INTO {time_track} SET nid = %d, uid = %d, time = %d", $nid, $uid, $totaltime);
$result = db_query_range("SELECT * FROM {time_track} WHERE nid = %d AND uid = %d", $nid, $uid, 0, 1);
      $tracker = db_fetch_object($result);
db_query("INSERT INTO {time_track_log} SET start = %d, stop = %d, ttid = %d", strtotime($node->start_time), strtotime($node->stop_time), $tracker->ttid);
} else {

db_query("UPDATE {time_track} SET time = %d WHERE ttid = %d AND nid = %d", $totaltime, $tracker->ttid, $nid);
db_query("UPDATE {time_track_log} SET start = %d, stop = %d WHERE ttid = %d", strtotime($node->start_time), strtotime($node->stop_time), $tracker->ttid);
}
rules_invoke_event('time_track_stop', $nid);
}
break;
}
}
}

Hope this helps someone finally solve this problem making this the ultimate module for time tracking. I am not the best coder in the world so please let me know if there is a better way to do any of this, I am open to suggestions.

nobody click here