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")
 
    }
 
}