Script types
These are the types of scripts that are supported:
Platform with security token authentication, using username and password:
import com.fasterxml.jackson.annotation.JsonProperty
import com.workbrain2.clocks.publ.api.ClocksPublicServiceAccess
import com.workbrain2.clocks.publ.api.domain.SwipePubl
import com.workbrain2.clocks.publ.api.domain.gateway.RESTRequestPubl
import com.workbrain2.clocks.publ.api.domain.gateway.RESTResponsePubl
import com.workbrain2.clocks.publ.api.domain.gateway.ResponsePubl
import com.workbrain2.clocks.publ.api.gateway.SwipeReceiverScriptable
import com.workbrain2.clocks.publ.api.gateway.SwipeRecevierBuilderPubl
import com.workbrain2.platform.publ.api.DebugPrint
import java.time.ZoneId
class PlatformReceiverExample extends SwipeReceiverScriptable{
SwipeRecevierBuilderPubl builder = ClocksPublicServiceAccess.getSwipeRecevierBuilderPubl()
TokenLocal token
int driverFieldLength = 7
@Override
String getName() {
return "PlatformSyncExample"
}
private String driver(){
return addLeadingZeroes("99968")
}
String addLeadingZeroes(String driver){
if (null == driver){
return ""
}
int length = driver.length()
if (length >= driverFieldLength){
return driver
}
return ("000000000" + driver).substring(driverFieldLength)
}
@Override
ResponsePubl acceptSwipe() {
if (!isSwipeAccepted()){
ResponsePubl responsePubl = builder.buildResponse()
responsePubl.setStatusCode(ResponsePubl.SC_OK)
return responsePubl
}
ResponsePubl tokenResponse = fetchOrLoadToken()
if (null != tokenResponse){
return tokenResponse //error getting token from the server, cannot recover now
}
RESTRequestPubl request = dutyStatusRequest(dutyStatus(getContext().getSwipe()), token)
RESTResponsePubl<String> response = request.make(String.class)
//check if cached token worked well, if not, reload it
if(response.statusCode() != ResponsePubl.SC_OK){
tokenResponse = fetchOrLoadToken()
if (null != tokenResponse){
return tokenResponse //error getting token from the server, cannot recover now
}
request = dutyStatusRequest(dutyStatus(getContext().getSwipe()), token)
response = request.make(String.class)
}
DebugPrint.debugprint("Got response: " + response.bodyAsString())
ResponsePubl responsePubl = buildResponseStatus(response)
DebugPrint.debugprint("ACCEPT_SWIPE_PLATFORM_EXAMPLE")
return responsePubl
}
ResponsePubl fetchOrLoadToken(){
if (null == token){
token = getCache().get("token") as TokenLocal
if (null == token){//token has never been fetched yet
ResponsePubl tokenResponse = fetchToken()
if (null == token){ //error with credentials
return tokenResponse
} else {
getCache().put("token", token)
return null
}
}
}
}
ResponsePubl buildResponseStatus(RESTResponsePubl response){
ResponsePubl responsePubl = builder.buildResponse()
responsePubl.setStatusCode(response.statusCode())
if(ResponsePubl.SC_OK != response.statusCode()){
responsePubl.setMessage(response.bodyAsString())
responsePubl.setErrors(response.getResponseDataMap())
}
return responsePubl
}
RESTRequestPubl dutyStatusRequest(DutyStatusLocal status, TokenLocal token){
String auth = token.getType() + " " + token.getValue()
RESTRequestPubl request = builder.buildRestRequest(getContext().getUrl())
.setBody(status)
.addHeader("Authorization", auth)
.addHeader("api-version", "2.0")
return request
}
DutyStatusLocal dutyStatus(SwipePubl swipe){
DutyStatusLocal status = new DutyStatusLocal()
status.driverId = driver()
boolean clockIn = "01" == swipe.getType()
status.status = clockIn ? 4 : 1
status.time = formatTime(swipe.getTime())
status.timezone= ZoneId.systemDefault().getId()
status.comment = clockIn? "On Duty" : "Off Duty"
return status;
}
private ResponsePubl fetchToken(){
RESTRequestPubl request = builder.buildRestRequest(getContext().getTokenUrl())
TokenRequestLocal tokenRequest = new TokenRequestLocal()
tokenRequest.username = getContext().getUserName()
tokenRequest.password = getContext().getUserPassword()
tokenRequest.grantType = "client_credentials"
tokenRequest.scope = "compliance-duty-status"
RESTResponsePubl<TokenLocal> response = request.setBody(tokenRequest).make(TokenLocal.class)
if (ResponsePubl.SC_OK == response.statusCode()){
token = response.body()
String auth = token.getType() + " " + token.getValue()
DebugPrint.debugprint("Got token: " + auth)
}
return buildResponseStatus(response)
}
}
class DutyStatusLocal {
@JsonProperty("external_id")
String driverId;
@JsonProperty("duty_status")
int status;
@JsonProperty("timestamp")
String time;
@JsonProperty("timezone")
String timezone;
@JsonProperty("comment")
String comment;
}
class TokenRequestLocal{
@JsonProperty("client_id")
String username;
@JsonProperty("client_secret")
String password;
@JsonProperty("grant_type")
String grantType = "client_credentials";
@JsonProperty("scope")
String scope = "compliance-duty-status";
}
class TokenLocal {
@JsonProperty("token_type")
String type;
@JsonProperty("expires_in")
long expiry;
@JsonProperty("access_token")
String value;
}
Roadnet type using authentication token
import com.fasterxml.jackson.annotation.JsonProperty
import com.workbrain2.clocks.publ.api.ClocksPublicServiceAccess
import com.workbrain2.clocks.publ.api.domain.SwipePubl
import com.workbrain2.clocks.publ.api.domain.gateway.RESTRequestPubl
import com.workbrain2.clocks.publ.api.domain.gateway.RESTResponsePubl
import com.workbrain2.clocks.publ.api.domain.gateway.ResponsePubl
import com.workbrain2.clocks.publ.api.gateway.SwipeReceiverScriptable
import com.workbrain2.clocks.publ.api.gateway.SwipeRecevierBuilderPubl
import com.workbrain2.platform.publ.api.DebugPrint
import com.workbrain2.platform.publ.api.EmployeePublService
import com.workbrain2.platform.publ.api.SystemPublicServiceAccess
class RoadNetReceiverExample extends SwipeReceiverScriptable{
SwipeRecevierBuilderPubl builder = ClocksPublicServiceAccess.getSwipeRecevierBuilderPubl()
@Override
String getName() {
return "RoadNetSyncExample"
}
private String driver(){
return "RoadNet"
}
@Override
ResponsePubl acceptSwipe() {
if (!isSwipeAccepted()){
ResponsePubl responsePubl = builder.buildResponse()
responsePubl.setStatusCode(ResponsePubl.SC_OK)
return responsePubl
}
ClockRequestLocal clockRequest = fillClockRequest(getContext().getSwipe())
DebugPrint.debugprint("ACCEPT_ROADNET_SWIPE")
RESTRequestPubl request = builder.buildRestRequest(getContext().getUrl())
.setBody(clockRequest)
.addHeader("Authorization", getContext().getAuth())
RESTResponsePubl<String> response = request.make(String.class)
ResponsePubl responsePubl = buildResponseStatus(response)
return responsePubl
}
ResponsePubl buildResponseStatus(RESTResponsePubl<String> response){
ResponsePubl responsePubl = builder.buildResponse()
responsePubl.setStatusCode(response.statusCode())
if(ResponsePubl.SC_OK != response.statusCode()){
responsePubl.setMessage(response.bodyAsString())
responsePubl.setErrors(response.getResponseDataMap())
}
return responsePubl
}
private ClockRequestLocal fillClockRequest(SwipePubl swipe){
ClockRequestLocal request = new ClockRequestLocal()
request.driverId = driver()
request.city = "ROUND ROCK"
request.stateName = "Texas"
request.current = true
request.eventType = "Duty Status(WebService)"
request.locationName = "AUSTIN TX SERVICE CTR"
request.editedDate = "/Date(" + formatTime(swipe.getTime()) + ")/"
request.modifiedTime = "/Date(" + formatTime(swipe.getTime()) + ")/"
request.time = "/Date(" + formatTime(swipe.getTime()) + ")/"
request.timeUTC = "/Date(" + formatTime(swipe.getTime()) + ")/"
request.remark = ("IN" == swipe.getType() ) ? "On Duty" : "Off Duty"
request.sequence = " "
request.siteId = "true"
return request
}
private Integer checkStatus(RESTResponsePubl response) {
int statusCode = response.statusCode()
return statusCode
}
}
class ClockRequestLocal{
@JsonProperty("StateName")
String stateName
@JsonProperty("CityName")
String city
@JsonProperty("LocationName")
String locationName
@JsonProperty("DriverID")
String driverId
@JsonProperty("Current")
boolean current
@JsonProperty("Comment")
String comment = ""
@JsonProperty("Remark")
String remark = ""
@JsonProperty("EditedDate")
String editedDate
@JsonProperty("ModifiedTime")
String modifiedTime
@JsonProperty("Time")
String time
@JsonProperty("TimeUTC")
String timeUTC
@JsonProperty("Latitude")
float latitude
@JsonProperty("Longitude")
float longitude
@JsonProperty("OdoMeter")
Double odoMeter
@JsonProperty("EventType")
String eventType
@JsonProperty("RowId")
String rowId
@JsonProperty("Sequence")
String sequence
@JsonProperty("SiteId")
String siteId
@JsonProperty("RecordSID")
String recordSID
}
TruckLoad using SOAP 1.2 protocol
import com.workbrain2.clocks.publ.api.ClocksPublicServiceAccess
import com.workbrain2.clocks.publ.api.domain.SwipePubl
import com.workbrain2.clocks.publ.api.domain.gateway.ResponseCodePubl
import com.workbrain2.clocks.publ.api.domain.gateway.ResponsePubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPBodyPubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPClientPubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPElementPubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPEnvelopePubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPHeaderPubl
import com.workbrain2.clocks.publ.api.domain.gateway.SOAPMessagePubl
import com.workbrain2.clocks.publ.api.gateway.SwipeReceiverScriptable
import com.workbrain2.clocks.publ.api.gateway.SwipeRecevierBuilderPubl
import com.workbrain2.platform.publ.api.DebugPrint
class TruckLoadReceiverExample extends SwipeReceiverScriptable {
private static final String nameSpace = "http://www.omnitracs.com"
private static final String securityUrl = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
SwipeRecevierBuilderPubl builder = ClocksPublicServiceAccess.getSwipeRecevierBuilderPubl()
@Override
String getName() {
return "TruckLoadExample"
}
private String driver(){
return "0900407"
}
@Override
ResponsePubl acceptSwipe() {
if (!isSwipeAccepted()){
ResponsePubl responsePubl = builder.buildResponse()
responsePubl.setStatusCode(ResponsePubl.SC_OK)
return responsePubl
}
SOAPClientPubl soap = builder.buildSoapClient(getContext().getUrl())
SOAPMessagePubl message = soap.createMessage()
message.addHeader("SOAPAction", "http://www.omnitracs.com/ClockInOut")
SOAPEnvelopePubl envelope = message.getEnvelope()
setBody(envelope.getBody(), getContext().getSwipe())
setHeader(envelope.getHeader())
String bodyAsString = soap.bodyAsString(message)
DebugPrint.debugprint("SOAP request: " + bodyAsString)
ResponsePubl responsePubl = builder.buildResponse()
if (message.saveChanges()) {
DebugPrint.debugprint("ACCEPT_TRUCKLOAD_SWIPE")
SOAPMessagePubl response = soap.post(message)
if (null != response) {
DebugPrint.debugprint("SOAP response: " + soap.bodyAsString(response))
DebugPrint.debugprint("ACCEPT_TRUCKLOAD_SWIPE")
ResponseCodePubl responseCode = getResponseCode(soap, response)
DebugPrint.debugprint("ResponseCode: " + responseCode.toString())
if (null != responseCode) {
responsePubl.setStatusCode(ResponsePubl.SC_OK)
} else {
responsePubl.setMessage(soap.bodyAsString(response))
responsePubl.setStatusCode(ResponsePubl.SC_BAD_REQUEST)
}
return responsePubl
}
}
responsePubl.setStatusCode(ResponsePubl.SC_SERVER_ERR)
responsePubl.setMessage("Unknown error, see log for details")
return responsePubl
}
ResponseCodePubl getResponseCode(SOAPClientPubl client, SOAPMessagePubl message){
SOAPElementPubl body = client.getSOAPBody(message)
if (null == body){
return null
}
SOAPElementPubl codeElement = client.getFirstElement(body, "ClockInOutResponse", "ClockInOutResult", "ResponseCode")
if (null != codeElement){
return ResponseCodePubl.fromValue(codeElement.getTextContent())
}
return null
}
private void setBody(SOAPBodyPubl body, SwipePubl swipe){
SOAPElementPubl clockInOut = body.addChildElement("ClockInOut", "omn", nameSpace)
SOAPElementPubl request = clockInOut.addChildElement("clockInOutRequest", "omn", nameSpace)
request.addChildElement("DriverID", "omn", nameSpace).addTextNode(driver())
setReaderInfo(request, swipe)
request.addChildElement("Action", "omn", nameSpace).addTextNode("ClockIn")
request.addChildElement("EffectiveTime", "omn", nameSpace).addTextNode(formatTime(swipe.getTime()))
}
private SOAPElementPubl setHeader(SOAPHeaderPubl header){
String prefix = "wsse";
SOAPElementPubl security = header.addChildElement("Security", prefix, securityUrl)
SOAPElementPubl usernameToken = security.addChildElement("UsernameToken", prefix)
usernameToken.addChildElement("Username", prefix).addTextNode(getContext().getUserName())
usernameToken.addChildElement("Password", prefix).addTextNode(getContext().getUserPassword())
return security
}
private void setReaderInfo(SOAPElementPubl request, SwipePubl swipe){
Double latitude = swipe.getReaderLatitude()
String lat = null != latitude ? latitude.toString() : ""
request.addChildElement("State", "omn", nameSpace).addTextNode("TX")
Double longitude = swipe.getReaderLongitude()
String lon = null != longitude ? longitude.toString() : ""
request.addChildElement("City", "omn", nameSpace).addTextNode("HOUSTON")
}
}