-
Notifications
You must be signed in to change notification settings - Fork 0
Home
This wiki documents the various ways of remotely interacting with the application. The RESTful JSON API can be consumed by clients written in any language. A SOAP API also exists and offers the same capabilities.
The application offers full 100% API coverage of all actions and operations that it performs. In fact the application's web interface actually utilizes the API itself in the background, so any operation that you can do from the UI can be easily done through the API too.
Each class that can be called from the API has its own Wiki page. See those for detailed functions and arguments for each.
If you simply need to import or export data (ie: employees, timesheets, or reports), consider the easy to use remote command line tools which are described in the latter part of this document and included in this repo.
To get started, lets define a couple helper functions to do most of the heavy lifting for us:
//Build URL given a Class and Method to call.
//Format is: http://{{YOUR DOMAIN NAME}}/api/json/api.php?Class=<CLASS>&Method=<METHOD>&SessionID=<SessionID>
function buildURL( $class, $method, $session_id = FALSE ) {
global $URL, $SESSION_ID;
$url = $URL.'?Class='.$class.'&Method='.$method;
if ( $session_id != '' OR $SESSION_ID != '' ) {
if ( $session_id == '' ) {
$session_id = $SESSION_ID;
}
$url .= '&SessionID='.$session_id;
}
return $url;
}
//Handle complex result.
function handleResult( $result, $raw = FALSE ) {
if ( is_array($result) AND isset($result['api_retval'])) {
if ( $raw === TRUE ) {
return $result;
} else {
if ( $result['api_retval'] === FALSE ) {
//Display any error messages that might be returned.
$output[] = ' Returned:';
$output[] = ( $result['api_retval'] === TRUE ) ? ' IsValid: YES' : ' IsValid: NO';
if ( $result['api_retval'] === TRUE ) {
$output[] = ' Return Value: '. $result['api_retval'];
} else {
$output[] = ' Code: '. $result['api_details']['code'];
$output[] = ' Description: '. $result['api_details']['description'];
$output[] = ' Details: ';
$details = $result['api_details']['details'];
if ( is_array($details) ) {
foreach( $details as $row => $detail ) {
$output[] = ' Row: '. $row;
foreach( $detail as $field => $msgs ) {
$output[] = ' --Field: '. $field;
foreach( $msgs as $key => $msg ) {
$output[] = ' ----Message: '. $msg;
}
}
}
}
}
$output[] = '==============================================================';
$output[] = '';
echo implode( "\n", $output );
}
return $result['api_retval'];
}
}
return $result;
}
//Post data (array of arguments) to URL
function postToURL( $url, $data, $raw_result = FALSE ) {
$curl_connection = curl_init( $url );
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 600 );
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt($curl_connection, CURLOPT_REFERER, $url ); //Referred is required is CSRF checks are enabled on the server.
//When sending JSON data to POST, it must be sent as JSON=<JSON DATA>
//<JSON DATA> should be an associative array with the first level being the number of arguments, where each argument can be of mixed type. ie:
// array(
// 0 => <ARG1>,
// 1 => <ARG2>,
// 2 => <ARG3>,
// ...
// )
$post_data = 'json='.urlencode( json_encode($data) );
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_data );
echo "==============================================================\n";
echo "Posting data to URL: ". $url ."\n";
echo " POST Data: ". $post_data ."\n";
echo "--------------------------------------------------------------\n";
$result = curl_exec($curl_connection);
curl_close($curl_connection);
return handleResult( json_decode($result, TRUE ), $raw_result );
}
Next define some global variables that point to our server API end-point and specify the username/password:
/*
Global variables
*/
$URL = 'https://{{YOUR DOMAIN NAME}}/api/json/api.php';
$USERNAME = 'demoadmin';
$PASSWORD = 'demo283920';
Now we should be able to login and obtain a SESSION ID for subsequent API requests:
//IMPORTANT: When passing separate arguments to a function the order must be maintained and proper.
// So when passing named key => value pairs always ensure that the order is preserved when the data is JSON encoded.
$arguments = array( 'user_name' => $USERNAME, 'password' => $PASSWORD );
$SESSION_ID = postToURL( buildURL( 'APIAuthentication', 'Login' ), $arguments );
if ( $SESSION_ID == FALSE ) {
echo "Login Failed!\n";
exit;
}
echo "Session ID: $SESSION_ID\n";
Our connection is setup now, lets grab an employee record by ID:
$arguments = array( 'filter_data' => array(
'id' => 1023
//'user_name' => 'john.doe567',
)
);
$user_data = postToURL( buildURL( 'APIUser', 'getUser' ), array( $arguments ) );
The $user_data variable will now look something like this:
Array
(
[0] => Array
(
[id] => 1023
[company_id] => 1001
[status_id] => 10
[status] => Active
[group_id] => 0
[group] =>
[user_name] => demoadmin1
[phone_id] => 12345
[phone_password] => 12345
[employee_number] => 10
[title_id] => 0
[title] =>
[default_branch_id] => 0
[default_branch] =>
[default_department_id] => 1
[default_department] => Administration
[permission_control_id] => 7
[permission_control] => Administrator (92) #1
[pay_period_schedule_id] => 260
[pay_period_schedule] => USBiWeekly
[policy_group_id] => 9
[policy_group] => Default
[first_name] => Demo
[middle_name] => J
[last_name] => Admin
[second_last_name] =>
[sex_id] => 10
[sex] => MALE
[address1] => Blah
[address2] =>
[city] => Kelowna
[country] => CA
[province] => BC
[postal_code] => V4T1E3
[work_phone] => 555-555-5555
[work_phone_ext] =>
[home_phone] => 555-555-5555
[mobile_phone] => 555-555-5555
[fax_phone] =>
[home_email] => test@democo.com
[work_email] => test@democo.com
[birth_date] => 07-Nov-04
[hire_date] => 07-Nov-04
[termination_date] =>
[currency_id] => 3
[currency] => CAD
[sin] => 1XXXXX789
[note] =>
[deleted] =>
[created_by_id] => 1
[created_by] =>
[created_date] => 08-Nov-04 11:18 AM
[updated_by_id] => 1023
[updated_by] => Demo Admin
[updated_date] => 01-Oct-08 12:49 PM
)
If you would prefer to get multiple employee records at once, you can send an array of arguments like this instead:
$arguments = array( 'filter_data' => array(
'id' => array(1023, 1024),
//'user_name' => array('john.doe567', 'jane.doe890'),
)
);
Now lets update the above employee record and set their status to terminated:
$user_data[0]['status_id'] = 20; //Terminated
$user_data[0]['termination_date'] = '01-Jul-09';
$result = postToURL( buildURL( 'APIUser', 'setUser' ), array( $user_data[1] ) );
if ( $result === TRUE ) {
echo "Employee data saved successfully.\n";
} else {
echo "Employee save failed.\n";
print $result; //Show error messages
}
If you prefer to update an employee record without first getting it, just specify the 'id' field along with the ones you want to change like this:
$user_data = array(
'id' => 1023,
'termination_date' => '02-Jul-09'
);
$result = postToURL( buildURL( 'APIUser', 'setUser' ), array( $user_data ) );
if ( $result === TRUE ) {
echo "Employee data saved successfully.\n";
} else {
echo "Employee save failed.\n";
print $result; //Show error messages
}
What about adding a new employee? Just don't specify a 'id' field and it will automatically know you want to add a new record:
$user_data = array(
'status_id' => 10, //Active
'first_name' => 'Michael',
'last_name' => 'Jackson',
'employee_number' => rand(10000, 99999),
'user_name' => 'mjackson_'. rand(10000, 99999),
'password' => 'whiteglove123',
'hire_date' => '01-Oct-09',
'currency_id' => 3,
);
$result = postToURL( buildURL( 'APIUser', 'setUser' ), array( $user_data ) );
if ( $result !== FALSE ) {
echo "Employee added successfully.\n";
$insert_id = $result; //Get employees new ID on success.
} else {
echo "Employee save failed.\n";
print $result; //Show error messages
}
Here is how we can add punches for employees:
$punch_data = array(
'user_id' => 1023,
'type_id' => 10, //Normal
'status_id' => 20, //In
'time_stamp' => strtotime('19-Aug-2013 5:50PM'),
'branch_id' => 296, //Branch
'department_id' => 896, //Department
'job_id' => 610, //Job
'job_item_id' => 9, //Task
);
$result = postToURL( buildURL( 'APIPunch', 'setPunch' ), array( $punch_data ) );
if ( $result !== FALSE ) {
echo "Punch added successfully.\n";
$insert_id = $result; //Get employees new ID on success.
} else {
echo "Punch save failed.\n";
print $result; //Show error messages
}
Getting report data, by first getting the report config data, then downloading the data in 'raw' (array) format:
$config = postToURL( buildURL( 'APITimesheetSummaryReport', 'getTemplate' ), array( 'by_employee+regular+overtime+premium+absence' ) );
$result = postToURL( buildURL( 'APITimesheetSummaryReport', 'getTimesheetSummaryReport' ), array( $config, 'raw' ) );
echo "Report Data:\n";
var_dump($result);
See https://github.com/staffcheck/api/blob/master/JSON_api_client_example.php for an example implementation.
Please see https://github.com/staffcheck/api/blob/master/Soap_api_client_example.php if you must use the Soap API. The JSON API is considered best practice for newly written API implementations as the data volume and overhead are lower.
To simply import or export data (ie: employees, timesheets, or reports) from a remote from a remote computer without using the API directly, please follow these instructions.
Keep in mind that you still will need to have PHP installed on whichever computer you wish to run these tools from and you will need the soap and openssl extension available.
Once you have the tools extracted you can see a list of arguments for each tool by running the tool with the help flag, here is an example:
php ./import.php --help
Before using the import tool we highly recommend going through an import within the application at least once to make it easier to map your import file columns.
To do this first login to the application then click Company -> Import in the menu along the top of the screen, this will bring up the import wizard which will step you through the import process, be sure to save the map settings on the column mapping step. *Warning: If you do go through the entire import wizard on your live installation this will import data into your application.
Once you have saved the column mapping with the import wizard you will be able to export it to be used with the command line.
Here is an example of exporting a saved mapping named "Default" with the import type "User":
php ./import.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -object User -export_map Default default_employees.map
You should now be able import employees using newly exported mapping file using a command similar to this:
php ./import.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -object User default_employees.map data_to_import.csv
If you want to update existing employees and import new employees in a single operation, use a command similar to this that specifies the "-f update" argument:
php import\import.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -object User -f update default_employees.map data_to_import.csv
Importing punches can be accomplished in a similar way as importing employee records described above. Follow those instructions for exporting a mapping file, then you can import punches with a command similar to this:
php import.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -object Punch punches.map data_to_import.csv
We recommend that you first create a saved report from the application that is customized as needed, then you can simply export that report by name from the command line. Keep in mind saved reports are only accessible by the employee that creates them, so you must use the same username/password when exporting reports.
If the type of report you saved was a TimeSheet Summary report, with the name "MySavedReport", you would export that report using the follow example:
php export_report.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -report TimesheetSummaryReport -saved_report MySavedReport timesheet_summary_report.csv csv
If you need to filter the report based on a specific start/end date rather than using the relative time period such as "Last Pay Period", see this example:
php export_report.php -server https://{{YOUR DOMAIN NAME}}/api/soap/api.php -username admin -password abc123 -report TimesheetSummaryReport -saved_report MySavedReport -time_period custom_date -filter start_date=01-Jan-19,end_date=31-Jan-19 timesheet_summary_report.csv csv
If you wish to utilize the API directly to programmatically perform actions that are not available from the existing tools, please see our API usage in the beginning of this document.