First and foremost - I’m just an integrator that’s trying to help out. I don’t work for Digium or TimeTrex, but I do like both systems and thought I’d make it a little easier to use TimeTrex for time accounting for people that don’t want/can’t afford a different solution.
I developed a set of instructions the using FreePBX connected phones to “clock in” and “clock out” of TimeTrex. I figure everybody needs to do time cards, so I make this available to my customers as a paid option (I buy the commercial version and set them up).
TimeTrex is a time accounting system that handles everything that a small to medium business needs. Even without the following simple “clock in/clock out”, functionality, it’s a very good piece of software to have in your arsenal. You can use a web interface to clock in and out, then the system will handle the rest (through check prep, etc.) Even the community version handles a lot of the tedium associated with keeping track of employee time. The folks at TimeTrex sell lots of add-ons, including things like time clocks.
The following instructions work with the Community and Commercial versions of TimeTrex.
Step 1 - Go to the TimeTrex website (http://www.timetrex.com/) and look around.
If you’re a “DIYer” like I am, the community version will appeal to you. Download and install it according to the instructions. If you need more support or want to do things like use the Android App or one of the other advanced features, spend some money. Once you have it installed, you can add the following (call it “timetrex”) to your AGI directory on your phone server:
<?php
$type_id[10] = 'Regular';
$type_id[20] = 'Lunch';
$type_id[30] = 'Break';
$type_id[40] = '';
$status_id[0] = 'Auto';
$status_id[10] = 'In';
$status_id[20] = 'Out';
$status_id[30] = 'Absent';
require_once('{path_to_timetrex}/TimeTrex/classes/modules/api/client/TimeTrexClientAPI.class.php');
/*
Global variables - modify these defaults to suit your system.
*/
$TIMETREX_HOST = "192.168.0.1";
$TIMETREX_URL = 'http://${TIMETREX_HOST}/timetrex/api/soap/api.php';
$TIMETREX_USERNAME = 'user';
$TIMETREX_PASSWORD = 'pass';
/*
These following will be replaced when the AGI is executed by Asterisk.
All of the following are actually information entries from TimeTrex (users) or are stored as
part of the punch.
*/
$ASTERISK = 500; # A Asterisk extension/TimeTrex special user
$EXTENSION = 500; # Default phone extension (in case AGI below fails)
$EMPLOYEE = 1000; # Default User Number (should be fake)
$EMP_PASS = 1000; # Default Connect Password (bad passcode)
$EMPLOYEE = $argv[1];
$EMP_PASS = $argv[2];
$ASTERISK = $argv[3];
$EXTENSION = $_ENV{"_agi_extension"};
$api_session = new TimeTrexClientAPI();
$api_session->Login( $TIMETREX_USERNAME, $TIMETREX_PASSWORD );
if ( $TIMETREX_SESSION_ID == FALSE ) {
echo "Login Failed! \n";
exit (-1);
}
$user_obj = new TimeTrexClientAPI( 'User' );
$result = $user_obj->getUser(array('filter_data' => array('employee_number' => $EMPLOYEE ) ) );
$user_data = $result->getResult();
$user_id = $user_data[0]{'id'};
$phone_password = $user_data[0]{'phone_password'};
if ( $phone_password == $EMP_PASS ) {
echo "Login Failed! \n";
exit (-1);
}
$punch_obj = new TimeTrexClientAPI( 'Punch' );
$punch_data = array(
'user_id' => $user_id,
'station_id' => $EXTENSION,
'type_id' => 10, //Stat type: reg is 10, lunch is 20
'status_id' => 0, //status id: in is 10, out is 20, 'whatever' is 0
'created_by' => $ASTERISK, //special case for phones
'time_stamp' => time()
);
try{
$result = $punch_obj->setPunch( $punch_data );
if ( $result->isValid() === TRUE ) {
echo "Punch added successfully.\n";
$insert_id = $result->getResult(); //Get punch new ID on success.
} else {
echo "Punch save failed.\n";
print $result; //Show error messages
}
} catch(Exception $e){
echo $e->getMessage();
}
?>
In our implementation, we use automatic punches so that we don’t have to check the “current status” in the punch, and for lunch in TimeTrex. If you want to use lunch punches, you will need to extend the program to do that.
In the community version of the TimeTrex user, fill in the Quick Punch code. This should work as the phone security code.
Note that I put the TimeTrex login user and password straight into the application. A better protocol would be to add it to the /etc/amportal.conf file along with the rest of the usernames and passwords.Also, the path to your timetrex installation directory will vary depending on your base operating system and other features. If you install TimeTrex on your PBX, the file will exist in your filesystem. If the server is remote, you’ll need to copy the TimeTrex API support files to your phone server to make them available to the application.
Step 2 - add the custom dial plan in Asterisk 1.8 or later.
I use FreePBX, so I pop open the “extensions_custom.conf” or even “extensions_override.conf” file and add this context. If you are using a more vanilla Asterisk, you may be able to add it to extensions_additional.conf (or even extensions.conf).
Special Notes - my employee numbers are 4-digits (mine is 0001). The timetrex value is the extension we default from (mine is 500). It’s a default, so that we know what’s going on in the TimeTrex logs later.
[timetrex]
exten => s,1,Set(wait=2)
exten => s,n,Set(length=4)
exten => s,n,Set(timetrex=500)
exten => s,n,Answer
exten => s,n(begin),Playback("silence/1")
exten => s,n,Playback("custom/TimeTrex-clock")
exten => s,n,Read(usernum,"silence/1",${length})
exten => s,n,Wait(1)
exten => s,n,Playback("custom/TimeTrex-pass")
exten => s,n,Read(userpass,"silence/1",${length})
exten => s,n,AGI(timetrex,${usernum},${userpass},${timetrex})
exten => s,n,Hangup
There are lots of things wrong with this script, not the least being there is no report of success or failure. The result values from the app are completely ignored. Maybe version 2 will have that. Make a note of the actual context name: [timetrex] in this case. This needs to mate up with the rest of the stuff later.
Step 3 - Set up the FreePBX environment.
Once you get the edits made, you will need to record the two audio prompts for your system. I used the “record system recordings” method in FreePBX. The “TimeTrex-clock” script is:
"Please enter your four digit employee number."
The “TimeTrex-pass” script is:
"Please enter your four digit passcode."
Once you’re done with that, you will need to add the custom destinations.
Using the “Custom Destinations” menu, add the Custom Destination your system will be able to connect to the at the “s” extension in your “timetrex” custom context. Add a “Custom Destination” called “timetrex,s,1”. Remember when I said to remember the context name - here you go. The Description is the name of the Custom Destination. I called mine “TimeTrex Custom Destination”.
Next, Edit “Miscellaneous Applications” to connect the custom context to a feature code. The description is whatever you want it to be, the feature code should be an unused feature code (I used *13, since the agent log-in and log-out use *11 and *12). Be sure to set the feature status to “Enabled”. The destination is under “Custom Destinations” - the “TimeTrex Custom Destination” from the Custom Destination above.
So, to summarize:
- add the context in extensions_custom.conf file.
- add a custom-context that identifies your new context to the FreeePBX system.
- Use that custom-destination to add the miscellaneous application so that you can assign the feature code to the system.