[go: up one dir, main page]

0% found this document useful (0 votes)
285 views508 pages

WTA WorkForce API Specs Guide - 18.3

The document provides API specifications for a workforce time and attendance system. It describes various APIs for functions like ACT cases, scheduling, badge data, imports/exports, and more. The document also includes revision history, legal notices, and a table of contents.

Uploaded by

k82r75m2gc
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
285 views508 pages

WTA WorkForce API Specs Guide - 18.3

The document provides API specifications for a workforce time and attendance system. It describes various APIs for functions like ACT cases, scheduling, badge data, imports/exports, and more. The document also includes revision history, legal notices, and a table of contents.

Uploaded by

k82r75m2gc
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 508

WORKFORCE TIME AND

ATTENDANCE
API Specifications
For use with WT&A 18.3.x
January 2019
WT&A API Specifications 18.3 Document Information

Document Information
Author(s) Rhino, Code Ninjas, and Honey Badgers Teams
Editor Nancy Faerber, Andrew Durand
Owner Iain Shearer
Revision History
Version Date Description Author
1.0 Jan 2017 First published INT Team
2.0 March 2017 Person Data API Example 2 script, changed the Karl J
PersonDataAPI.getAsgnmtRecordForEmployee to
PersonDataAPI.getAsgnmtRecord
3.0 April 2017 Added Time Off Request API, add new method for Timesheet Greg W
Operations API (getCurrentPeriodDates).
4.0 April 2017 Added Swipe Import API Greg W
5.0 November 2017 Added previously undocumented APIs: Generic Export, Incremental CodeNinjas
Export, Export Stage, LD Import, and Policy Mapping. Team
For 17.3, new methods were added to Assignment Group, File
Manager, Job Queue, Person Data, Policy Info, and Policy Set.
6.0 February 2018 Added previously undocumented APIs: Bank Import, Time Entry. CodeNinjas
Added new Appendix consisting of previously undocumented utility: Team
API_UTIL.
7.0 February 2018 New APIs added to support WT&A 18.1.0: LD Data, Retro Trigger, XML CodeNinjas
Reader, and XML Writer Team
Existing APIs enhanced for WT&A 18.1.0: Incremental Export, Time
Entry Import
8.0 March 2018 Added previously undocumented APIs: Decoder, Employee Import Honey
Library, and JS_UTIL Badgers Team
9.0 June 2018 New APIs added to support WT&A 18.2.0: Badge Data, Schedule Data CodeNinjas
Output, Timesheet Exception, and Timesheet Output. and Rhino
Existing APIs enhanced for WT&A 18.2.0: ACT, Assignment Group, Teams
Badge Import, Decoder, Employee Import Library, Export Stage, File
Manager, Generic Export, Incremental Export, Instance Info, LD
Import, Policy Creation, and Timesheet Operations.
For more information about the new and enhanced APIs, refer to the
WT&A Release Notes 18.2.0.
Added previously undocumented APIs: KPI Chart Library, PPI Data
Connector
10.0 October 2018 New APIs added to support WT&A 18.3.0: Advanced Scheduler Data. CodeNinjas
Existing APIs enhanced for WT&A 18.3.0: Assignment Group, Badge and Rhino
Import, File Manager, Job Queue, JS_UTIL (see the Appendix), LD Data, Teams
Retro Trigger, Schedule Detail Output, Swipe Import, Time Entry
Import, Time Off Request, Timesheet Operations, Timesheet Output,
XML Writer.
For more information about the new and enhanced APIs, refer to the
WT&A 18.3 Release Notes.
11.0 January 2019 Removed importDataFromResultsSet method from the LD Import API Andrew D

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 2


WT&A API Specifications 18.3 Document Information

LEGAL NOTICES
Copyright (c) 2000-2018 WorkForce Software, LLC. All rights reserved.

WorkForce Software
38705 Seven Mile Rd.
Livonia, MI 48152

Email address: info@workforcesoftware.com


Web site: http://www.workforcesoftware.com
Sales: 734.542.4100
Fax: 734.542.0635

Workforce Software considers the enclosed information a trade secret. By receiving this information, you agree to keep this
information confidential. This information may not be distributed outside your organization. It may not be duplicated in any way
without the express written consent of WorkForce Software, except that you are given permission to duplicate it in electronic or
printed form for the purpose of distribution within your organization to gather requirements or evaluate our software.

The information supplied is distributed on an "as is" basis, without any warranty. WorkForce Software shall not have any liability to
any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information
contained herein.

Trademark names may appear throughout this material. Rather than list the names and entities that own those trademarks or insert
a trademark symbol with each mention of the trademarked name, WorkForce Software states that it is using those names in editorial
fashion only for the benefit of the trademark owner, with no intention of infringing on the trademark. No mention of a company or
trademark is intended to convey endorsement or other affiliation with WorkForce Software.

If you have been provided this document under any other circumstances, you must contact WorkForce Software at 877-4WFORCE
(877-493-6723) to arrange to have this material returned immediately.

This document was last updated on 30 January 2019.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 3


WT&A API Specifications 18.3 Contents

Contents
About this Document .................................................................................................................................... 6
ACT API .......................................................................................................................................................... 7
ACT Case Export API .................................................................................................................................... 23
Advanced Scheduler API ............................................................................................................................. 36
Advanced Scheduler Data API ..................................................................................................................... 59
Assignment Group API ................................................................................................................................ 69
Badge Data API ............................................................................................................................................ 88
Badge Import API ........................................................................................................................................ 94
Bank Export API ......................................................................................................................................... 118
Bank Import API ........................................................................................................................................ 136
Batch Job Log Policy Tracker API ............................................................................................................... 139
Decoder API .............................................................................................................................................. 142
Email API ................................................................................................................................................... 155
Employee Import Library .......................................................................................................................... 167
Export Stage API ........................................................................................................................................ 185
File Manager API ....................................................................................................................................... 190
File Writer API ........................................................................................................................................... 201
FTP API ...................................................................................................................................................... 207
Generic Export API .................................................................................................................................... 231
Incremental Export API ............................................................................................................................. 243
Instance Info API ....................................................................................................................................... 263
Job Queue API ........................................................................................................................................... 273
KPI Chart Library ....................................................................................................................................... 288
LD Data API................................................................................................................................................ 305
LD Import API ............................................................................................................................................ 308
Line Approval API ...................................................................................................................................... 315
Person Data API ........................................................................................................................................ 322
Policy Creation API .................................................................................................................................... 345
Policy Info API ........................................................................................................................................... 366

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 4


WT&A API Specifications 18.3 Contents

Policy Mapping API ................................................................................................................................... 376


Policy Set API ............................................................................................................................................. 378
PPI Data Connector API ............................................................................................................................. 382
Retro Trigger API ....................................................................................................................................... 389
Schedule Detail Output API....................................................................................................................... 397
SSO API ...................................................................................................................................................... 401
Swipe Import API ...................................................................................................................................... 416
Time Entry Import API ............................................................................................................................... 420
Time Off Request API ................................................................................................................................ 450
Timesheet Exception API .......................................................................................................................... 459
Timesheet Operations API ........................................................................................................................ 463
Timesheet Output API ............................................................................................................................... 480
XML Reader API......................................................................................................................................... 485
XML Writer API.......................................................................................................................................... 487
Appendix: API_UTIL ................................................................................................................................... 491
Appendix: JS_UTIL ..................................................................................................................................... 497

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 5


WT&A API Specifications 18.3 About this Document

About this Document


This document describes the capabilities of the Application Program Interface (APIs) that are available for use
with WorkForce Time and Attendance (WT&A).

Note: With the 17.2.0 release, “EmpCenter” was renamed to “WorkForce Time and Attendance”.
Additionally, the module formerly named "WorkForce Time & Attendance" is now "WorkForce Time".
The term “EmpCenter” appears in this document for backward compatibility purposes.

Intended Audience
• System administrators at customer sites
• WorkForce Software implementation and support teams

• Partner implementation and support teams

Visit the WorkForce Community


Access our online Community to search the Knowledge Base, download release notes and product guides,
open Support cases, and suggest ideas for improving our products.
1. Go to the WorkForce Community login page.
2. Log in with your user ID and password. Your user ID is your email address.
If your email address does not work after attempting to reset your password, contact us at
community@workforcesoftware.com.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 6


WT&A API Specifications 18.3 ACT API

ACT API
Overview and Capabilities
The ACT API provides a mechanism for scripts to use in order to look up information about Absence
Compliance Tracker (ACT) Cases, such as the leave begin/end dates, the status of the Case, and what types of
leave the Case is eligible for. This information can be used as needed by scripts, for example as part of an
ACT Case Export process to look up additional relevant information about the ACT Case being processed for
export.
The ACT API also includes functionality for adding additional case managers to an ACT Case. This can be used
to automate the assignment of ACT Cases to the appropriate case manager(s), instead of requiring those
assignments to be made manually through the ACT web interface.
Additionally, this API also provides a mechanism for importing new ACT Cases and for importing the worked
time history and leave usage details for employees. This can be used as part of the go-live process to
transition leave information and open cases from an external system into ACT, or can be used in an ongoing
manner for customers who are using ACT without the WorkForce Time module in order to maintain the
employees’ current worked time history details.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Basic ACT functionality

Components
This API consists of the following component(s):
• The ACT_API Distributed JavaScript library
• The WorkedTimeRecord, LeaveUsageRecord, ACTCaseScriptable, WorkflowEventScriptable, and
HistoryEventScriptable Java classes

Setup
No setup is necessary for the ACT API. The distributed library is automatically available within WorkForce
Time and Attendance.

Use Cases
Importing Worked Time
The ACT API can be used to import worked time to use in determining eligibility for different leaves. This
time would typically be imported for one of two reasons:
• To load information about time worked prior to the customer switching to WorkForce Time and
Attendance.
• To load ongoing information about time worked if worked time is not being tracked on WorkForce
Time and Attendance timesheets (for customers not using WorkForce Time and Attendance for Time
and Attendance).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 7


WT&A API Specifications 18.3 ACT API

Regardless of which of these two scenarios is present for a customer, the API will import the worked time in
the same manner.

Example 1: Importing generic worked time


Most of the time, the worked time being imported does not have any specific breakdown as to what type of
time it is. (For instance, no distinction is made between regular worked time and overtime.) This is either
because those distinctions are not relevant for the types of leave being used or because that information is
not available.
The following script example demonstrates using the ACT API to import generic worked time:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Define the API to use for importing the worked time


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the worked time record


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
workDate: convertWDate(source.WORK_DATE), // The work date
hours: source.HOURS, // The number of hours worked
comments: source.COMMENTS // Any comments for the time worked
};

// Create the worked time record with the defined settings


var record = new WorkedTimeRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the worked time using all of the records that were added to the cache
api.updateWorkedTimeHistory();

Note: If there is already existing worked time for an employee that has new worked time processed, all of the
existing worked time for that employee with a work date between the earliest and latest work dates in
the new set of data being processed for that employee will be removed and replaced by the new data
being imported.

Example 2: Importing worked time of a specific type


If the type of worked time needs to be explicitly called out, to distinguish between different types of worked
time for leave eligibility purposes, the ACT API supports associating worked time with a pay code. This pay
code defines what type of time was worked on the day by the employee; a given day can have multiple
different pay codes worked by the same employee.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 8


WT&A API Specifications 18.3 ACT API

The following script example demonstrates using the ACT API to import worked time associated with specific
pay codes:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Define the API to use for importing the worked time


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the worked time record


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
workDate: convertWDate(source.WORK_DATE), // The work date
hours: source.HOURS, // The number of hours worked
payCode: source.PAY_CODE, // The type of time worked
comments: source.COMMENTS // Any comments for the time worked
};

// Create the worked time record with the defined settings


var record = new WorkedTimeRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the worked time using all of the records that were added to the cache
api.updateWorkedTimeHistory();

Note: The replacement process for a date range will replace existing worked time records for the employee
regardless of pay code. The import process does not only replace existing records with the pay codes
being imported.

Importing Historic Leave Usage


Eligibility for many types of leave is determined in part by how much leave has been used previously. This
presents a problem for customers during the initial phase after they begin using ACT, since none of that
historical leave usage would have been captured by the ACT module. The ACT API provides a mechanism that
allows historic leave usage information that has previously been tracked in external systems to be loaded into
WorkForce Time and Attendance so that ACT can correctly calculate eligibility during the initial phase after
ACT is deployed.

Example 1: Importing leave usage


The following script example demonstrates a basic import of leave usage information:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 9


WT&A API Specifications 18.3 ACT API

// Define the API to use for importing the leave usage


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the leave usage record


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
leaveDate: convertWDate(source.LEAVE_DATE), // The date leave was used
leaveType: "DIST_US_FED_FMLA", // The type of leave used
hours: source.HOURS, // The amount of leave used
comments: source.COMMENTS // Any comments for the usage
};

// Create the leave usage record with the defined settings


var record = new LeaveUsageRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the leave usage using all of the records that were added to the cache
api.updateLeaveUsage();

Note: If any of the employees with historic leave usage imported already have existing leave usage that was
previously imported, that existing leave usage will be removed and replaced by the new data being
imported.

Example 2: Importing leave usage associated with a first-usage date


While in many cases leave is tracked using a rolling window (such as a calendar year), in some cases leave
eligibility may be determined based on a date of first usage for the leave. The ACT API allows for a first-usage
date to be specified on all leave usage records being imported. This lets ACT correctly calculate eligibility
based on that history.
The following script example demonstrates importing leave usage associated with first-usage dates:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Define the API to use for importing the leave usage


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the leave usage record


var parms = {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 10


WT&A API Specifications 18.3 ACT API

displayEmployee: source.EMPLOYEE_ID, // The employee ID


leaveDate: convertWDate(source.LEAVE_DATE), // The date leave was used
leaveType: "DIST_US_FED_FMLA", // The type of leave used
hours: source.HOURS, // The amount of leave used
firstUsageDate: convertWDate(source.FIRST_USE), // First-usage date
comments: source.COMMENTS // Any comments for the usage
};

// Create the leave usage record with the defined settings


var record = new LeaveUsageRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the leave usage using all of the records that were added to the cache
api.updateLeaveUsage();

Example 3: Specifying values to use in conversion to leave units


Many leaves are officially tracked in units other than hours, such as days or weeks. Imported leave usage
expects to receive the amount of leave used measured in hours, which then gets converted to the
appropriate leave unit during the import process. For instance, for an employee who normally works 40
hours per week, 8 hours of leave usage might be converted into 0.2 weeks of leave usage.
The specific mechanism for these conversions is defined in the ACT configuration. However, most of those
methods rely on employee attribute values, such as the employee’s standard daily hours or standard weekly
hours. Since those values could have changed over time prior to the employee data that exists in WorkForce
Time and Attendance, the ACT API allows the values that should be used for those attributes to be specified
on the leave usage records being imported.
The following script example demonstrates specifying the standard daily hours, standard weekly hours, and
FTE percentage for the employee on the leave usage records being imported by the ACT API:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Define the API to use for importing the leave usage


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the leave usage record


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
leaveDate: convertWDate(source.LEAVE_DATE), // The date leave was used
leaveType: "DIST_US_FED_FMLA", // The type of leave used
hours: source.HOURS, // The amount of leave used
stdDailyHours: source.DAILY_HOURS, // The usage date’s daily hours
stdWeeklyHours: source.WEEKLY_HOURS, // The usage date’s weekly hours
fte: source.FTE_PERCENT, // The usage date’s FTE
comments: source.COMMENTS // Any comments for the usage
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 11


WT&A API Specifications 18.3 ACT API

// Create the leave usage record with the defined settings


var record = new LeaveUsageRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the leave usage using all of the records that were added to the cache
api.updateLeaveUsage();

Example 4: Defining a custom leave unit conversion function


If the configuration-defined conversion process cannot be used (for example, if the configuration is trying to
evaluate a formula to determine the value in the correct leave units), the ACT API allows a custom conversion
function to be defined. This function receives all of the different attribute values that would normally go into
the determination of the correct value in leave units, and allows the scripting to evaluate them to determine
the correct value to use.
The following script example demonstrates using a conversion function to calculate the value in leave units to
use when importing leave usage with the ACT API:
includeDistributedPolicy("ACT_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Define the API to use for importing the leave usage


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Define the conversion function that should be used to compute the correct usage
// in leave units
function convertHoursToLeaveUnits(employee, leaveDate, hours, leaveUnit, stdDailyHours,
stdWeeklyHours, fte) {
// The returned value should be the leave usage converted from hours into the
// appropriate leave units
return hours / stdWeeklyHours;
}

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the leave usage record


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
leaveDate: convertWDate(source.LEAVE_DATE), // The date leave was used
leaveType: "DIST_US_FED_FMLA", // The type of leave used
hours: source.HOURS, // The amount of leave used
stdDailyHours: source.DAILY_HOURS, // The usage date’s daily hours
stdWeeklyHours: source.WEEKLY_HOURS, // The usage date’s weekly hours
fte: source.FTE_PERCENT, // The usage date’s FTE
conversionFunction: convertHoursToLeaveUnits, // The conversion function
comments: source.COMMENTS // Any comments for the usage
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 12


WT&A API Specifications 18.3 ACT API

// Create the leave usage record with the defined settings


var record = new LeaveUsageRecord(parms);

// Add the record into the cache of records to be processed


api.addRecord(record);
}

// Update the leave usage using all of the records that were added to the cache
api.updateLeaveUsage();

Importing a New ACT Case


The ACT API can be used to import new ACT Cases. This would typically be used as part of the go-live process
for a customer using ACT in order to transfer information about cases being tracked in an external system
into ACT.
The following script example demonstrates using the ACT API to create a new ACT Case:

Example: Importing a new ACT Case


includeDistributedPolicy("ACT_API");

// Define the API to use for importing new cases


var api = new AbsenceCaseAPI();

// Get the source data in some fashion. Assuming a standard ResultSet is returned
// here
var source = getSourceData();

// Iterate over all of the records in the source data


while (source.next() ) {

// Define the parameters for the ACT Case


var parms = {
displayEmployee: source.EMPLOYEE_ID, // The employee ID
beginDate: convertWDate(source.START_DATE), // The case start date
endDate: convertWDate(source.END_DATE), // The case end date
leaveTypes: ["DIST_US_FED_FMLA"], // The leave types for the case
reason: source.REASON, // The reason for the case
caseStatus: "OPEN", // The status for the case
caseType: "CONTINUOUS", // The type of case
personAffected: source.PERSON_AFFECTED // The person affected
comments: source.COMMENTS // Any comments for the case
};

// Create the ACT Case


api.importNewACTCase(parms);
}

Note: The ACT API cannot be used to import updates to existing cases.

Assigning Additional Case Managers to an ACT Case


The ACT API can be used to assign additional case managers to an ACT Case. This would typically be used to
mass assign multiple case managers to a single ACT Case or multiple ACT Cases.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 13


WT&A API Specifications 18.3 ACT API

The following script example demonstrates using the ACT API to assign an additional case manager to an ACT
Case:

Example: Assigning an additional case manager to an ACT Case


includeDistributedPolicy("ACT_API");

// Define the API to use for assigning additional case managers


var api = new AbsenceCaseAPI();

// Do something to get the ID of the case to be assigned to additional case managers. This is
// assumed to return an ID for an existing ACT Case.
var actCaseId = getExistingActCaseId();

// Get the loginId of the case manager that is to be assigned to the existing ACT Case. This
// is assumed to return a loginId for a user that has rights to become a ACT case manager.
var caseManagerId = getCaseManagerLoginId();

// Assign the caseManagerId to the actCaseId.


api.assignCaseManager(actCaseId, caseManagerId);

Looking Up Existing ACT Case Data


The ACT API can be used to look up information about existing ACT Cases. This would be done as part of a
larger process—such as an ACT Case Export—in order to retrieve additional information about an ACT Case.

Example 1: Looking up a specific ACT Case


If you have the ID of the specific ACT Case you’re interested in available, the ACT API can return the
information for that specific Case directly. The following script example demonstrates using the ACT API to
look up information for a known ACT Case:
includeDistributedPolicy("ACT_API");

// Do something to get the ID of the case to be looked up. This is assumed to return
// an ID for an existing ACT Case
var actCaseId = getExistingActCaseId();

// Use the ACT API to look up information for the case


var actCase = AbsenceCaseAPI.getACTCase(actCaseId);

// Print out relevant information about the case


log.info("ACT Case ID is " + actCase.act_case);
log.info("Case belongs to employee " + actCase.employee);
log.info("Case runs from " + actCase.start_date + " through " + actCase.end_date);

// Print out information about history events associated with the case
var historyEvents = actCase.getHistoryEvents();
for (var i = 0; i < historyEvents.length; ++i) {
var historyEvent = historyEvents[i];
log.info("Case has history event of type " + historyEvent.act_history_event_type+
" with order " + historyEvent.event_history_order);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 14


WT&A API Specifications 18.3 ACT API

Example 2: Looking up all ACT Cases for an employee


The ACT API can also be used to look up information for all ACT Cases belonging to a particular employee, in
case the script needs to do further evaluation to determine which Case to evaluate or needs to operate on
several different Cases.
The following script example demonstrates using the ACT API to look up all ACT Cases for employee 12345
that are currently in either an APPROVED or OPEN status:
includeDistributedPolicy("ACT_API");

// Define the criteria for the employee whose cases should be found
var criteria = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",
MatchOperator.EQUALS, "12345");

// Define the date the criteria should be evaluated as of


var asOfDate = WFSDate.today();

// Define the statuses that the returned cases need to be in


var statuses = ["APPROVED", "OPEN"];

// Get the ACT cases for the employee


var actCases = AbsenceCaseAPI.getACTCasesForEmployee(criteria, asOfDate, statuses);

// Iterate over the cases for the employee and perform necessary actions
log.info("Employee has the following ACT Cases:");
for (var i = 0; i < actCases.length; ++i) {
var actCase = actCases[i];
log.info("Case " + actCase.act_case + ", for dates " + actCase.start_date +
" through " + actCase.end_date);
}

Example 3: Looking up eligible leaves for a specific ACT Case


The ACT API can be used to extract eligible leaves for a specific case.
The following example can be used to get all the eligible leaves for the provided ACT Case:
includeDistributedPolicy("ACT_API");

// Get the eligible leaves for specified ACT case


// It takes caseId (String) as input
var leaves = AbsenceCaseAPI.getEligibleLeaves("353");

// Iterate over the leaves for the case and perform necessary actions
log.info("Case has the following leaves:");
for (var i = 0; i < leaves.length; ++i) {
var leave = leaves[i];
log.info("Leave name: " + leave);
}

Example 4: Getting leave usages for a specific ACT Case


The ACT API can be used to get leave usages for a specific ACT case.
When an ACT Case ID along with the start and end date are passed, it returns records of leave usages to be
used as per the requirements.
Records can also be filtered on other parameters:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 15


WT&A API Specifications 18.3 ACT API

startDate (WFSDate) - start date to filter records


endDate (WFSDate) - end date to filter records
caseId (String) - the ID of the case that should be looked up
leaveType (String) - may be null, in which case no condition is enforced for the leave type of the returned
records.

The following example can be used to get all the leave usages for the provided ACT Case:
includeDistributedPolicy("ACT_API");

// Get the leave usages for specified ACT case


var leaveUsages = AbsenceCaseAPI.getLeaveUsageList(WFSDate.valueOf("2018-04-04", "yyyy-MM-
dd"), WFSDate.valueOf("2010-04-05", "yyyy-MM-dd"), "Case1", "DIST_LEAVE_1");

Troubleshooting
The job log of the script using the ACT API will contain information messages and, in the case of problems,
any error messages generated during processing. This job log should be reviewed if there are any problems
encountered while using the API.

Error Message Problem Solution


No ACT case exists with An attempt was made to look up Verify that the ACT Case to be looked
display ID CASE_ID information for an ACT Case using up exists and that its display ID is the
an ID that does not correspond to value that the script is using.
any of the existing ACT Cases.
Check that the criteria correctly
The criteria specified to match an
No employee found matches a single employee and that
employee when looking up the
matching specified criteria: the as-of date being provided is the
employee’s ACT Cases didn’t
CRITERIA correct one to use when evaluating
match any existing employees.
those criteria.
No existing ACT Case with An attempt was made to assign a Verify that the Case ID provided when
display ID CASE_ID found new case manager to an ACT Case assigning new case managers matches
that doesn’t exist. the display ID for an existing ACT
Case.
Specified case manager The general role assigned to the Verify that all users being assigned as
LOGIN_ID is not allowed to specified user does not include the case managers have the necessary
be assigned as a case right system features to allow system features on their general roles
manager for ACT Case them to be assigned as a case in order to act as case managers.
CASE_ID. Please check the manager.
rights associated with this
user if they are supposed to
be able to manage this
case.
Case status STATUS is not a The status specified when creating Ensure that all new Cases being
valid status for a new case a new ACT Case was not a valid created are using a status from the
being imported

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 16


WT&A API Specifications 18.3 ACT API

Error Message Problem Solution


status for a new case to be created defined set of allowed statuses for
with. new Cases.
No reason value specified The definition for a new ACT Case Verify that all new ACT Cases being
did not include a value for the created have a reason value specified.
reason.
Invalid value provided for The value provided for the reason Ensure that the reason value provided
reason code. The allowed when importing a new ACT Case either matches an ACT_REASON policy
values are an actual policy was not a valid value. name or is one of the defined integer
ID or one of the following values that are allowed to be used as
mappings: MAPPINGS aliases.
No begin date specified for No begin date value was provided Ensure that all ACT Cases being
absence when importing a new ACT Case. imported have a begin date specified.
No end date specified for No end date value was provided Ensure that all ACT Cases being
absence when importing a new ACT Case. imported have an end date specified.
End date END_DATE is The end date provided when Ensure that the end date provided for
before begin date importing a new ACT Case is earlier all ACT Cases being imported is on or
BEGIN_DATE than the begin date that was after the begin date for that Case.
provided for that same Case.
No employee ID specified No employee ID was specified Ensure that all ACT Cases being
when importing a new ACT Case. imported have an employee ID
specified.
Employee with ID No existing employees were found Ensure that the employee ID specified
EMPLOYEE_ID does not with the specified employee ID on for all ACT Cases being imported
exist as of DATE the indicated date when importing matches an existing employee in
a new ACT Case. WorkForce Time and Attendance.
No employee ID specified An attempt was made to create a Ensure that an employee ID is
for LeaveUsageRecord new LeaveUsageRecord without an specified for all LeaveUsageRecords
employee ID specified. that are being created.
No leave date specified for An attempt was made to create a Ensure that a leave date is specified
LeaveUsageRecord for new LeaveUsageRecord without a for all LeaveUsageRecords that are
employee EMPLOYEE_ID leave date specified. being created.
Conversion function did not The custom conversion function Ensure that all custom conversion
return a value as expected specified on a LeaveUsageRecord functions return a value.
did not return a value.
Conversion function The custom conversion function Ensure that all custom conversion
returned an invalid value. specified on a LeaveUsageRecord functions return a numeric value.
Value is expected to be of returned a value with a non-
type number, but instead it numeric data type.
was VALUE (TYPE)
Invalid value provided for A non-function value was provided Ensure that all conversion functions
conversion function. It is for the custom conversion function specified are defined as functions.
expected to be a function, on a LeaveUsageRecord.
but instead it was of type
TYPE

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 17


WT&A API Specifications 18.3 ACT API

Error Message Problem Solution


Conversion function does The custom conversion function Ensure that all conversion functions
not include the expected specified on a LeaveUsageRecord is defined expect the correct number of
number of arguments. It expecting an incorrect number of arguments to be defined.
includes arguments based on the number of
NUMBER_OF_ARGUMENTS arguments the API will be passing
arguments, when it’s into it.
expected to include 7
arguments
No leave type specified for An attempt was made to create a Ensure that a leave type is specified
LeaveUsageRecord for new LeaveUsageRecord without a for all LeaveUsageRecords that are
employee EMPLOYEE_ID leave type specified. being created.
No employee ID specified An attempt was made to create a Ensure that an employee ID is
for WorkedTimeRecord new WorkedTimeRecord without specified for all WorkedTimeRecords
an employee ID specified. that are being created.
No work date specified for An attempt was made to create a Ensure that a work date is specified
WorkedTimeRecord for new WorkedTimeRecord without a for all WorkedTimeRecords that are
employee EMPLOYEE_ID work date specified. being created.
No history event exists for A call was made to getHistoryEvent Ensure that the History Event order
ACT case with display ID on an ACT Case, specifying a specified when looking up a History
CASE_ID with history event History Event order that does not Event from an ACT Case matches one
order EVENT_ORDER exist for that ACT Case. of the History Events that exists for
that ACT Case.
No workflow event exists A call was made to Ensure that the Workflow Event ID
for ACT case with display ID getWorkflowEvent on an ACT Case, specified when looking up a Workflow
CASE_ID with workflow specifying a Workflow Event ID Event from an ACT Case matches one
event ID EVENT_ID that does not exist for that ACT of the Workflow Events that exists for
Case. that ACT Case.
Table 1: ACT API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The ACT API consists of the following component(s):
1. The AbsenceCaseAPI, which defines a mechanism for importing historic ACT data and for accessing
information about ACT Cases.
2. The WorkedTimeRecord Java class, which defines information for a single slice of worked time
3. The LeaveUsageRecord Java class, which defines information for a single slice of historic leave usage
4. The ACTCaseScriptable Java class, which encapsulates data about an ACT Case and provides methods
for looking up related information
5. The WorkflowEventScriptable Java class, which encapsulates data about a Workflow Event for an
ACT Case and provides methods for looking up related information
6. The HistoryEventScriptable Java class, which encapsulates data about a History Event for an ACT Case
and provides methods for looking up related information

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 18


WT&A API Specifications 18.3 ACT API

The following is a summary of the available methods and common uses:

AbsenceCaseAPI
AbsenceCaseAPI(parms)
Creates a new instance of the Absence Case API. This call accepts the following parameters:
Parameter Name Description
enableDebugging Indicates if additional debug output should be written to the
job log when performing any actions with this instance of
the API. Defaults to false if not specified.
Table 2: Parameters that can be defined when instantiating the Absence Case API

addRecord(record)
Adds an additional historic record (either a WorkedTimeRecord or a LeaveUsageRecord) into the internal
cache for this instance of the API. The data in that cache will be processed by a subsequent call to
updateWorkedTimeHistory or
updateLeaveUsage._WorkedTimeRecord_LeaveUsageRecord_updateWorkedTimeHistory()_updateLeave
Usage()

updateWorkedTimeHistory()
Processes all of the WorkedTimeRecord objects that have been added to the cache for this API using
addRecord. For each employee with new records added, the existing worked time history records will be
replaced for the date range spanned by the new records being processed for that
employee._WorkedTimeRecord_addRecord(record)

updateLeaveUsage()
Processes all of the LeaveUsageRecord objects that have been added to the cache for this API using
addRecord. For each employee with new records added, the existing leave usage records will be replaced by
the new records being processed for that employee._LeaveUsageRecord_addRecord(record)

importNewACTCase(parms)
Creates a new ACT Case using the definition provided by the parameter settings.
Parameter Name Description
displayEmployee The ID of the employee that the absence case is for.
beginDate The starting date of the absence.
endDate The ending date of the absence.
leaveTypes Array of different leave types that apply to the case. Can include both distributed
or customer-defined leave types.
reason The reason for the absence. Needs to match the name of a defined ACT_REASON
policy or one of the following integer values:
1 (DIST_PREGNANCY)
2 (DIST_DONATION)
3 (DIST_SELF_HEALTH_CONDITION)
4 (DIST_OTHER_PERSON_HEALTH_CONDITION)
5 (DIST_CHILD_BONDING)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 19


WT&A API Specifications 18.3 ACT API

6 (DIST_CHILD_PLACEMENT)
7 (DIST_MILITARY_EXIGENCY)
8 (DIST_MILITARY_DEPLOYMENT)
9 (DIST_CRIME_VICTIM)
10 (DIST_OTHER)
caseStatus The status the case should be in after it is created. Valid statuses are: PENDING,
OPEN, APPROVED, CLOSED.
workflowEvent The Workflow Event to use when creating the case. Defaults to
IMPORT_APPROVED_CASE if not specified.
caseType Defines what type of absence is reflected by the case. Valid values are:
CONTINUOUS, INTERMITTENT, or REDUCED_SCHEDULE. Defaults to CONTINUOUS
if not specified.
personAffected Identifies the person affected by the reason for the absence. Valid values are SELF,
SPOUSE, DOMESTIC PARTNER, CHILD, PARENT, or OTHER. Defaults to SELF if not
specified.
comments Any comments associated with the absence case
Table 3: Parameters that can be defined when creating a new ACT Case

assignCaseManager(caseId, loginId)
Adds the user with the specified loginId value as a case manager for the ACT Case with the indicated display
ID. The user being assigned as a case manager must have a general role that allows them to act as a case
manager, otherwise they will be unable to be assigned the case.

getACTCasesForEmployee(criteria, asOfDate, statuses)


Returns an array containing information for all of the ACT Cases that exist for the employee defined by the
specified criteria and asOfDate. This array can optionally be filtered to include only ACT Cases that are
currently in a specific status or statuses by specifying the desired statuses that should be returned.

getACTCase(caseId)
Returns information for the ACT Case with the specified display ID.

getEligibleLeaves (caseId)
Returns eligible leaves for the specified ACT case.

getLeaveUsageList(startDate, endDate, caseId, leaveType)


Returns leave usage records for the specified ACT case.

WorkedTimeRecord
WorkedTimeRecord(parms)
Creates a new immutable WorkedTimeRecord object containing the settings defined by the specified
parameters. Parameters that can be defined include:

Parameter Name Description

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 20


WT&A API Specifications 18.3 ACT API

displayEmployee The ID of the employee that the worked time is associated with
workDate The date that the worked time is associated with
hours The number of hours worked on the work date
payCode The type of worked time represented by this record
comments Any comments associated with this record
Table 4: Parameters that can be defined when creating a new WorkedTimeRecord

LeaveUsageRecord
LeaveUsageRecord(parms)
Creates a new immutable LeaveUsageRecord object containing the settings defined by the specified
parameters. Parameters that can be defined include:
Parameter Name Description
displayEmployee The ID of the employee associated with the leave.
leaveDate The date that the leave was used on.
leaveType The type of leave used. This needs to match either a distributed or a customer-
specific leave type policy.
hours The amount of leave used on the specified date.
comments Any comments associated with the leave usage.
stdDailyHours The employee’s standard daily hours on the date the leave was used. Based on
the ACT configuration, this may be used to convert the hours into the
appropriate leave units.
stdWeeklyHours The employee’s standard weekly hours on the date the leave was used. Based
on the ACT configuration, this may be used to convert the hours into the
appropriate leave units.
fte The employee’s full time equivalent (FTE) percentage on the date the leave was
used. Based on the ACT configuration, this may be used to convert the hours
into the appropriate leave units.
firstUsageDate The first-usage date for the leave.
conversionFunction A custom function that should be used to calculate the correct leave units for
the record instead of using the method defined in the configuration.
Table 5: Parameters that can be defined when creating a new LeaveUsageRecord

ACTCaseScriptable
getHistoryEvent(eventOrder)
Returns the History Event that is defined with the specified History Event order value for this ACT Case.

getHistoryEvents()
Returns all the History Events associated with this ACT Case, ordered by History Event order from earliest to
latest.

getWorkflowEvent(eventId)
Returns the Workflow Event with the specified ID that is associated with this ACT Case.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 21


WT&A API Specifications 18.3 ACT API

getWorkflowEvents()
Returns all the Workflow Events associated with this ACT Case.

WorkflowEventScriptable
getRelatedHistoryEvent()
Returns the History Event that is linked to this Workflow Event.

getRollbackHistoryEvent()
Returns the History Event that caused this Workflow Event to be rolled back.

HistoryEventScriptable
getRelatedWorkflowEvent()
Returns the Workflow Event that is linked to this History Event.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 22


WT&A API Specifications 18.3 ACT Case Export API

ACT Case Export API


Overview and Capabilities
The ACT (Absence Compliance Tracker) Case Export API provides a framework for identifying which ACT Cases
have had certain types of changes since the last time the export was run. This data is made available to the
calling script to allow it to take whatever action is needed. Some common uses of this API include updating
the HR system with information about employees’ leaves of absence or generating email notifications to
users when certain types of changes are made to ACT Cases.
This API provides also provides a mechanism for looking for information about the previous data that was
processed for a case, allowing a script to use both the “before” and “after” values from a change during
processing. This can include changes to standard fields on the ACT Case record, or custom values derived
during processing.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Basic ACT Case information, including how status changes and case dates work

Components
This API consists of the following component(s):
1. The Distributed JavaScript Library ACT_CASE_EXPORT_API
2. ActCaseExportRecord which describes a single ACT case

Setup
No setup is necessary for the ACT Case Export API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Initializing the ACT Case Export API
The main use for the ACT Case Export API is to detect changes that have happened to relevant ACT Cases
since the last time that the export was run. An ACT Case is considered relevant to the export if one of the
following conditions is true:
1) The ACT Case currently has a status with a higher rank than the minimum specified when initializing
the export (see ACT Case statuses table below.)
2) The ACT Case has already been exported during a previous run of the ACT Case Export
When the ACT Case Export API is initialized, one of the arguments provided specifies the minimum status a
case needs to have in order to be considered eligible for inclusion in the export. This is because many uses of
the ACT Case Export would not want to include cases as soon as they are created; for instance, a process that
wants to update the HR system with information about whether an employee is on leave probably doesn’t
want to update HR immediately when the employee submits the case, but rather would want to wait until

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 23


WT&A API Specifications 18.3 ACT Case Export API

the case manager has actually approved the case as valid before updating HR. The hierarchy of statuses is as
follows:
ACT Case Status Level
PENDING 0
OPEN 1
APPROVED 2
CANCELLED 3
CLOSED
DELETED
DENIED
Table 6: ACT Case statuses and their order of precedence

Only cases whose status is at the same or a higher level than the minimum status specified when initializing
the ACT Case Export API will be processed by the export (if they have not previously been exported already).
In addition to the case’s status, the ACT Case Export API will also look at which history event triggers have
been generated for a case since the last time it ran. This allows the export to control which cases it’s
interested in: depending on how it’s being used, the process may need to find cases that have had certain
types of data changes (such as the beginning or ending date of the absence having changed), cases that have
had documents attached, or if the case’s status has changed.
Each run of the ACT Case Export needs to be associated with an export process ID. This ID is used to allow
the ACT Case Export API to track multiple independent sets of changes to ACT Cases by associating those
changes with a particular ID, in the event that there are multiple jobs in a configuration that are dependent
on those changes. Each time the ACT Case Export is run it will only find changes relative to the last time the
export was run for that same export process ID. (For example, a customer could have a job to send out
emails when a case is created and a second job to update HR with absence information once the case
becomes approved. In this example each of these two jobs should be associated with a different export
process ID, so that the changes detected by one job can also be picked up by the other job.)
The following examples demonstrate some scenarios where the API is initialized to identify changes based on
several different ACT Case statuses and history event triggers:

Example 1: Identifying approved cases with status or absence date changes


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID.


// Only previously-processed ACT Case data associated with an export process
// ID of "Export Job 1" would be taken into account by the API in this case.
var exportProcessId = "Export Job 1";

// Define the minimum status an ACT Case needs in order to be exported.


// Only cases that have already been approved will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for cases where the begin/end date of the case has
// changed or where the case has been deleted or cancelled
var historyEventTriggers = ["CASE_DATES_EDITED", "CASE_CANCELLED", "CASE_DELETED"];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 24


WT&A API Specifications 18.3 ACT Case Export API

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Rest of export logic would go here. See other use cases for examples.

Example 2: Identifying open or approved cases with documents attached


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID.


// Only previously-processed ACT Case data associated with an export process
// ID of "Export Job 2" would be taken into account by the API in this case.
var exportProcessId = "Export Job 2";

// Define the minimum status an ACT Case needs in order to be exported.


// Both open and approved cases will be included in this export.
var minimumStatus = "OPEN";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for cases where a new document has been attached.
var historyEventTriggers = ["DOCUMENT_ATTACHED"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Rest of export logic would go here. See other use cases for examples.
Sometimes, in addition to the status and history event triggers, it may be desirable to limit which cases are
processed based on the beginning or ending dates of the absence as well. For instance, the system receiving
the data may not be interested in knowing about a change that was made to an absence after that absence
has already ended. The ACT Case Export API allows for cutoff dates to be specified for both the start date
and end date of the absences; the start date cutoff specifies the latest start date that an absence can have
and still be processed by the export, and the end date cutoff specifies the earliest end date an absence can
have and still be processed.
The following example demonstrates specifying the cut off dates when initializing the ACT Case Export:

Example 3: Limiting changes to cases with dates in a certain range


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of "Export Job 3" would be taken into account by the API in this case.
var exportProcessId = "Export Job 3";

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "PENDING";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 25


WT&A API Specifications 18.3 ACT Case Export API

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_CREATED_BY_ADMIN", "CASE_CREATED_BY_EMPLOYEE"];

// Define the latest start date a case can have to be considered for processing.
// Only cases starting two weeks or less into the future will be exported.
var startDateCutoff = WFSDate.today().addDays(14);

// Define the lastest end date a case can have to be considered for processing.
// Only cases ending 30 days ago or later will be exported.
var endDateCutoff = WFSDate.today().addDays(-30);

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus,
startDateCutoff, endDateCutoff);

// Rest of export logic would go here. See other use cases for examples.

Note: The start date cutoff and end date cutoff do not represent a date range. (That is, the export is not
processing only cases whose absence dates overlap with the range defined by the start date and end
date values.) In almost every case, the end date cutoff should be a date before the start date cutoff.

Getting ACT Case Data


Once the ACT Case Export is initialized, it is possible to get the information for the ACT Cases based on the
settings that are selected. This can be done in one of two ways.
The first way, and simplest option, for getting information about the ACT Cases is to get information about
just the cases that have had changes linked to one of the relevant history event triggers that were specified
during initialization. One scenario where this might be desirable would be to send out notifications when
new cases are first approved. The following example demonstrates how information for these cases can be
retrieved:

Example 1: Getting only the records with new relevant changes


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of "Changes Only Job" would be taken into account by the API in this case.
var exportProcessId = "Changes Only Job";

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_CREATED_BY_ADMIN", "CASE_CREATED_BY_EMPLOYEE"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 26


WT&A API Specifications 18.3 ACT Case Export API

// Load the ACT Case data for the approved cases that have been created and
// not yet exported
var changedCases = api.getModifiedExportRecords();

// Iterate over the records that have been modified and take some sort of action
for (var i = 0; i < changedCases.length; ++i) {
var currentCase = changedCases[i];
log.info("ACT Case " + currentCase.act_case + " has changed");
}
// Close the export once it is finished to commit the fact the records have been
// processed to the database
api.close();
In this example, the API looks for any cases that currently are in an APPROVED status that have had a history
event associated with either the CASE_CREATED_BY_ADMIN or CASE_CREATED_BY_EMPLOYEE triggers
generated since the last time the export ran. Since an ACT Case will only be evaluated once it hits the
APPROVED state, this means that once an ACT Case gets approved it will be returned by the call to
getModifiedExportRecords(). An ACT Case will only ever be returned once in this script, since a Case should
never have a second history event claiming to have created it.
The second option for getting ACT Case information is to get the data not only for the Cases that have
relevant changes, but also for any cases that have previously been exported already. This allows for logic to
be used that aggregates information across all of the currently-relevant ACT Cases, or for cancellation records
to be generated for previously-exported cases if needed. The following example demonstrates how to load
data for all ACT Cases with relevant changes or that have been previously exported:

Example 2: Getting records for all cases that have previously been exported
includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of "Previous Cases Job" would be taken into account by the API in this case.
var exportProcessId = "Previous Cases Job";

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_CREATED_BY_ADMIN", "CASE_CREATED_BY_EMPLOYEE"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Load the ACT Case data for the approved cases that have been created and
// not yet exported, as well as any cases that have already been exported.
var cases = api.getExportRecords();

// Iterate over the records and take some sort of action


for (var i = 0; i < cases.length; ++i) {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 27


WT&A API Specifications 18.3 ACT Case Export API

var currentCase = cases[i];


log.info("ACT Case " + currentCase.act_case + " is being processed");

var hasChanged = currentCase.isChangedSinceLastExport();


if (hasChanged) {
log.info("Case has had relevent history events since the last export!");
case.export_destination = "job log";
}
}
// Close the export once it is finished to commit the fact the records have been
// processed to the database
api.close();

In this example, data for the cases is loaded and isChangedSinceLastExport() is called for each record. This
method will return true if the ACT Case had a change linked to one of the specified history event triggers
since the last time the ACT Case Export was run, or false if the ACT Case had not had such a change. The set
of all ACT Cases where isChangedSinceLastExport() returns true make up the records that would have
been returned by a call to getModifiedExportRecords(), while the ACT Cases where false is returned are
only returned by the getExportRecords() method.
When processing an ACT Case record, the fields on that record can be used to specify a value for the
export_destination field. This tells the ACT Case Export that not only was that record evaluated by the
script, but something was actually done with it. This is used to drive additional behavior that will be
examined in the next use case. The specific value specified for the export_destination doesn’t have any
direct system use, but it is generally recommended to store the location of where the data was sent (e.g. the
file name the data was written to if exporting to a file).

Tracking Custom Data for Export Records


In many scenarios, just knowing that an ACT Case has changed is not sufficient. Often you need to know
various attributes about the ACT Case itself, such as the case begin and end dates, in order to be able to
process or export the data successfully. The ACT Case Export API includes support for both looking up some
of this information and storing it for later reference (such as when generating cancellation records).
The most common data that will need to be looked up would be data from the ACT Case itself. The
addFieldMapping() method of the API can be used to define which fields on the ACT Case are of interest to
the export, and to make the corresponding values available during the export script. This also allows for
custom aliases to be defined for the fields when they are accessed by the script, to make it clearer what the
script is actually doing.
The following example demonstrates how the start and end dates from the ACT Case information can be
made available and used within an export:

Example 1: Tracking data from the ACT Case


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of " Tracking Changes Job" would be taken into account by the API in this case.
var exportProcessId = "Tracking Changes Job";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 28


WT&A API Specifications 18.3 ACT Case Export API

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_DATES_EDITED"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Define the fields from the ACT Case record that should be available to the script.
// The ACT_CASE.START_DATE field will be available as a date-type object aliased as
// "startDate", and the ACT_CASE_.END_DATE field will be available as a date-type
// object aliased as "endDate"
api.addFieldMapping("startDate", "date", "start_date");
api.addFieldMapping("endDate", "date", "end_date");

// Load the ACT Case data for the approved cases that have been created and
// not yet exported, as well as any cases that have already been exported.
var cases = api.getModifiedExportRecords();

// Iterate over the records and take some sort of action


for (var i = 0; i < cases.length; ++i) {
var currentCase = cases[i];

// Pull the needed information about the case


var actCaseId = currentCase.act_case;
var startDate = currentCase.startDate;
var endDate = currentCase.endDate;

log.info("Processing case " + actCaseId);


log.info("Absence dates are from " + startDate + " to " + endDate);
}
// Close the export once it is finished to commit the fact the records have been
// processed to the database
api.close();

In this example, you can see that several calls to addFieldMapping() are made before getting the export
records, and then the appropriate alias is used in order to retrieve the corresponding value during
processing.
In addition to using fields directly from the ACT Case, it can also be desirable to define additional custom
fields that don’t direct map to the ACT_CASE table. These fields can store values as part of the export logic,
and when the API is closed the final values on the records will be persisted to the database. This is useful
when generating cancellations, since this allows the script to access the values that were calculated at the
time during the previous execution of the export. (See the “Getting Previously-Exported Case Data” section
below for more information.)_Getting_Previously-Exported_Case
The following example demonstrates looking up and storing information for custom fields on the export
records being processed:

Example 2: Tracking data from custom calculations


includeDistributedPolicy("ACT_CASE_EXPORT_API");
includeDistributedPolicy("PERSON_DATA_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 29


WT&A API Specifications 18.3 ACT Case Export API

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of " Tracking Changes Job" would be taken into account by the API in this case.
var exportProcessId = " Tracking Changes Job";

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_DATES_EDITED"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Define the fields from the ACT Case record that should be available to the script.
// object aliased as "endDate"
api.addFieldMapping("startDate", "date", "start_date");
api.addFieldMapping("endDate", "date", "end_date");
api.addFieldMapping("employee", "string", "employee");

// Define additional custom fields that should be used to track data


api.addFieldMapping("employeeId", "string");
api.addFieldMapping("actCompany", "string");

// Load the ACT Case data for the approved cases that have been created and
// not yet exported, as well as any cases that have already been exported.
var cases = api.getModifiedExportRecords();

// Define the person data API to use to look up some relevant information
var personDataApi = new PersonDataAPI();

// Iterate over the records and take some sort of action


for (var i = 0; i < cases.length; ++i) {
var currentCase = cases[i];

// Pull the needed information about the case


var actCaseId = currentCase.act_case;
var startDate = currentCase.startDate;
var endDate = currentCase.endDate;

log.info("Processing case " + actCaseId);


log.info("Absence dates are from " + startDate + " to " + endDate);

// These will both log out blank values at this point, since no values have been
// set at this point in the script
log.info("Employee ID = " + currentCase.employeeId);
log.info("ACT Company = " + currentCase.actCompany);

// Lookup the needed information


var employeeCondition = New MatchCondition(MatchTable.EMPLOYEE, "employee",
MatchOperator.EQUALS, currentCase.employee);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 30


WT&A API Specifications 18.3 ACT Case Export API

var employee = personDataApi.getEmployeeRecord(employeeCondition, startDate);

// Set the values on the record being processed


currentCase.employeeId = employee.display_employee;
currentCase.actCompany = employee.act_company;

// Log out the values that have now been set


log.info("Employee ID = " + currentCase.employeeId);
log.info("ACT Company = " + currentCase.actCompany);
}
// Close the export once it is finished to commit the fact the records have been
// processed to the database
api.close();

Note: The only fields that are available by default without calling addFieldMapping() are ACT_CASE and
LAST_EVENT_ORDER_EXPORTED. All other fields from the ACT Case, and any custom fields, must be
defined using that method in order to be available or persisted by the ACT Case Export API.

Getting Previously-Exported Case Data


In many cases, it is desirable to know not only the current state of an ACT Case but also the previous state of
that case. For instance, when the start date of a Case changes it may be desired to not only export the new
start date for the Case but also to export a cancellation record for the Case containing the old start date.
The ACT Case Export API provides a method for retrieving the previously-exported version of the data for an
ACT Case being processed, as shown in this example:

Example: Getting the case data that was previously exported


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Define the export process ID


// Only previously-processed ACT Case data associated with an export process
// ID of "Cancellation Job" would be taken into account by the API in this case.
var exportProcessId = "Cancellation Job";

// Define the minimum status an ACT Case needs in order to be exported.


// Pending, open and approved case statuses will be included in this export.
var minimumStatus = "APPROVED";

// Define which history event triggers will be considered relevant changes.


// In this case, we're looking for new cases that have been created
var historyEventTriggers = ["CASE_DATES_EDITED"];

// Initialize the export with the desired settings


api.initializeExport(exportProcessId, historyEventTriggers, minimumStatus);

// Define fields to be tracked


api.addFieldMapping("startDate", "date", "start_date");
api.addFieldMapping("endDate", "date", "end_date");

// Load the ACT Case data for the approved cases that have been created and

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 31


WT&A API Specifications 18.3 ACT Case Export API

// not yet exported, as well as any cases that have already been exported.
var cases = api.getModifiedExportRecords();

// Iterate over the records and take some sort of action


for (var i = 0; i < cases.length; ++i) {
var currentCase = cases[i];

// Pull the needed information about the case


var actCaseId = currentCase.act_case;
var startDate = currentCase.startDate;
var endDate = currentCase.endDate;

log.info("Processing case " + actCaseId);


log.info("New dates are from " + startDate + " to " + endDate);

// Retrieve the previously-exported data


var oldData = api.getPreviouslyExportedRecord(actCaseId);
if (oldData !== null) {
// Read the previously-exported dates from the old case data
var oldStartDate = oldData.startDate;
var oldEndDate = oldData.endDate;

log.info("Old dates were from " + oldStartDate + " to " + oldEndDate);


}
}
// Close the export once it is finished to commit the fact the records have been
// processed to the database
api.close();

Note: getPreviouslyExportedRecord() will return the most recent record for the indicated ACT Case that had a
non-blank EXPORT_DESTINATION specified. If the EXPORT_DESTINATION is never specified when
processing new records, getPreviouslyExportedRecord() will always return null.

Rolling Back an Export


The ACT Case Export works by identifying ACT Cases that have had particular types of changes since the last
time the export ran. However, because this is building on the state the Cases were in after the last export,
sometimes it is necessary to rollback a prior export to allow those previously-processed changes to be
processed again. This would most often be needed when there is an error in processing that means that the
target system was not able to load the data that was exported.
To roll back a previous run of the export and allow those changes to be reprocessed, the API needs to be
provided with the export process ID and the specific batch job ID of the export to be rolled back. The
following example demonstrates what this would look like:

Example: Rolling back an export


includeDistributedPolicy("ACT_CASE_EXPORT_API");

// Define a new instance of the API


var api = new ActCaseExportAPI();

// Specify the export process ID to be rolled back


var exportProcessId = "Rollback Job";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 32


WT&A API Specifications 18.3 ACT Case Export API

// Specify the batch job ID of the export run to rollback


var jobId = "1001792133628";

// Rollback the prior run of the export


api.rollbackPriorExport(exportProcessId, jobId);

Note: If multiple runs of the export need to be rolled back, the rollback operation needs to be performed for
each of the runs (by specifying its batch job ID), starting with the most recent job and ending with the
oldest.

Troubleshooting
The job log of the script using the ACT Case Export API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


ACT Case Export must be An attempt was made to compute Ensure that initializeExport() is called
initialized before it can be changes to ACT Cases or retrieve before attempting to compute
used information about previously- changes or retrieve information about
exported records without first previously-exported records.
having initialized the ACT Case
Export API.
Unknown event trigger A history event trigger was Ensure that all of the history event
‘TRIGGER_NAME’ specified specified that does not match one trigger types specified are valid types
of the defined options for history of history event triggers.
event trigger types.
Invalid target ACT Case The ACT Case status specified Ensure that the status specified when
status specified. Valid when initializing the ACT Case initializing the ACT Case Export API is
values are ‘PENDING’, Export API was not a valid status. one of the “PENDING”, “OPEN”,
‘OPEN’, ‘APPROVED’, or “APPROVED”, or “CLOSED”
‘CLOSED’
Unable to process changed The ACT Case Export API was Ensure that at least one of
records. Export differences closed without ever having getExportRecords() or
have not been computed evaluating any changes to ACT getModifiedExportRecords() is called
Case records. before attempting to close the ACT
Case Export API.
Invalid export field type The field type specified when Ensure that all calls to
‘FIELD_TYPE’ specified. defining a new field mapping for addFieldMapping() specify one of the
Valid values are: ‘BOOLEAN’ the ACT Case Export records was valid field types.
‘DATE’ ‘DATETIME’ not a valid field type.
‘NUMBER’ ‘STRING’ ‘TEXT’
Target field FIELD_TYPE The script has attempted to define Either increase the variable field
FIELD_NUMBER exceeds more field mappings of a particular counts in the ACT_CASE_EXPORT
defined variable field type than there are fields in the table to raise the number of available
count. Max count is ACT_CASE_EXPORT table of that fields of that type, or find a way to
COUNT type. remap the fields so that some of them
use a different type.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 33


WT&A API Specifications 18.3 ACT Case Export API

Unable to set custom An attempt was made to store a Ensure that all custom fields defined
export field FIELD_NAME to value on an ACT Case Export with addFieldMapping() are of the
value VALUE – error parsing record that was incompatible with correct type for the type of values
value the type of field, e.g. attempting to that need to be stored in them.
store the string “ABC” in a number
field.
Field name ‘FIELD_NAME’ An attempt was made to read a Ensure that addFieldMapping() is
has not been defined for value from an ACT Case Export called when setting up the ACT Case
the ActCaseExportRecord Record with a field name that had Export API for every field that needs
not been defined. to be referenced off of the records.
Cannot define a custom An attempt was made to specify a Ensure that all field names specified in
mapping for field name custom field name on an ACT Case addFieldMapping() do not overlap
‘FIELD_NAME’. Standard Export record that matched a field with the actual field names defined in
mapping is already defined name in the ACT_CASE_EXPORT the ACT_CASE_EXPORT table.
using that name. table.
Table 7: ACT Case Export typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The ACT Case Export API consists of the following component(s):
1. The ActCaseExportAPI, which defines a process for determining which ACT Cases have had changes
and for storing information about them.
2. The ActCaseExportRecord, which stores information about a single ACT Case.
See the contents of the ACT_CASE_EXPORT_API policy in the Distributed JavaScript Library category for full
documentation on these methods. The following is a summary of the available methods and common uses:

ActCaseExportAPI
ActCaseExportAPI()
Creates a new instance of the ACT Case Export API

initializeExport(exportId, historyEventTriggersToExport, actCaseStatus, startDateCutoff,


endDateCutoff)
Defines how the API will determine which ACT Cases should be considered when looking for changes. This
specifies which set of historical data is used for identifying changes, what status and case dates an ACT Case
needs to have in order to be considered eligible for processing, and which history event triggers are
considered relevant changes.

addFieldMapping(fieldName, exportFieldType, actCaseSourceField)


Defines a new named field of the indicated data type that can be referenced on all ActCaseExportRecords
generated during processing. If an ACT Case source field is specified, the value from the ACT Case record will
automatically be populated in the field.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 34


WT&A API Specifications 18.3 ACT Case Export API

getExportRecords()
Returns an array of ActCaseExportRecords for all ACT Cases that meet the status and date criteria used to
initialize the API and have either had a change associated with one of the indicated history event triggers or
that have previously been exported. This allows retractions to be generated if a Case was previously
exported but now no longer meets the criteria for inclusion in the export.

getModifiedExportRecords()
Returns an array of ActCaseExportRecords for all ACT Cases that meet the status and date criteria used to
initialize the API and have had a change associated with one of the indicated history event triggers.

getPreviouslyExportedRecord(actCaseId)
Returns an ActCaseExportRecord reflecting the most recent data for the specified ACT Case that was
previously exported for the current export ID. If no data for the ACT Case has been previously exported, null
will be returned. Only records that had an export target specified during processing previously are
considered to have been exported by this method.

close(ch)
Writes the ActCaseExportRecords, including any custom field mappings and their current export state, to the
database. This is necessary to call in order to finalize the changes associated with this export and stop them
from being picked up again during the next run of the export.

rollbackPriorExport(exportId, jobId)
Removes all records from the database associated with the specified export ID and batch job ID. This allows
those same changes to be re-evaluated during the next run of the export.

ActCaseExportRecord
isChangedSinceLastExport()
Returns true if the ACT Case represented by this record had changes linked to any of the specified history
event triggers since the last time it was exported, or false if it does not. This is needed when calling
getExportRecords() on the ActCaseExportAPI, where not all of the records returned will necessarily have had
any relevant changes._getExportRecords()

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 35


WT&A API Specifications 18.3 Advanced Scheduler API

Advanced Scheduler API


Overview and Capabilities
The Advanced Scheduler API provides a framework for importing data into Advanced Scheduler and for
exporting data out of Advanced Scheduler.
The import functionality is typically used when setting up a new Advanced Scheduler configuration, in order
to create many of the Advanced Scheduler components that need to be defined in order to schedule
employees. This functionality would typically be used during the initial configuration setup phase, but can
also be used on-demand as needed to make changes to the Advanced Scheduler configuration. This API is
also used in an ongoing fashion to sync up the employee data between the WorkForce Time and Advanced
Scheduler modules of WorkForce Time and Attendance.
The export functionality allows the Advanced Scheduler data to be easily transferred between instances. The
format of the export data also exactly matches the format used by the imports, so this also allows the
existing data to be downloaded into a spreadsheet form, where it can be edited and then reimported in order
to process changes to the existing data.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Basic understanding of Advanced Scheduler components

Components
This API consists of the following component(s):
• The distributed JavaScript library ADVANCED_SCHEDULER_API

Setup
No setup is necessary for the Advanced Scheduler API. The distributed library is automatically available
within WorkForce Time and Attendance.
In order to sync employee data between WorkForce Time and Advanced Scheduler, employees need to be
assigned a general role that includes the system feature AS_EMPLOYEE. In order to sync user data between
WorkForce Time and Advanced Scheduler, users need to be assigned a General Role or delegated an
assignment group with a Group Role that includes the AS_USER system feature.

Use Cases
Syncing Employee Data Between WorkForce Time and Advanced
Scheduler
The Advanced Scheduler API provides the means by which employee demographic data is synchronized
between the WorkForce Time and Advanced Scheduler modules of WorkForce Time and Attendance. A
Scheduled Script process should be set up to run daily (after the main employee import completes), which
would sync up the AS data with the latest data that has been loaded into WorkForce Time.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 36


WT&A API Specifications 18.3 Advanced Scheduler API

Data can be mapped from WorkForce Time to Advanced Scheduler using one of two methods (or both
methods can be combined together if desired). The simplest way, if the WorkForce Time data can be used
exactly as is without needing to be modified or transformed, is to use a Decoder to map the data over. The
Decoder for this sync process is unusual in that instead of having a single source column that maps to one or
more destination tables, as Decoders are usually structured, this process uses a Decoder that has up to four
source columns all mapping to a single destination.

Figure 1: Sample decoder mapping for the Advanced Scheduler sync process

When using a Decoder with this process, the Decoder needs to have at least one of the EMPLOYEE, ASGNMT,
EMPLOYEE_MASTER, or ASGNMT_MASTER columns specified. Any of these columns are optional, but at
least one of the four must be present in order for mappings to be applied. The Decoder needs to specify
AS_ASSIGNMENT as the destination for the mappings.

Note: The AS_ASSIGNMENT column that must be specified in the Decoder does not match the actual table
name for the Advanced Scheduler Assignment data, which is AS_ASGNMT.

The following script example demonstrates using the Advanced Scheduler API to sync data between
WorkForce Time and Advanced Scheduler using only a Decoder to define the mappings:

Example 1: Using a Decoder policy


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

// Create a new instance of the API


var api = new AdvancedSchedulerAPI();

// Define the parameters for the sync process


var parameters = {
// Specify which decoder policy should be used
decoderPolicy: "AS_IMPORT_DECODER"
};

// Sync the data between WorkForce Time and Advanced Scheduler


api.importAssignmentData(parameters);

Sometimes custom logic or transformations need to be applied to the WorkForce Time data in order to
correctly format it for Advanced Scheduler. In these cases, a simple Decoder mapping can’t be used since the
Decoder can’t transform the data. The Advanced Scheduler API allows for a custom mapping function to be
defined which allows for custom logic to be inserted into the mapping process, allowing whatever script-
based logic is needed to be used to derive the final mappings.
The following script example demonstrates using a custom mapping function to populate the AS Assignment
record:

Example 2: Using custom script logic


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 37


WT&A API Specifications 18.3 Advanced Scheduler API

// Create a new instance of the API


var api = new AdvancedSchedulerAPI();

// Define the parameters for the sync process


var parameters = {
// Define which function should be used for the custom mapping logic
mappingFunction: customMappingFunction
};

// Sync the data between WorkForce Time and Advanced Scheduler


api.importAssignmentData(parameters);

// The custom mapping function containing the logic to be used to map data to the
// AS Assignment record
function customMappingFunction(record, employeeMaster, asgnmtMaster, employee,
asgnmt) {
record.alternate_employee_id = employee.display_employee;
record.seniority_date = employee.seniority_date;
record.birth_date = employee.birth_date;
record.phone_no1 = employee.home_phone;
record.phone_no2 = employee.mobile_phone;
record.pay_rate = asgnmt.base_pay_rate;

// Additional logic can be applied at any point in here as needed


if (asgnmt.fulltime_parttime == "FT") {
record.working_status = "F";
}
else {
record.working_status = "P";
}
}

Note: Both a Decoder and a custom mapping function can be specified. In that case, the Decoder is applied
before the custom mapping function is called and the record argument provided there will be pre-
populated with the results of the Decoder mapping.

In certain cases, it is desirable to have the import not overwrite existing values for a particular field. This
would typically be the case when the Maintain Employees screen is being used to populate a particular field
on the AS Assignment record, or when the WorkForce Time data does not include Rotation Pattern, OT Cost
Control, and/or Fatigue Management information for the employee and these need to be manually
maintained.
The Advanced Scheduler API offers two different approaches for fields to keep. The first approach is used
whenever a particular field or set of fields should have their values preserved globally, regardless of any
specific data conditions. (This would most commonly be used for fields being manually maintained).
The following script example demonstrates specifying the pay rate and seniority date fields on the AS
Assignment record as fields to keep:

Example 3: Specifying global fields to keep


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

// Create a new instance of the API

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 38


WT&A API Specifications 18.3 Advanced Scheduler API

var api = new AdvancedSchedulerAPI();

// Define the parameters for the sync process


var parameters = {
// Specify which decoder policy should be used
decoderPolicy: "AS_IMPORT_DECODER",

// Specify which fields should not be overwritten by the sync process


fieldsToKeep: ["PAY_RATE", "SENIORITY_DATE"]
};

// Sync the data between WorkForce Time and Advanced Scheduler


api.importAssignmentData(parameters);

In other cases, whether a field is preserved or not may depend on certain conditions being present in the
data. For these cases, an additional property called fieldsToKeep can be used on the record being mapped
within the custom mapping function to specify which fields should be preserved for just that record currently
being evaluated.
The following script example demonstrates using the Advanced Scheduler API to specify that the
user_field10 value should be preserved, but only for employees who are excluded from one-touch callout:

Example 4: Specifying per-record fields to keep


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

// Create a new instance of the API


var api = new AdvancedSchedulerAPI();

// Define the parameters for the sync process


var parameters = {
// Define which function should be used for the custom mapping logic
mappingFunction: customMappingFunction
};

// Sync the data between WorkForce Time and Advanced Scheduler


api.importAssignmentData(parameters);

// The custom mapping function containing the logic to be used to map data to the
// AS Assignment record
function customMappingFunction(record, employeeMaster, asgnmtMaster, employee,
asgnmt) {
record.alternate_employee_id = employee.display_employee;
record.seniority_date = employee.seniority_date;
record.birth_date = employee.birth_date;
record.phone_no1 = employee.home_phone;
record.phone_no2 = employee.mobile_phone;
record.pay_rate = asgnmt.base_pay_rate;

record.exclude_from_otc == (asgnmt.c_exclude_from_otc == "T");


// If the employee is excluded from one-touch callout, preserve the user_field10
// value that already exists
if (record.exclude_from_otc) {
record.fieldsToKeep.push("user_field10");
}
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 39


WT&A API Specifications 18.3 Advanced Scheduler API

Note: It is possible to define both global fields to keep and per-record fields to keep at the same time, if
needed. However, if a field is marked as a global field to keep there is no way to disable that on a
record-by-record basis.

Importing Model Data


The Advanced Scheduler API can be used to import Model data from a file into Advanced Scheduler. The
Model import keys off of the value in the ModelName field: if an existing Model is found with that same
name then the existing Model will be updated with the new data, otherwise a new Model will be created.
Model data within Advanced Scheduler is effective dated, and the Model import follows the standard
WorkForce Time and Attendance import rules for effective date handling. Specifically, if the start date on the
record being imported is earlier than an existing start date for that same Model, then the later effective-
dated records for that Model will be removed. If the start date on the record being imported is later than an
existing start date for that Model, then the end date of that record will be adjusted to the day before the new
start date so as to avoid any overlap. If the start date exactly matches an existing start date for the Model,
then that existing record will be updated in place.
The following script example demonstrates using the Advanced Scheduler API in order to import Model data
from a file:

Example 1: Importing Model data


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "models.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Model data from the file


api.importModelsFromFile(file);

If the customer can provide all of the necessary fields for the Model import, but for some reason needs to
use different names for some or all of the fields in the file, then an alias map can be defined to translate the
standard field names into custom names.
The following script example demonstrates import Model data from a file, where the standard “StartDate”
and “EndDate” fields have been aliased as “Begin Date” and “Close Date”, respectively:

Example 2: Importing Model data with custom aliases


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 40


WT&A API Specifications 18.3 Advanced Scheduler API

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "models.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Define the aliases


var aliases = {
StartDate: "Begin Date",
EndDate: "Close Date"
};

// Import the Model data from the file


api.importModelsFromFile(file, aliases);

Importing Rotation Pattern Data (Nuclear Industry Customers)


The Advanced Scheduler API can be used to import Rotation Pattern data for Nuclear Industry customers.
For these customers, the Rotation Pattern data is broken out into three different segments that need to be
imported: the master data, the details, and the FM metadata.
The Rotation Pattern master data defines the Rotation Patterns as entities within Advanced Scheduler. The
Rotation Patterns defined here are those available to be assigned to employees and used for scheduling. The
Rotation Pattern import keys off the RotationPatternName field: if the name matches an existing Rotation
Pattern’s name then that rotation pattern’s data will be updated, otherwise a new Rotation Pattern will be
created.
The following script example demonstrates how the Advanced Scheduler API can be used to import Rotation
Pattern master data:

Example 1: Importing Rotation Pattern master data


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "rotation_pattern_masters.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern data from the file


api.importNuclearRotationPatternMastersFromFile(file);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 41


WT&A API Specifications 18.3 Advanced Scheduler API

The Rotation Pattern details define the pattern itself. These indicate which days are working days and which
are not in the Rotation Pattern, as well as determining the length of the pattern.
The Rotation Pattern details import uses the RotationPatternName to identify which Rotation Pattern should
be updated to include the details. This needs to match the name of an existing Rotation Pattern within
Advanced Scheduler. The DayNumber field is then used to identify which day within the pattern the details
belong to. If there is an error on one of the days for a Rotation Pattern, then all of the details for that
Rotation Pattern being processed during the import will be errored out and the Rotation Pattern will remain
unchanged.

Note: Day numbers are not allowed to be duplicated or have gaps without records in the import data for the
same Rotation Pattern.

The following script example demonstrates using the Advanced Scheduler API to import Rotation Pattern
details from a file:

Example 2: Importing Rotation Pattern details


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "rotation_pattern_details.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern data from the file


api.importNuclearRotationPatternDetailsFromFile(file);

The FM metadata defines the Fatigue Management settings for the Rotation Pattern, including the outage
status and how long the MDO period is. The FM metadata import uses the RotationPatternName to identify
which Rotation Pattern should be updated with the FM metadata. This needs to match the name of an
existing Rotation Pattern within Advanced Scheduler.
FM metadata within Advanced Scheduler is effective dated, and the FM metadata import follows the
standard WorkForce Time and Attendance import rules for effective date handling. Specifically, if the start
date on the record being imported is earlier than an existing start date for that same Rotation Pattern, then
the later effective-dated records for that Rotation Pattern will be removed. If the start date on the record
being imported is later than an existing start date for that Rotation Pattern, then the end date of that record
will be adjusted to the day before the new start date so as to avoid any overlap. If the start date exactly
matches an existing start date for the Rotation Pattern, then that existing record will be updated in place.
The following script example demonstrates using the Advanced Scheduler API to import Rotation Pattern FM
metadata from a file:

Example 3: Importing FM Metadata


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 42


WT&A API Specifications 18.3 Advanced Scheduler API

includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "rotation_pattern_metadata.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importNuclearRotationPatternFMMetadataFromFile(file);

Importing Rotation Pattern Data (Petrochemical Industry Customers)


The Advanced Scheduler API can be used to import Rotation Pattern data for Petrochemical Industry
customers. For these customers, the Rotation Pattern data is broken out into two different segments that
need to be imported: the master data (including FM metadata) and the details.
The Rotation Pattern master data defines the Rotation Patterns as entities within Advanced Scheduler. The
Rotation Patterns defined here are those available to be assigned to employees and used for scheduling. The
Rotation Pattern import keys off the RotationPatternName field: if the name matches an existing Rotation
Pattern’s name then that rotation pattern’s data will be updated, otherwise a new Rotation Pattern will be
created. For Petrochemical Industry customers, the Rotation Pattern master data also includes the FM
metadata information.
The following script example demonstrates how the Advanced Scheduler API can be used to import Rotation
Pattern master data:

Example 1: Importing Rotation Pattern master data


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "rotation_pattern_masters.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importPetroChemRotationPatternMastersFromFile(file);

The Rotation Pattern details define the pattern itself. These indicate which days are working days and which
are not in the Rotation Pattern, as well as determining the length of the pattern.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 43


WT&A API Specifications 18.3 Advanced Scheduler API

The Rotation Pattern details import uses the RotationPatternName to identify which Rotation Pattern should
be updated to include the details. This needs to match the name of an existing Rotation Pattern within
Advanced Scheduler. The DayNumber field is then used to identify which day within the pattern the details
belong to. If there is an error on one of the days for a Rotation Pattern, then all of the details for that
Rotation Pattern being processed during the import will be errored out and the Rotation Pattern will remain
unchanged.

Note: Day numbers are not allowed to be duplicated or have gaps without records in the import data for the
same Rotation Pattern.

The following script example demonstrates using the Advanced Scheduler API to import Rotation Pattern
details from a file:

Example 2: Importing Rotation Pattern details


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "rotation_pattern_details.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importPetroChemRotationPatternDetailsFromFile(file);

Importing Qualifications
The Advanced Scheduler API can be used to import Qualification data from a file into Advanced Scheduler.
The Qualifications import keys off of the value in the QualificationName field: if an existing Qualification is
found with that same name then the Qualification will be updated with the new data, otherwise a new
Qualification will be created.
In addition to creating the Qualification itself, the Qualifications import will also make that Qualification
available to the specified Scheduling Unit.
The following script example demonstrates using the Advanced Scheduler API in order to import Qualification
data from a file:

Example: Importing Qualifications


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "qualifications.csv";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 44


WT&A API Specifications 18.3 Advanced Scheduler API

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importQualificationsFromFile(file);

Importing Assignment Qualifications


The Advanced Scheduler API can be used to import Assignment Qualification data from a file into Advanced
Scheduler. This makes the Qualification available to that Assignment and specifies how proficient the
employee is, which can be used to drive scheduling behavior. The Assignment Qualifications import keys off
of the combination of EmployeeID and QualificationName specified in the source data: if an existing
Qualification is assigned to the indicated employee with that name then that Assignment Qualification will be
updated with the new data, otherwise a new Assignment Qualification will be created.
If it is not already available, the Assignment Qualifications import will make the Qualification available to the
home Scheduling Unit specified on the Assignment record.
The Assignment Qualifications import also allows for existing Assignment Qualifications to be deleted. If the
TransactionType is specified as D, rather than adding or updating an Assignment Qualification the import will
remove any Assignment Qualification it finds for the matching EmployeeID/QualificationName combination.
The following script example demonstrates using the Advanced Scheduler API to import Assignment
Qualification data:

Example: Importing Assignment Qualifications


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "equals.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importAssignmentQualificationsFromFile(file);

Importing Stations
The Advanced Scheduler API can be used to import Station data from a file into Advanced Scheduler. The
Stations import keys off of the value of the StationName field specified in the source data: if an existing
Station is found with that name then that Station will be updated with the new data, otherwise a new Station
will be created.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 45


WT&A API Specifications 18.3 Advanced Scheduler API

The following script example demonstrates using the Advanced Scheduler API to import Station data:

Example: Importing Stations


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "stations.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importStationsFromFile(file);

Importing Events and Slots


The Advanced Scheduler API can be used to import Event and Slot data from a file into Advanced Scheduler.
The import keys off the EventName field in the source data: if no existing Event is found with the specified
name, then a new Event is created. Otherwise, the existing Event is left unchanged. In either case, the
import will then create a new Slot with the indicated attributes associated with that Event.

Note: The import will always create a new Slot, never update an existing one. It is not possible to use this
import to process updates to Slots after they’ve been created.

The following script example demonstrates using the Advanced Scheduler API to import Event and Slot data:

Example: Importing Events and Slots


includeDistributedPolicy("ADVANCED_SCHEDULER_API");
includeDistributedPolicy("FILE_MANAGER_API");

// Define the import file to be processed


var filePath = "interface/incoming/";
var fileName = "events_and_slots.csv";

// Create a FileManager for the source file


var file = new FileManager();
file.setFile(filePath, fileName);
file.openFile( {hasHeaderRecord: true} );

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Import the Rotation Pattern metadata from the file


api.importEventsAndSlotsFromFile(file);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 46


WT&A API Specifications 18.3 Advanced Scheduler API

Exporting Advanced Scheduler Data


The Advanced Scheduler API can be used to export data for all of the types it can import from files back to a
file. (For a list of valid export types, see: Table 21: Types of Advanced Scheduler data that can be exported.)
The files resulting from this export process are in the same format that the import expects to read data from.
This allows data to be exported from one instance and loaded into another instance, or for the data to be
downloaded to a file, edited, and then reimported into the same instance to make changes to the Advanced
Scheduler data.
The following script example demonstrates how the Advanced Scheduler API can be used to export all Station
information to a file:

Example 1: Exporting Advanced Scheduler data to a file


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

// Define the file the data should be exported to


var filePath = "interface/incoming/";
var fileName = "stations.csv";

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

// Define the export settings that should be used


var exportSettings = {
// The delimiter that should be used to separate fields in the file
delimiter: ",",

// Indicates whether all values should be wrapped in quotes. If false,


// any value that includes the delimiter will still be enclosed in quotes
quoteValues: false
};

// Define the type of Advanced Scheduler data that should be exported


var exportType = "STATION";

// Export the data to the file


api.exportDataToFile(filePath, fileName, exportType, exportSettings);

The data that is exported to the file can also be filtered so that only certain portions of the data are written
to the file. For instance, it may only be desirable to export the records for a certain subset of the data, such
as only the most recent effective-dated Model record.
The following script example demonstrates how the filtering provided by the Advanced Scheduler API can be
used to export only Model data that is effective on 3000-12-31 to a file:

Example 2: Filtering the data that is exported


includeDistributedPolicy("ADVANCED_SCHEDULER_API");

// Define the file the data should be exported to


var filePath = "interface/incoming/";
var fileName = "models.csv";

// Initialize the API to process the file


var api = new AdvancedSchedulerAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 47


WT&A API Specifications 18.3 Advanced Scheduler API

// Define the export settings that should be used


var exportSettings = {
// The delimiter that should be used to separate fields in the file
delimiter: ",",

// Indicates whether all values should be wrapped in quotes. If false,


// any value that includes the delimiter will still be enclosed in quotes
quoteValues: false,

// Specify the filter function that should be used


filter: modelFilterFunction
};

// Define the type of Advanced Scheduler data that should be exported


var exportType = "MODEL";

// Export the data to the file


api.exportDataToFile(filePath, fileName, exportType, exportSettings);

// Defines the logic that should be used to determine which Models are exported.
// This will be executed once for each Model record, and should return true if
// that record should be exported, false if it should not.
function modelFilterFunction(record) {
// Only export the records with an end date of 3000-12-31
return (record.EndDate == "3000-12-31");
}

Troubleshooting
The job log of the script using the Advanced Scheduler API will contain information messages and, in the case
of problems, any error messages generated during processing. This job log should be reviewed if there are
any problems encountered while using the API.

Error Message Problem Solution


Unable to import Advanced The parameters specified for Ensure that either a decoder or
Scheduler Assignment data importing AS Assignment data did mapping function (or both) are
without a decoder or not specify either a decoder or a specified in the parameters when
mapping function specified. mapping function, so the import importing AS Assignment data.
At least one of those two has no way of knowing how to map
properties must be defined the data from WorkForce Time to
in the import parameters. Advanced Scheduler.
The script attempted to write to a Ensure that all fields mapped on the
Property PROPERTY_NAME
field that does not exist in the AS Assignment records are valid fields
is not a valid property for
AS_ASGNMT table and is not a to map data to.
an AS Assignment mapping
valid additional property.
Invalid fields The array of fields to keep specified Ensure that all fields specified as fields
LIST_OF_FIELD_NAMES when calling the API method to to keep are valid fields that data can
specified as global fields to import AS Assignment data be mapped to on AS Assignment
keep included field names that do not records.
exist in the AS_ASGNMT table and
are not valid additional properties.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 48


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


Field FIELD_NAME is not A field that does not exist in the Ensure that all fields specified as fields
allowed to be added as a AS_ASGNMT table and is not a to keep are valid fields that data can
field to keep valid additional property was be mapped to on AS Assignment
specified in the mapping function records.
as a record-specific field to keep.
Aliases defined for The aliases specified for a file- Ensure that all of the fields being
unknown fields: based import or export included aliased in the list of aliases are
LIST_OF_FIELD_NAMES non-standard field names. standard fields that exist for that type
of import/export.
File did not contain the The file being processed did not Ensure that the file being processed
expected fields; unable to contain all of the expected field contains all of the standard field
continue processing file names for the type of data being names, or that appropriate aliases are
imported. defined for the fields using custom
names. Fields are not allowed to be
missing completely in the import files.
No employee ID specified The source data did not contain a Ensure that the employee ID field is
value for the employee ID field populated on all records in the source
when importing Assignment file when importing Assignment
Qualifications. Qualifications.
No AS assignment is The employee ID specified in the Ensure that all of the employee IDs
currently active for source data did not match an specified in the source data for an
employee EMPLOYEE_ID employee defined in Advanced Assignment Qualifications import
Scheduler when importing match employees that exist in
Assignment Qualifications. Advanced Scheduler.
No qualification name The source data did not contain a Ensure that the Qualification name
specified value for the Qualification name field is populated on all records in the
when importing Assignment source file when importing
Qualifications. Assignment Qualifications.
Qualification The Qualification name specified in Ensure that all of the Qualification
QUALIFICATION_NAME the source data did not match a names specified in the source data for
does not exist Qualification defined in Advanced an Assignment Qualifications import
Scheduler when importing match Qualifications that exist in
Assignment Qualifications. Advanced Scheduler.
Transaction type of ‘D’ The source data specified that an Ensure that any deletion records
specified for an Assignment Qualification should be specified in the Assignment
assignment/qualification deleted, but that Assignment Qualification source data match up to
combination that does not Qualification was not already records that should be deleted.
already exist. Unable to present in Advanced Scheduler to Alternatively, this message can be
delete assignment be deleted. ignored if it is expected that the
qualification Assignment Qualification might not
have existed to begin with.
Invalid transaction type The source data contained an Ensure that all records in the source
‘TRANSACTION_TYPE’ invalid value for the transaction data contain either a ‘U’ or a ‘D’ in the
specified. Valid values are type when importing Assignment transaction type field when importing
‘U’ or ‘D’ Qualifications. Assignment Qualifications.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 49


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


Expiration date DATE is The expiration date provided for Ensure that the expiration date of all
before start date DATE an Assignment Qualification was Assignment Qualifications is on or
earlier than the start date provided after the start date of those
for that same record. Assignment Qualifications in the
source data.
Invalid proficiency level of The proficiency level specified in Ensure that the proficiency level of
PROFICIENCY_LEVEL the source data for an Assignment the Assignment Qualification falls
specified. Proficiency level Qualification was outside of the within the allowed range. If the
must be between 1 and allowed range. maximum value for the range is too
MAX_PROFICIENCY_LEVEL low, this can be adjusted on the
System Setup policy (Advanced
Scheduler Configuration tab >
Maximum Qualification Proficiency
Level field).
No event name specified The source data did not include a Ensure that the Event name field is
value for the Event name field populated on all records in the source
when importing Events and Slots. data.
End date DATE is before The source data specified an end Ensure that the end date is on or after
start date DATE date that was earlier than the start the start date for all records in the
date when importing Event and source data.
Slot data.
End time DATETIME is The source data specified a Ensure that the end date and end
before start time combination of end date and end time combine to reflect a date-time
DATETIME time that was earlier than the that is on or after the date-time
combination of start date and start defined by the combination of the
time when importing Event and start date and start time for all
Slot data. records in the source data.
Required headcount must The required headcounts specified Ensure that all records in the source
be greater than 0. Instead was less than 1 when importing data have a required headcount of 1
it was HEADCOUNT Event and Slot data. or greater.
Unable to parse time value The indicated field, which is Ensure that all of the time fields
for field FIELD_NAME; no expected to contain a time value, contain non-blank values.
value was specified was instead blank when importing
Event and Slot data.
Unable to parse time value The indicated field, which is Ensure that all time fields are
for field FIELD_NAME with expected to contain a time value, formatted in HH:MM format
value ‘VALUE’ as a valid contained a string which could not
time be successfully parsed as a time
value.
No model name specified The source data did not include a Ensure that the Model name field is
value in the Model name field populated on all records in the source
when importing Event and Slot data.
data.
No model exists with name The Model name specified in the Ensure that Model records exist in
‘MODEL_NAME’ source data did not match any Advanced Scheduler for all Model
names specified in the source data.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 50


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


Models defined in the Advanced
Scheduler configuration.
No model name specified The source data did not include a Ensure that the Model name field is
on record value in the Model name field populated on all records in the source
when importing Model data data.
No shift with name ‘SHIFT The source data specified a shift Ensure that the shifts specified in the
NAME’ is defined that is not defined in the Advanced source data all exist in the Advanced
Scheduler configuration when Scheduler configuration.
importing Model data.
Specified qualification The source data specified a Ensure that the Qualifications
‘QUALIFICATION’ is not Qualification name that is not specified in the source data all exist in
defined defined in the configuration when the Advanced Scheduler
importing Model data. configuration.
Either required head count The source data did not include Ensure that all days with start/end
or optional head count both the required head count and times specified also have at least one
must be specified for DAY the optional head count for a day of the required and optional head
NAME that has start/end times specified. counts specified for all records in the
source data.
Proficiency level The proficiency level specified in Ensure that the proficiency level for
PROFICIENCY for DAY the source data for the indicated the day falls within the allowed range.
NAME must be between 1 day on a Model was outside of the If the maximum value for the range is
and allowed range. too low, this can be adjusted on the
MAX_PROFICIENCY_LEVEL System Setup policy (Advanced
Scheduler Configuration tab >
Maximum Qualification Proficiency
Level field).
Schedule order The schedule order specified in the Ensure that the schedule order for the
SCHEDULE_ORDER for source data for the indicated day day falls within the allowed range.
DAY_NAME must be 1 or on a Model was outside of the
greater allowed range.
Negative values (VALUE) The specified field on the Model Ensure that the specified field
are not allowed for field record is expected to contain a contains non-negative values on all
FIELD_NAME non-negative value and instead records in the source data.
contained a negative value.
No start time specified for The indicated day for the Model Ensure that the start time field is
day DAY_NAME when an had an end time specified but no populated for each day that has an
end time was specified. start time specified in the source end time populated on all records in
Either both start and end data. the source data.
times must be present or
both must be blank.
No end time specified for The indicated day for the Model Ensure that the end time field is
day DAY_NAME when a had a start time specified but no populated for each day that has a
start time was specified. end time specified in the source start time populated on all records in
Either both start and end data. the source data.
times must be present or
both must be blank.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 51


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


Station with name The Station name specified in the Ensure that the Stations specified in
‘STATION_NAME’ does not source data did not match a the source data all exist in the
exist Station that exists in the Advanced Advanced Scheduler configuration.
Scheduler configuration.
Minimum breaks between The minimum break between shifts Ensure that all of the minimum break
shifts must be between 0 specified in the source data when between shift values specified in the
and 2359. Instead it was importing Nuclear Rotation Pattern source data fall within the allowed
BREAK_BETWEEN_SHIFTS details was outside of the allowed range.
range.
Outage Status must be The source data specified Fatigue Ensure that all records containing
specified when FM Details Management details but did not Fatigue Management data have an
are present specify an outage status when outage status specified in the source
importing Petrochemical Rotation data.
Pattern master data.
Shift Length must be The source data specified Fatigue Ensure that all records containing
greater than 0 when FM Management details but had an Fatigue Management data have a shift
Details are present. invalid shift length when importing length of 1 or greater specified in the
Instead it was Petrochemical Rotation Pattern source data.
SHIFT_LENGTH master data.
Start Date must be The source data specified Fatigue Ensure that all records containing
specified when FM Details Management details but did not Fatigue Management data have a
are present specify a start date when start date specified in the source data.
importing Petrochemical Rotation
Pattern master data.
End Date must be specified The source data specified Fatigue Ensure that all records containing
when FM Details are Management details but did not Fatigue Management data have an
present specify an end date when end date specified in the source data.
importing Petrochemical Rotation
Pattern master data.
Specified end date The source data specified Fatigue Ensure that all records containing
END_DATE is before start Management details with an end Fatigue Management data have an
date START_DATE date that was earlier than the start end date that is on or after the start
date when importing date specified in the source data.
Petrochemical Rotation Pattern
master data.
No qualification name The Qualification name field was Ensure that all records have the
specified on record not populated in the source data Qualification name field populated in
when importing Qualification data. the source data.
Data for rotation pattern One or more of the details being Ensure that all of the details for the
ROTATION_PATTERN_NAM imported for the indicated indicated Rotation Pattern are valid in
E contained invalid records. Rotation Pattern had an error. the source data.
Please correct all errors in Since the details are processed as a
the rotation pattern details batch, if any of them for a given
and reimport to update the Rotation Pattern have an error
rotation pattern then all of the details for that

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 52


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


Rotation Pattern will be errored
out.
No rotation pattern name The Rotation Pattern name field Ensure that all records have the
specified on record was not populated in the source Rotation Pattern name field
data. populated in the source data.
Day number must be The day number specified in the Ensure that all records in the source
between 1 and source data was outside of the data have a day number specified
MAX_ROTATION_PATTERN valid range for the length of a between 1 and the maximum
_LENGTH. Instead it was Rotation Pattern. configured length of a Rotation
DAY_NUMBER Pattern, as defined by the System
Setup policy.
Multiple records defined The source data defined multiple Ensure that all records for the same
for day number records for a given Rotation Rotation Pattern in the source data
DAY_NUMBER Pattern with the same day number have a unique day number.
value.
Gaps in day numbers are The source data specified for a Ensure that there are no gaps in the
not allowed – day number given Rotation Pattern defined a day numbers for each Rotation
DAY_NUMBER was found, record for a given day number Pattern in the source data.
but only without including records for all
NUMBER_OF_DAYS days preceding day numbers.
were specified
No rotation pattern exists The Rotation Pattern name Ensure that the Rotation Patterns
with name specified in the source data did not specified in the source data all exist in
‘ROTATION_PATTERN_NA match with any Rotation Patterns the Advanced Scheduler
ME’ defined in the Advanced Scheduler configuration.
configuration.
End date (END_DATE) is The end date provided in the Ensure that the end date on all
before start date source date is earlier than the start records in the source data is on or
(START_DATE) date provided. after the start date on that same
record.
Shift Length must be 0 or The shift length provided in the Ensure that the shift length provided
greater. Instead it was source data was negative. on all records is a non-negative
SHIFT_LENGTH integer
No scheduling group is The Scheduling Group name Ensure that the Scheduling Groups
defined with name specified in the source data does specified in the source data all exist in
‘SCHEDULING_GROUP_NA not match any of the Scheduling the Advanced Scheduler
ME’ Groups defined in the Advanced configuration.
Scheduler configuration.
No scheduling unit with The Scheduling Unit name Ensure that the Scheduling Units
name specified in the source data does specified in the source data all exist in
‘SCHEDULING_UNIT_NAME not match any of the Scheduling the Advanced Scheduler configuration
’ exists within the Units defined in the Advanced and belong to the Scheduling Group
scheduling group Scheduler configuration that that is specified on that record.
‘SCHEDULING_GROUP_NA belong to the Scheduling Group
ME’ specified in the source data.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 53


WT&A API Specifications 18.3 Advanced Scheduler API

Error Message Problem Solution


No station name specified The Station name specified in the Ensure that the Stations specified in
on record source data does not match any of the source data all exist in the
the Stations defined in the Advanced Scheduler configuration.
Advanced Scheduler configuration.
Area AREA_NAME does not The Area specified in the source Ensure that the Areas specified in the
exist within facility data does not exist or does not source data all exist in the Advanced
FACILITY_NAME belong to the Facility specified onScheduler configuration and belong to
that same record. the Facility specified on the same
record.
Table 8: Advanced Scheduler API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
See the contents of the ADVANCED_SCHEDULER_API policy in the Distributed JavaScript Library category for
full documentation on these methods. The following is a summary of the available methods and common
uses:

AdvancedSchedulerAPI
AdvancedSchedulerAPI(parms)
Creates a new instance of the Advanced Scheduler API, using the provided settings. The available parameters
that can be defined are:
Parameter Description
debug Indicates if additional debug information should be written to the job log to aid in
troubleshooting. Defaults to false if not specified.
Indicates if a file should be renamed after it has been processed, when importing data from
archiveFiles
files. Defaults to false if not specified.
Table 9: Available parameters when initializing the Advanced Scheduler API

importAssignmentData(parms)
Synchronizes the Advanced Scheduler Assignment and User data with the WorkForce Time employee data.
This needs to be run on an ongoing basis in order to ensure that Advanced Scheduler is scheduling employees
correctly. The available parameters that can be defined are:
Parameter Description
decoderPolicy The Decoder Policy to apply in order to map data from WorkForce Time to the
Advanced Scheduler assignments.
Custom mapping function that can be used to map data from WorkForce Time
mappingFunction to the Advanced Scheduler assignments, or to apply custom logic to derive
the data to be mapped.
Field names on the Advanced Scheduler assignment record whose values
fieldsToKeep
should not be overwritten by the import process.
Indicates whether existing Rotation Pattern assignments should be preserved
keepRotationPatterns
by the import process. Defaults to false if not specified.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 54


WT&A API Specifications 18.3 Advanced Scheduler API

Indicates whether existing OT Cost Control assignments should be preserved


keepOTCC
by the import process. Defaults to false if not specified.
Indicates whether existing Fatigue Management assignments should be
keepFatigueManagement
preserved by the import process. Defaults to false if not specified.
Table 10: Available parameters when importing AS Assignment Data

importModelsFromFile(fileManager, aliases)
Imports Advanced Scheduler Model data from the specified file. The provided FileManager object is
expected to already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
ModelName StationName ShiftName QualificationNames ModelType StartDate
EndDate DifficultyRating AllowJobOverlap CalloutOrder CalloutWritesOTEqualization FMStatus
SunStart SunEnd SunProficiency SunScheduleOrder SunRequiredHeadCount SunOptionalHeadCount
MonStart MonEnd MonProficiency MonScheduleOrder MonRequiredHeadCount MonOptionalHeadCount
TuesStart TuesEnd TuesProficiency TuesScheduleOrder TuesRequiredHeadCount TuesOptionalHeadCount
WedStart WedEnd WedProficiency WedScheduleOrder WedRequiredHeadCount WedOptionalHeadCount
ThuStart ThuEnd ThuProficiency ThuScheduleOrder ThuRequiredHeadCount ThuOptionalHeadCount
FriStart FriEnd FriProficiency FriScheduleOrder FriRequiredHeadCount FriOptionalHeadCount
SatStart SatEnd SatProficiency SatScheduleOrder SatRequiredHeadCount SatOptionalHeadCount
HolStart HolEnd HolProficiency HolScheduleOrder HolRequiredHeadCount HoldOptionalHeadCount
Description UserField1 UserField2 UserField3 UserField4 UserField5
UserField6 UserField7 UserField8 UserField9 UserField10 UserField11
UserField12 UserField13 UserField14 UserField15
Table 11: Standard field names expected for importing Model data

importNuclearRotationPatternMastersFromFile(fileManager, aliases)
Imports Advanced Scheduler Rotation Pattern master data, containing the information necessary for a
Nuclear Industry customer, from the specified file. The provided FileManager object is expected to already
have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
RotationPatternName Description SchedulingGroup SchedulingUnit UserField1
UserField2 UserField3 UserField4 UserField5 UserField6
UserField7 UserField8 UserField9 UserField10
Table 12: Standard field names expected for importing Nuclear Industry Rotation Pattern master data

importNuclearRotationPatternDetailsFromFile(fileManager, aliases)
Imports Advanced Scheduler Rotation Pattern detail data, containing the information necessary for a Nuclear
Industry customer, from the specified file. The provided FileManager object is expected to already have been
opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 55


WT&A API Specifications 18.3 Advanced Scheduler API

RotationPatternName DayNumber IsWorking Model


UserField1 UserField2 UserField3 UserField4
UserField5 ReportNotation MinBreakBetweenShifts FMDayUserField1
FMDayUserField2 FMDayUserField3 FMDayUserField4 FMDayUserField5
Table 13: Standard field names expected for importing Nuclear Industry Rotation Pattern detail data

importNuclearRotationPatternFMMetadataFromFile(fileManager, aliases)
Imports Advanced Scheduler Rotation Pattern FM metadata, containing the information necessary for a
Nuclear Industry customer, from the specified file. The provided FileManager object is expected to already
have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
RotationPatternName AveragingWeekStartDay PeriodType
StandardOnlinePeriodLength ShiftLength OutageStatus
StartDate EndDate Period1StartDay
Period2StartDay Period3StartDay Period4StartDay
Period5StartDay
Table 14: Standard field names expected for importing Nuclear Industry Rotation Pattern FM metadata

importPetroChemRotationPatternMastersFromFile(fileManager, aliases)
Imports Advanced Scheduler Rotation Pattern master data, containing the information necessary for a
Petrochemical Industry customer, from the specified file. The provided FileManager object is expected to
already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
RotationPatternName Description SchedulingGroup SchedulingUnit UserField1
UserField2 UserField3 UserField4 UserField5 UserField6
UserField7 UserField8 UserField9 UserField10 StartDate
EndDate OutageStatus ShiftLength
Table 15: Standard field names expected for importing Petrochemical Industry Rotation Pattern master data

importPetroChemicalRotationPatternDetailsFromFile(fileManager, aliases)
Imports Advanced Scheduler Rotation Pattern detail data, containing the information necessary for a
Petrochemical Industry customer, from the specified file. The provided FileManager object is expected to
already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
RotationPatternName DayNumber IsWorking Model UserField1
UserField2 UserField3 UserField4 UserField5
Table 16: Standard field names expected for importing Petrochemical Industry Rotation Pattern detail data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 56


WT&A API Specifications 18.3 Advanced Scheduler API

importQualificationsFromFile(fileManager, aliases)
Imports Advanced Scheduler Qualification data from the specified file. The provided FileManager object is
expected to already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
QualificationName Description Organization
Facility SchedulingGroup SchedulingUnit
Table 17: Standard field names expected for importing Qualification data

importAssignmentQualficiationsFromFile(fileManager, aliases)
Imports Advanced Scheduler Assignment Qualification data from the specified file. The provided
FileManager object is expected to already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
EmployeeID QualificationName Proficiency
StartDate ExpirationDate TransactionType
Table 18: Standard field names expected for importing Assignment Qualification data

importEventsAndSlotsFromFile(fileManager, aliases)
Imports Advanced Scheduler Assignment Event and Slot data from the specified file. Events will be created if
they don’t already exist; otherwise new slots will be added onto the existing event that is already defined.
This import does not support updating existing slots or events in any fashion. The provided FileManager
object is expected to already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
Model StartDate StartTime
EndDate EndTime EventName
RequiredHeadCount WorkOrderNo Note
Table 19: Standard field names expected for importing Event and Slot data

importStationsFromFile(fileManager, aliases)
Imports Advanced Scheduler Assignment Station data from the specified file. The provided FileManager
object is expected to already have been opened and validated.
The provided aliases allow the standard field names to be overridden, in case the customer needs to provide
different field names in the file than the standard values. The standard field names expected by the import
are:
StationName Description Organization Facility
Area SchedulingGroup SchedulingUnit UserField1
UserField2 UserField3 UserField4 UserField5
Table 20: Standard field names expected for importing Station data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 57


WT&A API Specifications 18.3 Advanced Scheduler API

exportDataToFile(filePath, fileName, exportType, parms)


Exports data of the indicated type to the specified file. The file format will match the same format used for
importing data of that type.
The following export types are supported:
Export Type Description
ASSIGNMENT_QUALIFICATION Exports the Qualifications that are available to Assignments.
Exports the Models and their corresponding day details. All
MODEL
effective-dated records will be included in the file.
QUALIFICATION Exports the Qualifications that are defined.
Exports the Rotation Pattern master information in the
ROTATION_PATTERN_MASTER_NUCLEAR
form used for Nuclear Industry customers.
Exports the Rotation Pattern detail information in the form
ROTATION_PATTERN_DETAIL_NUCLEAR
used for Nuclear Industry customers.
Exports the Rotation Pattern FM metadata in the form used
ROTATION_PATTERN_FM_NUCLEAR for Nuclear Industry customers. All effective-dated records
will be included in the file.
Exports the Rotation Pattern master information in the
ROTATION_PATTERN_MASTER_PETRO form used for Petrochemical Industry customers. This will
also include the FM metadata information.
Exports the Rotation Pattern detail information in the form
ROTATION_PATTERN_DETAIL_PETRO
used for Petrochemical Industry customers.
Table 21: Types of Advanced Scheduler data that can be exported

The following parameters are accepted:


Parameter Description
Delimiter The character that will be placed in between fields in the export file. Defaults
to a comma if not specified.
Indicates if all values in the export file should be enclosed in quotes, or if only
quoteValues
the ones that contain the delimiter should be. Defaults to quoting all values.
JS Object defining a mapping from the standard field name in the file to the
Aliases
customer-specific name that should be used instead.
Function that evaluates the record being processed for export to determine
Filter whether it should be included in the export file or not. Used to export only a
subset of the existing data.
Table 22: Available parameters when exporting AS data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 58


WT&A API Specifications 18.3 Advanced Scheduler Data API

Advanced Scheduler Data API


Overview and Capabilities
The Advanced Scheduler Data API lets you retrieve advanced scheduler data from the database in a
conforming way.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The ADVANCED_SCHEDULER_DATA_API Distributed JavaScript Library
• The API_UTIL Distributed JavaScript Library

Setup
No setup is necessary for the Advanced Scheduler Data API. The distributed library is automatically available
in WT&A.

Use Cases
Get Models by using AdvancedSchedulerMatchCondition
The following script examples demonstrate how models can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.MODEL,
field: "JOBASSIGN_DESCRIPTION",
operator: MatchOperator.EQUALS,
values: ["Callout testing model 1"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

//changing value for another condition


matchConditionParam.values = ["Callout testing model 2"];
matchCondition.or(new AdvancedSchedulerMatchCondition(matchConditionParam));

//changing match condition params for another match condition


matchConditionParam.field = "JOB_ID";
matchConditionParam.values = ["6"];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 59


WT&A API Specifications 18.3 Advanced Scheduler Data API

matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));
var actualRecords = asAPI.getModels(matchCondition);

if (actualRecords.length != 0) {
log.info("JOBASSIGN_DESCRIPTION: " + actualRecords[0].JOBASSIGN_DESCRIPTION + " JOB_ID:
" + actualRecords[0].JOB_ID);
}

Get Qualifications by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how qualifications can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.QUALIFICATION,
field: "SKILL_DESCRIPTION",
operator: MatchOperator.LIKE,
values: ["%Test-Qualification-1%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

//changing value for another condition


matchConditionParam.values = ["%Test-Qualification-2%"]
matchCondition.or(new AdvancedSchedulerMatchCondition(matchConditionParam));

//changing match condition params for another match condition


matchConditionParam.field = "CREATED_BY";
matchConditionParam.operator = MatchOperator.EQUALS;
matchConditionParam.values = ["5"];

matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));
var actualRecords = asAPI.getQualifications(matchCondition);

if (actualRecords.length != 0) {
log.info("SKILL_DESCRIPTION: " + actualRecords[0].SKILL_DESCRIPTION + "
CREATED_BY: " + actualRecords[0].CREATED_BY);
}

Get Scheduling Units by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how scheduling units can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 60


WT&A API Specifications 18.3 Advanced Scheduler Data API

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.SCHEDULING_UNIT,
field: "DEPT_NAME",
operator: MatchOperator.EQUALS,
values: ["Test-Sched-Unit-1-1"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

//changing match condition params for another match condition


matchConditionParam.field = "DEPT_ID";
matchConditionParam.values = ["1"];
matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));

var actualRecords = asAPI.getSchedulingUnits(matchCondition);

if (actualRecords.length != 0) {
log.info("DEPT_NAME: " + actualRecords[0].DEPT_NAME + "
DEPT_ID: " + actualRecords[0].DEPT_ID);
}

Get Users by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how users can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.USER,
field: "USER_ID",
operator: MatchOperator.EQUALS,
values: ["110"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getUsers(matchCondition);

if (actualRecords.length != 0) {
log.info("USER_ID: " + actualRecords[0].USER_ID);
}

Get Organizations by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how organizations can be retrieved.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 61


WT&A API Specifications 18.3 Advanced Scheduler Data API

includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.ORGANIZATION,
field: "ORG_DESCRIPTION",
operator: MatchOperator.LIKE,
values: ["%Test-Organization%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getOrganizations(matchCondition);
if (actualRecords.length != 0) {
log.info("ORG_DESCRIPTION: " + actualRecords[0].ORG_DESCRIPTION);
}

Get Stations by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how stations can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.STATION,
field: "JOB_DESCRIPTION",
operator: MatchOperator.LIKE,
values: ["%Test-Station-1-1%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getStations(matchCondition);

if (actualRecords.length != 0) {
log.info("JOB_DESCRIPTION: " + actualRecords[0].JOB_DESCRIPTION);
}

Get Scheduling Groups by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how scheduling groups can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 62


WT&A API Specifications 18.3 Advanced Scheduler Data API

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.SCHEDULING_GROUP,
field: "DIV_DESCRIPTION",
operator: MatchOperator.LIKE,
values: ["%Test-Scheduling-Group-1%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getSchedulingGroups(matchCondition);

if (actualRecords.length != 0) {
log.info("SCHEDULING_GROUP: " + actualRecords[0]. SCHEDULING_GROUP);
}

Get Rotation Patterns by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how rotation pattern can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.ROTATION_PATTERN,
field: "RP_CODE",
operator: MatchOperator.LIKE,
values: ["%Rotation-Pattern-2-1%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getRotationPatterns(matchCondition);

if (actualRecords.length != 0) {
log.info("RP_CODE: " + actualRecords[0].RP_CODE);
}

Get Facilities by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how facilities can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 63


WT&A API Specifications 18.3 Advanced Scheduler Data API

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.FACILITY,
field: "DESCRIPTION",
operator: MatchOperator.LIKE,
values: ["%Test-Facility%"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);


var actualRecords = asAPI.getFacilities(matchCondition);

if (actualRecords.length != 0) {
log.info("DESCRIPTION: " + actualRecords[0].DESCRIPTION);
}

Get Assignments by using AdvancedSchedulerMatchCondition


The following script examples demonstrate how AS assignments can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.ASGNMT,
field: "ASGNMT",
operator: MatchOperator.EQUALS,
values: ["1256355908"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

//adding another match condition


matchConditionParam.field = "IS_ACTIVE";
matchConditionParam.values = ["T"]
matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));

var actualRecords = asAPI.getAssignments(matchCondition);

if (actualRecords.length != 0) {
log.info("ASGNMT: " + actualRecords[0].ASGNMT);
}

Get Employee Rotation Pattern Detail of an Assignment


The following script examples demonstrate how employee rotation pattern details (trans_emp_rp_details) of
an assignment can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 64


WT&A API Specifications 18.3 Advanced Scheduler Data API

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.ASGNMT,
field: "ASGNMT",
operator: MatchOperator.EQUALS,
values: ["1256355908"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

//adding another match condition


matchConditionParam.field = "IS_ACTIVE";
matchConditionParam.values = ["T"]
matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));

var asgnmtRecords = asAPI.getAssignments(matchCondition);

if (asgnmtRecords.length != 0) {
log.info("ASGNMT: " + asgnmtRecords[0].ASGNMT);
}

var empRpDetailRecords = asgnmtRecords[0].getEmpRpDetails();

if (empRpDetailRecords.length != 0) {
log.info("RPATTERN_ID: " + empRpDetailRecords[0].RPATTERN_ID);
}

Get Rotation Pattern Detail of Rotation Pattern


The following script examples demonstrate how rotation pattern details (trans_rp_details) of a rotation
pattern can be retrieved.
includeDistributedPolicy("ADVANCED_SCHEDULER_DATA_API");

var apiParams = {
enableDebugLogging: true
};

var asAPI = new AdvancedSchedulerDataAPI(apiParams);

// Creating the Match Condition


var matchConditionParam = {
table: AdvancedSchedulerMatchTable.ASGNMT,
field: "ASGNMT",
operator: MatchOperator.EQUALS,
values: ["1256355908"]
};

var matchCondition = new AdvancedSchedulerMatchCondition(matchConditionParam);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 65


WT&A API Specifications 18.3 Advanced Scheduler Data API

//adding another match condition


matchConditionParam.field = "IS_ACTIVE";
matchConditionParam.values = ["T"]
matchCondition.and(new AdvancedSchedulerMatchCondition(matchConditionParam));

var asgnmtRecords = asAPI.getAssignments(matchCondition);

if (asgnmtRecords.length != 0) {
log.info("ASGNMT: " + asgnmtRecords[0].ASGNMT);
}

var empRpDetailRecords = asgnmtRecords[0].getEmpRpDetails();

if (empRpDetailRecords.length != 0) {
log.info("RPATTERN_ID: " + empRpDetailRecords[0].RPATTERN_ID);
}

var rpDetailsRecords = empRpDetailRecords[0].getRpDetails();

if (rpDetailsRecords.length != 0) {
log.info("RPATTERN_ID: " + rpDetailsRecords[0].RPATTERN_ID + " RP_DETAIL_ID: " +
rpDetailsRecords[0].RP_DETAIL_ID);
}

Troubleshooting
The job log of the script using the Advanced Scheduler Data API will include informational messages, and in
the case of problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
Match condition is not provided Required match condition has Provide
not been provided to calling AdvancedSchedulerMatchCondition
method
Table 23: Advanced Scheduler Data API common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to make best use of this section.

AdvancedSchedulerDataAPI
The following methods are available for AdvancedSchedulerDataAPI.

AdvancedSchedulerDataAPI (params)
Constructor to create a new instance of the API. Takes an object as parameter, which includes the parameter
defined in the following table.
Parameter Description
enableDebugLogging True if debug content should be written to the log, false if not.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 66


WT&A API Specifications 18.3 Advanced Scheduler Data API

getModels (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_job_assignment table using the provided match condition and returns
matching rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getUsers (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_users table using the provided match condition and returns matching rows
as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getSchedulingUnits (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_department table using the provided match condition and returns
matching rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getQualifications (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_skills table using the provided match condition and returns matching rows
as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getSchedulingGroups (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_division table using the provided match condition and returns matching
rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getStations (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_jobs table using the provided match condition and returns matching rows
as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 67


WT&A API Specifications 18.3 Advanced Scheduler Data API

getOrganizations (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_organization table using the provided match condition and returns
matching rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getRotationPatterns (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_rotational_pattern table using the provided match condition and returns
matching rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getFacilities (advancedSchedulerMatchCondition)
Performs a lookup on the tbl_mst_facility table using the provided match condition and returns matching
rows as ReadOnlyScriptables.
Parameter Description
advancedSchedulerMatchCondition Match condition to retrieve matching records.

getAssignments (advancedSchedulerMatchCondition)
Performs a lookup on the as_asgnmt table using the provided match condition and returns matching rows as
AsAsgnmtScriptables. AsAsgnmtScriptable gives support to get emp_rp_details records by using
AsAsgnmtScriptable#getEmpRpDetails, getEmpRpDetails returns a list of EmpRpDetailsScriptable. Similarly,
EmpRpDetailsScriptable gives support to get rp_details records by using EmpRpDetailsScriptable
#getRpDetails, getRpDetails returns ReadOnlyScriptables of rp_details records.
Parameter Description
advancedSchedulerMatchCo Match condition to retrieve matching records.
ndition

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 68


WT&A API Specifications 18.3 Assignment Group API

Assignment Group API


Overview and Capabilities
The Assignment Group API provides a way to create assignment groups and manage assignment group
delegations and memberships from outside of an Employee Import operation.
The Assignment Group API has three main sets of functionality, which can be used separately or combined as
needed.
The first use of the Assignment Group API is to create new assignment groups. The API provides a way to
define specific criteria for a group, including its filter settings, whether it is available for end-of-period
processing, etc. and to create a group matching that definition. It also provides functionality to determine
whether there is already a group existing that matches that definition.
The second use of the Assignment Group API is to delegate rights (and revoke existing rights) to assignment
groups for different users.
The third use of the Assignment Group API is to manage the membership of manual assignment groups. The
API includes functionality for determining which assignments are already included in a group, for adding an
additional assignment to a group, and for replacing the entire group membership with a new assignment
population.

NOTE: The Assignment Group API will no longer automatically revoke assignment group delegations that
were manually re-delegated after having initially been delegated by the API.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• How assignment groups function

Components
This API consists of the following component(s):
• AssignmentGroupOperator, AssignmentGroupFilter, AssignmentGroupParameters, and
AssignmentGroupAPI. These components are in the distributed JavaScript Library,
ASSIGNMENT_GROUP_API.
• This library automatically includes the API_UTIL library as well, for providing access to additional
functionality needed within the Assignment Group API.

Setup
No setup is necessary for the Assignment Group API. The distributed library is automatically available in
WorkForce Time and Attendance.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 69


WT&A API Specifications 18.3 Assignment Group API

Use Cases
Creating a new assignment group
This script excerpt demonstrates how the Assignment Group API can be used to create a new assignment
group. A new group will be created named “Sample Assignment Group” using the provided definition and
settings, containing all assignments where employee.other_string5 = “A1150” and asgnmt.ld2 != “BV113”.

Note: Even if there is already a group with that description, or that matches the specified settings, a new
assignment group would be created by this script.

includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Define the first filter for the assignment group to be created


var filter1 = new AssignmentGroupFilter("EMPLOYEE", "OTHER_STRING5",
AssignmentGroupOperator.EQUALS, "A1150");
// Define the second filter for the assignment group to be created
var filter2 = new AssignmentGroupFilter("ASGNMT", "LD2",
AssignmentGroupOperator.NOT_EQUALS, "BV113");
var filters = [filter1, filter2];

// Define the settings for the assignment group


var parameters = new AssignmentGroupParameters();
// The group is an Automatic assignment group
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// Not used for end-of-period processing
parameters.setEOPPGroup(false);

// The description of the group to be created


var description = "Sample Assignment Group";

// Create the assignment group and keep track of its ID


var assignmentGroup = assignmentGroupAPI.createAssignmentGroup(description, filters,
parameters);

Creating assignment groups for policy profiles


The Assignment Group API includes functionality for automatically creating assignment groups for each policy
profile defined in the configuration. This would typically be used as part of the go-live process, and for
testing, to create groups for administrators that include all of the employees of each of the different types
defined. This script excerpt demonstrates how the Assignment Group API can be used to create new
assignment groups for each policy profile. The groups created will have a description of the form
“.PROFILE_NAME”. For instance, if there was a policy profile named “EXEMPT” then a group would be
created named “.EXEMPT” containing all of the assignments that belong to that policy profile.

Note: Even if there is already a group with that description, a new assignment group would be created by this
script.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 70


WT&A API Specifications 18.3 Assignment Group API

includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant
var assignmentGroupAPI = new AssignmentGroupAPI("PROFILE_GROUPS");

// Define the settings for the assignment groups


var parameters = new AssignmentGroupParameters();
// The groups should be automatic groups
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// The policy profile groups should be available for end-of-period processing
parameters.setEOPPGroup(true);

// Create the assignment groups


assignmentGroupAPI.createPolicyProfileGroups(parameters);

// Recalculate the groups to populate them


assignmentGroupAPI.recalculateAssignmentGroups(true);

Creating assignment groups for distinct employee/assignment values


In addition to creating groups based on policy profile, the Assignment Group API can be used to create
assignment groups based on all the distinct values in any employee or assignment record field. For instance,
creating groups for every location that an employee belongs to. The following script excerpt demonstrates
how the Assignment Group API can be used to create these data-based groups.

Note: Even if there is already a group with that description, a new assignment group would be created by this
script.

includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant
var assignmentGroupAPI = new AssignmentGroupAPI("DATA_GROUPS");

// Define the settings for the assignment groups


var parameters = new AssignmentGroupParameters();
// The groups should be automatic groups
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// The groups should not be available for end-of-period processing
parameters.setEOPPGroup(false);

// Create assignment groups for every location specified on the assignments


// Groups will include the specified prefix ("Location ") at the beginning of
// the description to make it easy to tell which groups these are
assignmentGroupAPI.createDataBasedGroups("ASGNMT", "LD3", parameters, "Location ");

// Recalculate the groups to populate them


assignmentGroupAPI.recalculateAssignmentGroups(true);

If the assignment data included assignments in locations A, B, and D, this would create three assignment
groups named “Location A”, “Location B”, and “Location D”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 71


WT&A API Specifications 18.3 Assignment Group API

Finding existing assignment group(s)


This script demonstrates how to find an assignment group that already exists. This example will find an
existing group with the same settings that were used in the Creating a new assignment group example.

Example 1: Find the ID of existing assignment group


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Define the first filter for the assignment group to be found


var filter1 = new AssignmentGroupFilter("EMPLOYEE", "OTHER_STRING5",
AssignmentGroupOperator.EQUALS, "A1150");
// Define the second filter for the assignment group to be found
var filter2 = new AssignmentGroupFilter("ASGNMT", "LD2",
AssignmentGroupOperator.NOT_EQUALS, "BV113");
var filters = [filter1, filter2];

// Define the settings for the assignment group


var parameters = new AssignmentGroupParameters();
// Automatic assignment group
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// Not used for end-of-period processing
parameters.setEOPPGroup(false);

// The description of the group to be found


var description = "Sample Assignment Group";

// Locate the assignment group and keep track of its ID


var assignmentGroup = assignmentGroupAPI.findAssignmentGroup(description, filters,
parameters);

This will attempt to find a group with the specified description, filters, and settings. An existing group will
only be considered a match if all of those attributes are the same. If a filter is different, or a setting, or the
description, then the group will not be considered a match. If no matching group is found, the value null will
be returned instead of the ID of the group.

Example 2: Find the Record of existing assignment group


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Define the first filter for the assignment group to be found


var filter1 = new AssignmentGroupFilter("EMPLOYEE", "OTHER_STRING5",
AssignmentGroupOperator.EQUALS, "A1150");
// Define the second filter for the assignment group to be found
var filter2 = new AssignmentGroupFilter("ASGNMT", "LD2",
AssignmentGroupOperator.NOT_EQUALS, "BV113");
var filters = [filter1, filter2];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 72


WT&A API Specifications 18.3 Assignment Group API

// Define the settings for the assignment group


var parameters = new AssignmentGroupParameters();
// Automatic assignment group
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// Not used for end-of-period processing
parameters.setEOPPGroup(false);

// The description of the group to be found


var description = "Sample Assignment Group";

// Locate the assignment group and keep track of its ID


var assignmentGroup = assignmentGroupAPI.findAssignmentGroupRecord(description, filters,
parameters);

This will attempt to find a group record with the specified description, filters, and settings. An existing group
record will only be considered a match if all of those attributes are the same: if a filter is different, or a
setting, or the description, then the group will not be considered a match. If no matching group record is
found, the value null will be returned instead of the record.

Example 3: Find the IDs of existing assignment groups


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Define the first filter for the assignment group to be found


var filter1 = new AssignmentGroupFilter("EMPLOYEE", "OTHER_STRING5",
AssignmentGroupOperator.EQUALS, "A1150");
// Define the second filter for the assignment group to be found
var filter2 = new AssignmentGroupFilter("ASGNMT", "LD2",
AssignmentGroupOperator.NOT_EQUALS, "BV113");
var filters = [filter1, filter2];

// Define the settings for the assignment group


var parameters = new AssignmentGroupParameters();
// Automatic assignment group
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// Not used for end-of-period processing
parameters.setEOPPGroup(false);

// The description of the group to be found


var description = "Sample Assignment Group";

// Locate the assignment group and keep track of its ID


var assignmentGroup = assignmentGroupAPI.findAssignmentGroups(description, filters,
parameters);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 73


WT&A API Specifications 18.3 Assignment Group API

This will attempt to find groups with the specified description, filters, and settings. An existing group will only
be considered a match if all of those attributes are the same. If a filter is different, or a setting, or the
description, then the group will not be considered a match. If no matching group is found, an empty array
will be returned.

Example 4: Find the IDs of all existing assignment groups


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Locate all the assignment groups and keep track of IDs


var assignmentGroup = assignmentGroupAPI.findAssignmentGroups();

This will attempt to find IDs of all existing groups as an array.

Finding an existing assignment group, or creating it if it doesn’t exist


Sometimes an interface may need to operate on an assignment group, but may not be sure that the
assignment group already exists. In that case a new group may need to be created, but if the group already
exists then it would be preferable to avoid creating an identical group. The following is an example of how a
script would go about finding a group if it already exists or creating it if it does not.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. For this example, the argument here is irrelevant.
var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_CREATION");

// Define the first filter for the assignment group to be found


var filter1 = new AssignmentGroupFilter("EMPLOYEE", "LD3",
AssignmentGroupOperator.EQUALS, "SR781");
var filters = [filter1];

// Define the settings for the assignment group


var parameters = new AssignmentGroupParameters();
// Automatic assignment group
parameters.setAssignmentGroupType("AUTO");
// Don't display soft-terminated assignments
parameters.setDisplaySoftTerminated(false);
// Not used for end-of-period processing
parameters.setEOPPGroup(false);

// The description of the group to be found


var description = "SR781 Group";

// Locate or create the assignment group and keep track of its ID


var assignmentGroup = assignmentGroupAPI.findOrCreateAssignmentGroup(description, filters,
parameters);

With this approach, you should be guaranteed to get an ID returned since if no matching group was found a
new group would have been created.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 74


WT&A API Specifications 18.3 Assignment Group API

Delegate assignment groups


While the Employee Import can often handle most common assignment group delegation scenarios,
periodically more complex requirements for delegation come up that the Employee Import is not well suited
to handle. The Assignment Group API can be used in these scenarios to handle these more unusual
delegations.
The Assignment Group API’s delegation process operates based on a process name, which is a unique ID
associated with the process doing the delegation that links together all of the rights that it delegates. The
entire set of rights associated with a given process name is evaluated as a single batch, allowing for easy
revocation of previously-delegated rights when a user no longer meets the delegation conditions.

Example 1: Updating delegations


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The process name here is "DELEGATION_SCRIPT_1".


var assignmentGroupAPI = new AssignmentGroupAPI("DELEGATION_SCRIPT_1");

// Iterate over all records in some data source


while (source.hasData() ) {
// Need to know the login ID for the user to delegate rights to
var userLoginId = source.login_id;
// See "Finding an existing assignment group" section for details
// on finding the ID for an assignment group
var groupId = findAssignmentGroup(source);
// Each delegation needs to have an accompanying Group Role
var groupRole = "MANAGER_GROUP";

// Indicate that the user should end up with rights to the group
assignmentGroupAPI.addGroupRight(userLoginId, groupId, groupRole);
}

// Assign the new group rights and revoke any old rights that were
// not specified.
assignmentGroupAPI.commitGroupRights();

After this script is run, assignment groups would have been delegated for each record in the data source
being processed. This could include multiple delegations for the same user if desired. If the user had not
previously been delegated those rights, then a new delegation would have been created.
If a user had previously been delegated rights using this same process name (“DELEGATION_SCRIPT_1”), and
those rights were not delegated again within the source data being processed, then those existing
delegations would have been revoked by the call to commitGroupRights().

Example 2: Revoking all previously-delegated rights for a process name


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The process name here is "DELEGATION_SCRIPT_1".


var assignmentGroupAPI = new AssignmentGroupAPI("DELEGATION_SCRIPT_1");

// No new rights have been assigned, so revoke all previous delegations


assignmentGroupAPI.commitGroupRights();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 75


WT&A API Specifications 18.3 Assignment Group API

Since this script doesn’t include any calls to addGroupRight(), it is effectively saying that all of the existing
delegations are no longer valid and should be revoked. Any rights previously delegated that are associated
with the specified process name would be revoked in this scenario.

Example 3: Specifying a delegator for the delegated rights


Sometimes it is desirable to have a delegator associated with the rights that are created by a script, so that a
user would have the ability to manually revoke those rights outside of the script process. This can be done by
specifying a delegator when calling commitGroupRights():
assignmentGroupAPI.commitGroupRights(true, "WF_DELEGATOR");
Here the first argument indicates that a delegator should be assigned, and the second argument is the login
ID of the delegator that should be assigned. If the first argument is false, then no delegator will be assigned
and the rights will not be able to be revoked manually.

Look up existing delegations for a user


The Assignment Group API can also be used to look up which assignment groups are delegated to a user.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_LOOKUP");

// Get the information for the groups delegated to the user


var groupInfo = assignmentGroupAPI.getAssignmentGroupsForUser("USER_A", WFSDate.today());

// Iterate over the groups and print their information


for (var i = 0; i < groupInfo.length; ++i) {
var group = groupInfo[i]; log.info("Group ID = " + group.displayId);
log.info("Group role = " + group.groupRole);
log.info("Eff date = " + group.effDt);
log.info("End date = " + group.endEffDt);
log.info("Group type = " + group.parameters.getAssignmentGroupType() );
log.info("Display soft-terminated assignments: " +
group.parameters.getDisplaySoftTerminated() );
log.info("Is EOPP group: " + group.parameters.getEOPPGroup() );

for (var j = 0; j < group.filters.length; ++j) {


log.info("Filter " + (j + 1) + " criteria:");
log.info(" Table = " + group.filters[j].getTableName() );
log.info(" Field = " + group.filters[j].getFieldName() );
log.info(" Operator = " + group.filters[j].getOperator() );
log.info(" Value = " + group.filters[j].getValue() );
}
}

Determine assignment group membership


The Assignment Group API can be used to determine which assignments are in an assignment group, to allow
further processing to be done for those assignments as needed. The following examples demonstrate two
ways of accessing this information.

Example 1: Getting all assignments in the assignment group


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 76


WT&A API Specifications 18.3 Assignment Group API

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_LOOKUP");

// See "Finding an existing assignment group" section details on finding


// the ID for an assignment group
var groupId = findExistingGroup();

// Get the IDs of all assignments in the assignment group


var assignments = assignmentGroupAPI.getAssignmentsInGroup(groupId, false);

// Iterate over the assignments and do something


for (var i = 0; i < assignments.length; ++i) {
var asgnmtId = assignments[i];
// Do something with the assignment here...
}

This will provide access to the IDs for the assignments in the group. The Person Data API can be used to look
up the entire corresponding assignment record if additional information is needed for further processing.

Example 2: Getting only active assignments in the assignment group


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_LOOKUP");

// See "Finding an existing assignment group" section details on finding


// the ID for an assignment group
var groupId = findExistingGroup();

// Get the IDs of only the active assignments in the assignment group
var assignments = assignmentGroupAPI.getAssignmentsInGroup(groupId, true);

// Iterate over the assignments and do something


for (var i = 0; i < assignments.length; ++i) {
var asgnmtId = assignments[i];
// Do something with the assignment here...
}

In this case, whether a soft-terminated assignment is considered active or not depends on how the “display
soft-terminated assignments” setting from the AssignmentGroupParameters is set for the assignment group
being evaluated. If the group is set to display those assignments, then they will be considered active here.
Otherwise they are considered terminated.

Update assignment group membership


The Assignment Group API can be used to update the membership of manual assignment groups. Typically,
this would be used to create assignment groups whose membership is based on criteria that cannot be
specified using the criteria available for automatic assignment groups, such as groups containing all
employees who have used a certain LD value on their timesheet in the current period. Automatic group
memberships cannot be adjusted through this process.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 77


WT&A API Specifications 18.3 Assignment Group API

Example 1: Add an assignment to the existing membership of an assignment group


The following example demonstrates how an additional assignment could be added to an existing group’s
membership.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_UPDATE");

// See "Finding an existing assignment group" section details on finding


// the ID for an assignment group
var groupId = findExistingGroup();

// This is something that would need to be determined by the script logic.


// The Person Data API can be used to get this value for an assigment
// record as needed.
var assignmentId = getAssignmentId();

// Add the assignment to the group


assignmentGroupAPI.addAssignmentToGroup(groupId, assignmentId);

In this case, the assignments already in the group would remain in the group and the new assignment would
be added. If the group already contained the specified assignment, no changes would be made to the group
membership.

Example 2: Replace the membership of an assignment group


The following example demonstrates how the entire membership of an assignment group could be replaced.
This would be useful if your source data can tell you the entire current membership that should be included
in the group.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_UPDATE");

// See "Finding an existing assignment group" section details on finding


// the ID for an assignment group
var groupId = findExistingGroup();

// This is an array that will be populated with the assignment IDs for
// all of the assignments that should be included in the group
var assignmentsForGroup = [];

// Iterate over the data available in the source


while (source.hasData() ) {
var assignmentId = computeAssignmentIdForSourceRecord(source);
// Add the assignment to the membership array
assignmentsForGroup.push(assignmentId);
}

// Replace the membership of the group with the newly-identified assignments


assignmentGroupAPI.replaceAssignmentsInGroup(groupId, assignmentsForGroup);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 78


WT&A API Specifications 18.3 Assignment Group API

In this case, any assignments in the assignment group that were not in the array of assignment IDs would be
removed from the assignment group, and any new assignments in the array that were not already in the
assignment group would be added to its membership.

Recalculating automatic assignment groups


Automatic groups can recalculate their memberships based on the filter criteria that are specified for them.
The Assignment Group API can be used to trigger this process, to ensure that their membership is up to date
when needed. This is shown in the following example.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("GROUP_RECALC");

// Recalculate the automatic assignment group memberships


// The argument here defines whether the script should wait for
// the recalculation to finish before proceeding or not
assignmentGroupAPI.recalculateAssignmentGroups(false);

Delegate assignment group rights via hierarchy.


Delegates assignment group rights from all managers to their top managers in a hierarchical manner.

Example 1: Delegate all assignment group rights without any group filtration.
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("Delegate_Rights");

//define description function to evaluate groups description.


var descriptionFunction = function(supervisorEmployee) {
return supervisorEmployee.First_Name + "'s Employees"; // for example Josh’s Employees
}

//define parameters
var parms = {
supervisorField: "Manager_ID",// column name in ASGNMT table pointing to the managers ID
supervisorMatchID: "Other_String12",// column name in ASGNMT or EMPLOYEE table to which
// supervisor id maps.
descriptionFunction: descriptionFunction,
groupRole: "MANAGER",
isAsgnmtTable: true, //true if supervisorMatchID comes from ASGNMT table, false if comes
//from EMPLOYEE table.
assignDelegator: true,
delegatorLoginId: "WORKFORCE"
};

//Call to function
assignmentGroupAPI.delegateAssignmentGroupRightViaHierarchy(parms);

Example 2: Delegate assignment group rights with group filtration.


includeDistributedPolicy("ASSIGNMENT_GROUP_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 79


WT&A API Specifications 18.3 Assignment Group API

// Initialize the API. The argument here is irrelevant.


var assignmentGroupAPI = new AssignmentGroupAPI("Delegate_Rights");

//define description function to evaluate groups description.


var descriptionFunction = function(supervisorEmployee) {
return supervisorEmployee.First_Name + "'s Employees"; // for example Josh’s Employees
}

//define group filter function in oder to exclude any group from being delegated to any top
//manager.
var filterFunction = function(asgnmt_grp,topSupervisorAppUser) {

if(asgnmt_grp.description == "Ronald's Employees" && topSupervisorAppUser.first_name ==


“Josh"){
return false;
}
else{
}
}
//define parameters
var parms = {
supervisorField: "Manager_ID",// column name in ASGNMT table pointing to the managers ID
supervisorMatchID: "Other_String12",// column name in ASGNMT or EMPLOYEE table to which
// supervisor id maps.
descriptionFunction: descriptionFunction,
groupRole: "MANAGER",
groupFilterFunction: filterFunction,
isAsgnmtTable: false, //true if supervisorMatchID comes from ASGNMT table, false if
//comes from EMPLOYEE table.
assignDelegator: true,
delegatorLoginId: "WORKFORCE"
};

//Call to function
assignmentGroupAPI.delegateAssignmentGroupRightViaHierarchy(parms);

Troubleshooting
The job log of the script using the Assignment Group API will include informational messages, and in the case
of problems, error messages. This job log should be reviewed if there are problems using the API.
Some common error messages, their causes, and the solution:
Error Message Cause Solution
TYPE is an invalid assignment The parameters for an Check that the group type is set
group type. Valid choices are assignment group specified an to either AUTO or MANUAL in the
‘AUTO’ and ‘MANUAL’. (Not case invalid group type. assignment group parameters.
sensitive)
OPTION is an invalid evaluate-as- The parameters for an Check that the as-of date option
of option. Valid options are assignment group specified an is set to either AS_OF_TODAY,
‘AS_OF_TODAY’, invalid as-of date option. CURRENT_PERIOD_END, or
‘CURRENT_PERIOD_END’, or SYSTEM_SETUP in the assignment
‘SYSTEM_SETUP’. (Not case group parameters.
sensitive)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 80


WT&A API Specifications 18.3 Assignment Group API

Error Message Cause Solution


TABLE NAME is invalid. Valid The filter definition for an Check that the table name is set
tables when creating assignment assignment group specified an to either EMPLOYEE or ASGNMT
groups are EMPLOYEE and invalid table. in the filter definition.
ASGNMT
Too many filters specified. The number of filter criteria Check the definition specified for
Maximum allowed filters is 5 specified exceeded the maximum the assignment group with the
(Group: GROUP DESCRIPTION) number able to be stored in the indicated description and ensure
database. the number of filters specified
does not exceed the specified
maximum number.
No assignment group found for The ID specified for an existing Make sure that the group actually
display ID 10245 assignment group does not exists as expected and that the
match the IDs of any of the correct ID (the display ID of the
assignment groups that currently group) is being provided to the
exist. API.
No app user record found for An invalid user ID was specified Check that the correct login ID
delegator with login ID for the delegator. has been specified for the
DELEGATOR delegator user, and that a user
account with that login ID
actually exists.
Column name is undefined or null Column name for supervisorField Provide proper column names as
or supervisorMatchID is not String.
defined or set to null.
Table 24: Assignment Group API common errors, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The following is a summary of the available methods and common uses:

AssignmentGroupOperator
EQUALS
Only assignments where the value in the specified field exactly matches the indicated value will be included
in the assignment group.

GREATER_THAN
Only assignments where the value in the specified field is greater than the indicated value will be included in
the assignment group. For string fields, this uses lexicographic ordering (so “3” is greater than “20”).

LESS_THAN
Only assignments where the value in the specified field is less than the indicated value will be included in the
assignment group. For string fields, this uses lexicographic ordering (so “20” is less than “3”).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 81


WT&A API Specifications 18.3 Assignment Group API

GREATER_THAN_OR_EQUALS
Only assignments where the value in the specified field is the same as or greater than the indicated value will
be included in the assignment group.

LESS_THAN_OR_EQUALS
Only assignments where the value in the specified field is the same as or less than the indicated value will be
included in the assignment group.

NOT_EQUALS
Only assignments where the value in the specified field does not exactly match the indicated value will be
included in the assignment group.

IS_NULL
Only assignments where the value in the specified field is null will be included in the assignment group.

IS_NOT_NULL
Only assignments where the value in the specified field is not null will be included in the assignment group.

LIKE
Only assignments where the value in the specified field matches the pattern defined by the indicated value
will be included in the group.
% — A substitute for zero or more characters
_ — A substitute for a single character
[charlist] — Sets and ranges of characters to match
[^charlist] or [!charlist] — Matches only a character NOT specified within the brackets

NOT_LIKE
Only assignments where the value in the specified field does not match the pattern defined by the indicated
value will be included in the group.

IN
Only assignments where the value in the specified field is one of the items defined by the comma-delimited
list contained in the indicated value will be included in the group.

AssignmentGroupFilter
AssignmentGroupFilter(tableName, fieldName, operator, value)
Creates a new AssignmentGroupFilter that matches all assignments whose value in the indicated table/field
combination matches the indicated value, using the specified operator.

getTableName()
Returns the name of the table referenced by the filter. Will be either EMPLOYEE or ASGNMT. May be useful
for debugging.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 82


WT&A API Specifications 18.3 Assignment Group API

getFieldName()
Returns the name of the field within the table referenced by the filter. May be useful for debugging.

getOperator()
Returns the AssignmentGroupOperator used by the filter. May be useful for debugging.

getValue()
Returns the value that the filter is comparing against. May be useful for debugging.

AssignmentGroupParameters
AssignmentGroupParameters()
Creates a new parameters object, using the default parameter settings.

setAssignmentGroupType(type)
Sets the desired assignment group type to either AUTO or MANUAL. If this is not called, then the default
assignment group type is AUTO.

getAssignmentGroupType()
Returns the assignment group type. May be useful for debugging.

setLd(fieldIndex, value)
Sets the LD field with the indicated index on the assignment group to the specified value.

getLd(fieldIndex)
Returns the value associated with the LD field with the indicated index on the assignment group. May be
useful for debugging.

setDisplaySoftTerminated(displaySoftTerminated)
Sets whether the assignment group should display soft-terminated assignments or not. If this is not called,
then the default behavior is for the group not to display soft-terminated assignments.

getDisplaySoftTerminated()
Returns whether the assignment group will display soft-terminated assignments or not. May be useful for
debugging.

setEOPPGroup(isEOPPGroup)
Sets whether the assignment group is visible on the end-of-period processing screen or not. If this is not
called, then the default behavior is for the group not to be displayed on the end-of-period processing screen.

getEOPPGroup()
Returns whether the assignment group is visible on the end-of-period processing screen or not. May be
useful for debugging.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 83


WT&A API Specifications 18.3 Assignment Group API

setEvaluateAsOf(evaluateAsOf)
Sets which date is used to evaluate the membership of an automatic assignment group. Valid options are
“AS_OF_TODAY”, which looks at the assignment records that are effective on the current system date,
“CURRENT_PERIOD_END”, which looks at the assignment records that are effective on the last date of the
current period, or “SYSTEM_SETUP”, which uses the default behavior for the groups as defined by the System
Setup policy. If this is not called, then the default behavior is to use the behavior defined by the System
Setup policy.

getEvaluateAsOf()
Returns which date will be used for evaluating the assignment group membership. May be useful for
debugging.

setHrSystemId(hrSystemId)
Sets the HR system that is associated with the assignment group, for tracking purposes.

getHrSystemId()
Returns the HR system that is associated with the assignment group. May be useful for debugging.

AssignmentGroupAPI
AssignmentGroupAPI(processName)
Creates a new instance of the Assignment Group API, associated with the specified process name. The
process name should uniquely identify a process that is using the API for group delegation (e.g., “Location
Group Delegation”), and will be used during delegation processing to ensure that all groups delegated by that
process are revoked if they are no longer valid. Generally, this process name should be distinct for each
different job that is using the API, though in rare cases it may be desirable to share the same process name
across more than one job if the intent is that the delegations created by one job should potentially be
revoked by the other job.

recalculateAssignmentGroups(waitUntilFinished)
Launches the process to recalculate the membership for all automatic assignment groups. Depending on the
value for waitUntilFinished, this will either wait until the recalculation is complete before resuming script
execution or will immediately continue with the next action in the script.

createPolicyProfileGroups(parameters)
Creates assignment groups for each policy profile, each containing just the assignments in that policy profile.
Groups will have names of the form ".POLICY_PROFILE", where POLICY_PROFILE is replaced with the policy
profile description as defined on the Policy Profile Master policy in Policy Editor. Only creates a group if no
duplicate is found. A call to recalculateAssignmentGroups() is required to populate the assignment groups.

createDataBasedGroups(tableName, fieldName, parameters, prefix)


Creates assignment groups for each non-null, non-blank value in the field indicated by the specified table and
field name combination. These groups will contain all assignments where the employee/assignment records
contain that specific value in the indicated database field. Groups will have names of the form
"PREFIXVALUE", where PREFIX is a supplied prefix value and VALUE is the value contained within the

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 84


WT&A API Specifications 18.3 Assignment Group API

indicated database field. If no prefix is provided, then the group name will just be of the form "VALUE".
These groups will not be automatically delegated to any users except for those with the Administrator role
specified on the System Setup policy. Only creates a group if no duplicate is found. A call to
recalculateAssignmentGroups() is required to populate the assignment groups.

createAssignmentGroup(description, filters, parameters)


Creates a new assignment group with the specified description and match filters. Does not check for
duplicates before creating the assignment group. If duplicates are not desired, it is the caller's responsibility
to ensure no duplicates will be created. Use findOrCreateAssignmentGroup() to prevent the creation of
duplicate groups.

findAssignmentGroup(description, filters, parameters)


Finds the existing assignment group that matches the provided description, and optionally filters and
assignment group parameters. Returns the lowest ID of the matching group, or null if no matching group is
found.

findAssignmentGroupRecord(description, filters, parameters)


Finds the existing assignment group record that matches the provided description, and optionally filters and
assignment group parameters. Returns the record of the matching group, or null if no matching group is
found.

findOrCreateAssignmentGroup(description, filters, parameters)


Returns the ID of an existing assignment group, if a matching one is found, or creates the assignment group if
there is no matching group found.

findOrCreateDataBasedGroups(tableName, fieldName, parameters, prefix)


Returns full list of assignment group IDs for existing and newly created assignment groups. For each
non-null, non-blank value in the field indicated by the specified table and field name combination, the
assignment groups which do not exist are created and their IDs are returned. This will contain all
assignments where the employee/assignment records contain that specific value in the indicated
database field. Groups will have names of the form "PREFIXVALUE", where PREFIX is a supplied prefix
value and VALUE is the value contained within the indicated database field. If no prefix is provided then
the group name will just be of the form "VALUE". These groups will not be automatically delegated to
any users except for those with the Administrator role specified on the System Setup policy. A call to
recalculateAssignmentGroups() is required to populate the assignment groups. For the assignment
groups that already exist, no duplicates will be created but their IDs will be returned.

getAssignmentGroupsForUser(loginId, asOfDate)
Returns information about all of the assignment groups that are delegated to the user with the indicated
login ID on the specified as-of date.

addGroupRight(loginId, displayId, groupRole, allowRedelegation)


Queues up a new user right to be delegated to the user with the indicated login ID for the assignment group
with the specified display ID using the indicated group role. These rights will be associated with a process

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 85


WT&A API Specifications 18.3 Assignment Group API

name, which will allow only the rights that were delegated through a specific job to be updated. If called
multiple times for the same loginId and displayId, the groupRole that will ultimately be applied will be the
latest one provided. The allowRedelgation parameter will default to true if not specified.

commitGroupRights(assignDelegator, delegatorLoginId)
Commits the changes to the group rights that have been indicated by calls to addGroupRight(). This will
perform the following changes to the group rights:
1. If the user does not already have rights to the indicated group, they will be delegated access to that
group.

2. If the user is already delegated access to the group, with the same group role, then that delegation
will remain unchanged.

3. If the user is already delegated access to the group, but with a different group role, then the group
role associated with the delegation will be updated to reflect the new group role.

4. If a user was previously delegated a group, but that delegation is not in the collection of queued
rights specified by calls to addGroupRight(), then that existing delegation will be revoked.

Only delegations associated with the process name specified for the API will be updated during this
processing. Assignment groups will be recalculated automatically after this operation is performed.

getAssignmentsInGroup(displayId, activeOnly)
Returns the array of assignment IDs contained in the assignment group with the specified display ID.
Terminated assignments will be included in the array if activeOnly is specified as false, otherwise only the
active assignments will be included.

replaceAssignmentsInGroup(displayId, assignmentIds)
Replaces the membership of the assignment group with the specified display ID with the provided collection
of assignments. This method only applies to MANUAL assignment groups, and replaces existing assignments
regardless of active status.

addAssignmentToGroup(displayId, assignmentId)
Adds the specified assignment to the indicated assignment group, if that assignment is not already included
in that group's membership. This method only applies to MANUAL assignment groups.

delegateAssignmentGroupRightViaHierarchy (parms)
This function takes an object as an argument with some required and optional parameters. The parameters
are as follows:
Required:
• supervisorField - Column name in the ASGNMT table pointing to the manager/supervisor ID.
• supervisorMatchID - Column name in ASGNMT or EMPLOYEE table to which supervisor
Id(supervisorField) maps.
• descriptionFunction - Description function to evaluate group description. This function would have
lower manager employee object as an argument.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 86


WT&A API Specifications 18.3 Assignment Group API

• groupRole - Group role policy ID for manager/supervisor.


• isAsgnmtTable – Returns true if supervisorMatchID comes from ASGNMT table or false if comes
from EMPLOYEE table.
Optional:
• groupFilterFunction - Filter function to filter out assignment groups. This function would have
assignment group and top manager app user objects as arguments.
• assignDelegator - Indicates if the rights being created should be marked as having been delegated to
the user, to allow them to be manually revoked. Default is true.
• delegatorLoginId - The login ID of the delegator to use for setting delegations, if they are being set.
Default is “WF_DELEGATOR”. This function delegates rights of all lower manager’s assignment
groups to their top managers. All conditions are reserved as defined for addGroupRight and
commitGroupRights.

findAssignmentGroups(description, filters, parameters)


Finds the existing assignment groups that matches the provided description, filters or assignment group
parameters. Returns the IDs of the matching groups, or empty array if no matching group is found. If no
argument is passed, then IDs of all existing assignment groups will be returned.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 87


WT&A API Specifications 18.3 Badge Data API

Badge Data API


Overview and Capabilities
The Badge Data API lets you retrieve badges from the database.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The BADGE_DATA_API Distributed JavaScript Library

Setup
No setup is necessary for the Badge Data API. The distributed library is automatically available in WT&A.

Use Cases
Finding Badges by ID and Group
The following script examples demonstrate how badge data can be retrieved by badge ID and badge group.

Example 1: Finding badges by ID and Group without optional parameters


This example shows how to retrieve badge data by ID and Group without using optional parameters.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set required parameters


var methodParams = {
badgeId : "ABC123",
badgeGroup : "PROXIMITY_CARDS"
};

// get badge
var badge = badgeDataAPI.findBadge(methodParams);

Example 2: Finding badges by ID and Group with optional parameters


This example shows how to retrieve badge data by ID and Group with optional parameters.
includeDistributedPolicy("BADGE_DATA_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 88


WT&A API Specifications 18.3 Badge Data API

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set required and optional parameters


var methodParams = {
badgeId : "ABC123",
badgeGroup : "PROXIMITY_CARDS",
effDateTime : WFSDateTime.today, // optional parameter
dataSourceType : "MANUAL_ENTRY" // optional parameter
};

//get badge
var badge = badgeDataAPI.findBadge(methodParams);

Finding Multiple or List of Badges


The following script examples demonstrate how badges can be retrieved by providing allowed parameters.

Example 1: Finding active badges as of given date-time


This example shows how to retrieve active badges.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set parameters
var methodParams = {
effDateTime: WFSDateTime.today
};

// get badges
var badge = badgeDataAPI.findBadges(methodParams);

Example 2: Finding badges by provided parameters


This example shows how to retrieve badges according to provided parameters.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set desired parameters and remove rest. All parameters are optional.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 89


WT&A API Specifications 18.3 Badge Data API

var methodParams = {
badgeId: "ABC123",
badgeGroup: "PROXIMITY_CARDS",
employeeId: "21345", // Display_EMPLOYEE
dataSouceType: 1, //MANUAL_ENTRY
effDateTime: WFSDateTime.today
};

// get badges
var badge = badgeDataAPI.findBadges(methodParams);

Example 3: Finding all badges from the database


This example shows how to retrieve all badges from the database.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

// get badges
var badge = badgeDataAPI.findBadges();

Finding Badges Between Date-Time Range


The following script examples demonstrate how the badges can be retrieved between a given date-time
range

Example 1: Finding badges between given date-time range without optional parameters
This example shows how to retrieve badges between a date-time range.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set required parameters


var methodParams = {
startDateTime: WFSDateTime.VERY_EARLY_DATE_TIME,
endDateTime: WFSDateTime.VERY_LATE_DATE_TIME,
onlyIncludeSubRanges:true // get only subranges
};

// get badges
var badge = badgeDataAPI. findBadgesBetweenEffDateTimeRange (methodParams);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 90


WT&A API Specifications 18.3 Badge Data API

Example 2: Finding badges between given date-time range with optional parameters
This example shows how to retrieve badges between date-time range with optional parameters.
includeDistributedPolicy("BADGE_DATA_API");

var apiParams = {
enableDebugLogging : true
};

// create instance of API


var badgeDataAPI = new BadgeDataAPI(apiParams);

//Set required and optional parameters


var methodParams = {
startDateTime: WFSDateTime.VERY_EARLY_DATE_TIME,
endDateTime: WFSDateTime.VERY_LATE_DATE_TIME,
badgeId: "ABC123", // optional
badgeGroup: "PROXIMITY_CARDS", // optional
employeeId: "21345", // Display_EMPLOYEE, // optional
dataSourceType: "1", // optional
onlyIncludeSubRanges:true // get only subranges
};

// get badges
var badge = badgeDataAPI. findBadgesBetweenEffDateTimeRange (methodParams);

Troubleshooting
The job log of the script using the Badge Data API will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
Required parameter is not Required parameter(s) are missing or Provide required parameter for
provided or null null in the method findBage or method
findBadgesBetweenEffDateTimeRange
Value is not a valid value for Provided data source type value is not Provide valid value for data
choice a valid value for the API method. source type which includes
MANUAL_ENTRY or
IMPORTED and their integer
value 1 or 2 respectively
Table 25: BADGE DATA API common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to make best use of this section.

BadgeDataAPI
The following methods are available for the Badge Data API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 91


WT&A API Specifications 18.3 Badge Data API

BadgeDataAPI (params)
Constructor to create a new instance of the API. Takes an object as parameter, which includes the parameter
defined in the following table.
Parameter Description
enableDebugLogging True if debug content should be written to the log, false if not

findBadge (params)
Retrieves badge by ID and Group. This method has some required and optional parameters, where the
optional parameters add additional criteria to get the desired badges. Takes an object as a parameter, which
includes the parameters defined in the following table.
Parameter Description
badgeId (required) ID for the badge which need to be retrieved
badgeGroup (required) Badge group name to get only badge of that group
dataSourceType (optional) Date-time to put additional criteria to get only active badge as of given date-
time
effDateTime (optional) Data source type to put additional criteria to get badge

findBadges (params)
Retrieves badge(s) by provided parameters. This method has all optional parameters and retrieves badges
according to the provided number of parameters. t retrieves all badges from the database if no parameter is
provided. Takes an object as a parameter, which includes the parameters defined in the following table.
Parameter Description
badgeId (optional) ID for the badge which need to be retrieved
badgeGroup (optional) Badge group name to get only badges of that group.
employeeId (optional) Display employee id, whose badges need to be retrieved
dataSourceType (optional) Date-time to put additional criteria to get only active badge as of given date-
time
effDateTime (optional) Data source type to put additional criteria to get badge

findBadgesBetweenEffDateTimeRange (params)
Retrieves badge(s) within the provided data-time range. This method has some required and optional
parameters, where the optional parameters add additional criteria to get the desired badges. Takes an object
as a parameter, which includes the parameters defined in the following table.
Parameter Description
startEffDateTime (required) Start date-time for the date-time range
endEffDateTime (required) End date-time for the date-time range
badgeId (optional) ID for the badge which need to be retrieved
badgeGroup (optional) Badge group name to get only badges of that group.
employeeId (optional) Display employee id, whose badges need to be retrieved
dataSourceType (optional) Date-time to put additional criteria to get only active badge as of given date-
time

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 92


WT&A API Specifications 18.3 Badge Data API

onlyIncludeSubRanges True if only badges within sub-range of given range are required, false if
badges with any portion of that time range are required. False by default.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 93


WT&A API Specifications 18.3 Badge Import API

Badge Import API


Overview and Capabilities
The Badge Import API provides scripts with the ability to create and modify Badge records. These records are
needed in order to be able to process clock punches from outside of WorkForce Time and Attendance and
would typically be used in association with a swipe import of some sort. Most of the time these Badge
records would be used alongside the WorkForce Data Collection Terminals, in order to correctly evaluate
punches made at the WorkForce Terminal, but Badge records can also be used as part of the processing of
punches from any external clocking system.
The Badge records created through the Badge Import API can come from any number of data sources. The
most common, and preferred, source for the Badge data is the HR data that is already being loaded into the
Employee or Assignment tables. However, if HR is unable to provide that data, the Badge Import API also
supports loading it from CSV or fixed-width files, or by using a custom query against other tables in order to
load the data.
In addition to creating Badge records, the Badge Import API also includes support for creating Badge Groups.
When processing Badge records, if the corresponding Badge Group does not exist, the API will automatically
create a new Badge Group policy of the necessary type and add it to the configuration so that the Badge
record can be processed successfully.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding experience
• Basic understanding of Badges within WorkForce Time and Attendance and how they work with
clock processing

Components
This API consists of the following component(s):
1. The BADGE_IMPORT_LIBRARY Distributed JavaScript library
2. The Badge Group policies defined within the configuration

Setup
No setup is necessary for the Badge Import API. The distributed library is automatically available within
WorkForce Time and Attendance, and the API will automatically generate the appropriate Badge Group
policies as needed.

Use Cases
Importing Badge Records from HR Data
The most common use for the Badge Import API is for loading Badge information that was included as part of
the main HR data. The Badge information is loaded onto the employee or assignment records by the main
Employee Import process, which defines the associations between employee and Badge ID as well as the

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 94


WT&A API Specifications 18.3 Badge Import API

effective dating for that association, and then the Badge Import API transfers that information into the Badge
table.
When the Badge information is being imported out of the HR data, the API always looks at the
employee/assignment data that is effective on the current system date. If the employee is not active on that
date then the Badge data is considered to be terminated (which will end date the existing Badge record),
otherwise it is treated as active.
The following script example demonstrates the most basic case for importing Badge data using the HR data
as the source. It defines a Badge Group named “ALL_BADGES”, and then uses the information defined in the
assignment’s IMPORTED_BADGE_ID field to identify the Badge ID for the employee:

Example 1: Importing based on the values in a specific field


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define the settings for the source data


var sourceSettings = {
// The badge group the badges should be placed in
badgeGroup: "ALL_BADGES",

// The field in the employee/assignment data containing the badge ID


badgeIdField: "a.imported_badge_id",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the WorkForce Time and Attendance HR data as
the data
// source
api.addEmpCenterSource(sourceSettings);

// Import the Badge data


api.importBadges();

Note: While Badges support being defined as either numeric or alpha-numeric, an alpha-numeric Badge can
store an ID that is all numbers. To avoid issues with leading zeros being dropped, and to ensure
compatibility with all possible Badge ID values, it is recommended to always define Badges as alpha-
numeric.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 95


WT&A API Specifications 18.3 Badge Import API

Example 2: Defining custom criteria to limit which Badges are created


In many cases, Badges should not be created for every employee in WorkForce Time and Attendance. They
often need to be limited to only those employees that meet certain criteria (such as working in a particular
location or belonging to a particular policy profile). The Badge Import API allows the employee population
that will be processed to be filtered down by specifying custom SQL criteria to define which employees
should be processed.
The following script example demonstrates using the Badge Import API to create Badges only for those
employees with an assignment belonging to the BADGE_PROFILE policy profile:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define the settings for the source data


var sourceSettings = {
// The badge group the badges should be placed in
badgeGroup: "ALL_BADGES",

// The field in the employee/assignment data containing the badge ID


badgeIdField: "a.imported_badge_id",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC,

// Specify the criteria that must be met in order for a badge to be created
criteria: "a.policy_profile = 'BADGE_PROFILE'"
};

// Add the source definition to the API, defining the WorkForce Time and Attendance HR data as
the data
// source
api.addEmpCenterSource(sourceSettings);

// Import the Badge data


api.importBadges();

Note: If an employee had previously met the criteria for being imported, and had a badge created, and now
due to a data change no longer meets the criteria for being imported, then their existing badge will be
deactivated the next time the Badge Import is run.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 96


WT&A API Specifications 18.3 Badge Import API

Example 3: Modifying the value in the field used as the import source
Sometimes the Badge ID supplied in the HR data is not quite sufficient on its own to use as the actual ID for
the Badge records. For instance, maybe the customer has multiple locations that each have their own pool of
Badge IDs. In this case, it is possible that the same Badge ID could end up being assigned to different
employees working out of different locations. In order to ensure that the Badge IDs loaded into the Badge
table are unique (so that the terminals can correctly resolve which employee the Badge belongs to), a prefix
denoting which location the badge belongs to can be appended to the Badge ID supplied in the HR data.
When using the HR data as the data source for the import, the Badge Import API supports the use of SQL in
the badgeIdField definition, which allows the value to be modified as needed. The following script example
demonstrates adding a prefix based on the location an employee works at to the Badge ID being imported:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define the settings for the first location


var location1Settings = {
// The badge group the badges should be placed in
badgeGroup: "ALL_BADGES",

// The field in the employee/assignment data containing the badge ID


// Concatentation being done here assuming script is running on a SQL Server
// database
badgeIdField: "'LOCATION1' + a.imported_badge_id",

// Only include the badges for the employees in that location


criteria: "e.locationID = 'LOCATION1'",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Define the settings for the second location


var location1Settings = {
// The badge group the badges should be placed in
badgeGroup: "ALL_BADGES",

// The field in the employee/assignment data containing the badge ID


// Concatentation being done here assuming script is running on a SQL Server
// database
badgeIdField: "'LOCATION2' + a.imported_badge_id",

// Only include the badges for the employees in that location


criteria: "e.location_ID = 'LOCATION2'",

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 97


WT&A API Specifications 18.3 Badge Import API

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definitions to the API, defining the WorkForce Time and Attendance HR data
as the data
// source
api.addEmpCenterSource(location1Settings);
api.addEmpCenterSource(location2Settings);

// Import the Badge data


api.importBadges();

Example 4: Looking up the badge group from a field in the HR data


In addition to using hard-coded Badge Group names, where all Badges processed are assigned to the same
Badge Group, the Badge Import API also includes functionality for dynamically assigning Badges to a Badge
Group based on an attribute in the employee/assignment data.
The following script examples demonstrates assigning each Badge to a Badge Group named for the location
the employee is assigned to:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define the settings for the source data


var sourceSettings = {
// The badge group the badges should be placed in. The badge will be assigned
// to a badge group with the name corresponding to the value in the indicated
// field in the HR data
badgeGroup: "e.location_id",

// The field in the employee/assignment data containing the badge ID


badgeIdField: "a.imported_badge_id",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the WorkForce Time and Attendance HR data as
the data
// source
api.addEmpCenterSource(sourceSettings);

// Import the Badge data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 98


WT&A API Specifications 18.3 Badge Import API

api.importBadges();

Example 5: Calculating the badge group using custom calculations


When the source data alone does not provide sufficient information to determine the Badge Group, or when
modifications need to be made to the values in the source data in order to use them as the Badge Group, a
custom function can be defined in the source definition for the Badge Import API to use to calculate the
Badge Group for each record being processed.
The following script example demonstrates using a function to extract the first three characters from the
location and append them to the end of a common prefix in order to determine the desired Badge Group
name:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");
includeDistributedPolicy("PERSON_DATA_API");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define the settings for the source data


var sourceSettings = {
// Specify the function to use to calculate the badge group
badgeGroupFunction: badgeGroupCalculationFunction,

// The field in the employee/assignment data containing the badge ID


badgeIdField: "a.imported_badge_id",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the WorkForce Time and Attendance HR data as
the data
// source
api.addEmpCenterSource(sourceSettings);

// Import the Badge data


api.importBadges();

// Custom function for calculating the badge group for a record


function badgeGroupCalculationFunction(sourceData) {
var condition = new MatchCondition(MatchTable.EMPLOYEE, "EMPLOYEE",
MatchOperator.EQUALS, sourceRecord.getLong("employee") );
var personDataApi = new PersonDataAPI();
var employee = personDataApi.getEmployeeRecord(condition, WFSDate.today() );

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 99


WT&A API Specifications 18.3 Badge Import API

var location = employee.location_id;

// Define the badge group as a common prefix plus the first three characters of
// the location
var badgeGroup = "PRE" + location.substr(0, 3);

return badgeGroup;
}

Importing Badges from a CSV File


When the Badge information cannot be supplied as part of the normal HR data being processed by the
Employee Import, the Badge Import API also supports reading the Badge information from a CSV file. The
CSV file is expected to include the employee ID and Badge ID, and can also optionally include the Badge
Group, effective date, end effective date, and status of the Badge record.
If an effective date is supplied, then the Badge data will be treated as effective starting on that date.
Otherwise, the Badge data is considered to be effective starting on the current system date.
The Badge’s status can be indicated in one of two ways. The first is by specifying the status in the source
data. When that happens, a record with a status of ‘A’ will be treated as active starting on the associated
effective date and a record with a status of ‘T’ will be treated as terminated starting on that effective date.
(This is represented by the Badge record being end dated one second before the provided effective date.)
Alternatively, instead of providing a status, the Badge data can explicitly specify an end date for the Badge,
which will deactivate the Badge as of the end of that date.
The following script example demonstrates using the Badge Import API to load Badge data from a CSV file
named “badge_data.csv”. The Badges will be placed in the Badge Group “ALL_BADGES”:

Example 1: Importing badges


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID" // The name of the field containing the badge ID
};

// Define the settings for the source data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 100


WT&A API Specifications 18.3 Badge Import API

var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 2: Trimming source values


Sometimes the values received for the Badge ID in the file include additional information at the beginning of
the ID. For instance, the Badges may use the same IDs as the employees, but the employee IDs may include
an extra prefix at the beginning. (e.g. Employee E12345 having Badge 12345.)
The Badge Import API includes functionality to allow these prefixes to be stripped off the values in the file to
arrive at the correct ID to store for the Badge. The following script example demonstrates how the leading ‘E’
could be removed in the above scenario:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "EMP_ID" // Read the badge from the same field as the employee
};

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 101


WT&A API Specifications 18.3 Badge Import API

sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// All recurrences of this string will be removed from the beginning of the badge
// ID. This will remove the leading Es on the value in this case.
trimString: "E",

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 3: Specifying badge group in the source data


When the Badge data in the CSV needs to be assigned to more than just a single Badge Group, the Badge
Import API allows the source data to specify which Badge Group the Badge should be placed in. This allows a
single file to contain data for multiple different Badge Groups.
The following script example demonstrates how to set up the Badge Import API to read the Badge Group
from a file:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID", // The name of the field containing the badge ID
BADGE_GROUP: "GROUP" // The name of the field identifying the badge group
};

// Define the settings for the source data


var sourceSettings = {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 102


WT&A API Specifications 18.3 Badge Import API

// The file containing the badge data that should be processed


sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 4: Reclassifying badge groups from the source data


Sometimes the source data contains Badge Group information, but the values in the source data are not
exactly the values that should be used for the Badges. For these cases, the Badge Import API supports
reclassifying the values in the source data into the actual values that should be used.
The reclassification map defines a translation between the values in the source data and the Badge Group
names that should be used. If the Badge Group specified in the source data matches one of the keys defined
in the reclassification map, then the corresponding value will be used as the actual Badge Group name.
Otherwise, if the value in the source data does not match a key in the map, then the default Badge Group will
be used.
The following script example demonstrates using the reclassification map:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID", // The name of the field containing the badge ID
BADGE_GROUP: "GROUP" // The name of the field identifying the badge group
};

// Define the reclassification map. In this case, we're assuming that the badges
// are being grouped by state and that the source file contains the abbreviation

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 103


WT&A API Specifications 18.3 Badge Import API

// for the state while the actual badge group should be the full state name.
var reclassificationMap = {
MI: "MICHIGAN",
OH: "OHIO",
IN: "INDIANA"
};

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// Specify the reclassification map to use for the badge groups


badgeGroupReclassificationMap: reclassificationMap,

// Specify the default badge group to use if the reclassification map does
// not have an entry for the provided badge group value
defaultBadgeGroupReclassification: "UNKNOWN_STATE",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 5: Calculating the badge group using custom calculations


When the source data alone does not provide sufficient information to determine the Badge Group, or when
modifications need to be made to the values in the source data in order to use them as the Badge Group, a
custom function can be defined in the source definition for the Badge Import API to use to calculate the
Badge Group for each record being processed.
The following script example demonstrates using a function to extract the first three characters from the
location and append them to the end of a common prefix in order to determine the desired Badge Group
name:
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");
includeDistributedPolicy("PERSON_DATA_API");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 104


WT&A API Specifications 18.3 Badge Import API

// This will be used for processing the source data.


var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID" // The name of the field containing the badge ID
};

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// Specify the function to use to calculate the badge group


badgeGroupFunction: badgeGroupCalculationFunction,

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

// Custom function for calculating the badge group for a record


function badgeGroupCalculationFunction(sourceData) {
var condition = new MatchCondition(MatchTable.EMPLOYEE, "EMPLOYEE",
MatchOperator.EQUALS, sourceRecord.getLong("employee") );
var personDataApi = new PersonDataAPI();
var employee = personDataApi.getEmployeeRecord(condition, WFSDate.today() );
var location = employee.location_id;

// Define the badge group as a common prefix plus the first three characters of
// the location
var badgeGroup = "PRE" + location.substr(0, 3);

return badgeGroup;
}

Example 6: Importing badges while validating the file character set


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 105


WT&A API Specifications 18.3 Badge Import API

// default settings will all be used.


var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID" // The name of the field containing the badge ID
};

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC,

// Character set of the source file


characterSet: “UTF-8”,

// Specify whether to enforce character set encoding validation


enforceCharsetEncoding: true
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 7: Importing badges while specifying delimiter


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 106


WT&A API Specifications 18.3 Badge Import API

overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the CSV file correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "EMP_ID", // The name of the field containing the employee ID
BADGE: "BADGE_ID" // The name of the field containing the badge ID
};

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.csv",

// The field name mappings for the file


fieldNames: fieldNames,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC,

// Delimiter of the source file


delimiter: ";"
};

// Add the source definition to the API, defining the CSV file as the data source
api.addCsvSource(sourceSettings);

// Import the Badge data


api.importBadges();

Importing Badges from a Fixed-Width File


In addition to importing data from CSV files, the Badge Import API also supports reading the Badge
information from fixed-width files. Like with CSV files, the fixed-width file is expected to include the
employee ID and Badge ID, and can also optionally include the Badge Group, effective date, end effective
date, and status of the Badge record.
The fields that can be defined for a fixed-width file are the same as with a CSV file, and they behave in the
same fashion. The only difference between processing CSV files and fixed-width files is that where the CSV
version of the import just needs to know what the fields are called, the fixed-width version of the import
needs to know both how wide the fields are and at what position in the record they begin at. A
FixedWidthFields object needs to be created, and then for each of the fields that are present in the file the
corresponding setter method (such as fields.setEmployeeId() or fields.setBadge()) should be called specifying
the starting position and the width of the field.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 107


WT&A API Specifications 18.3 Badge Import API

The following script example demonstrates using the Badge Import API to load Badge data from a fixed-width
file named “badge_data.txt”. The Badges will be placed in the Badge Group “ALL_BADGES”:

Example 1: Importing data from a fixed-width file


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define which fields are present in the fixed-width file, their starting
// positions, and their length.
var fields = new FixedWidthFields();
fields.setEmployeeId(0, 10); // The employee ID is the first 10 characters
fields.setBadge(10, 7); // The badge ID is the 7 characters after that

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.txt",

// The field definitions for the file


fixedWidthFields: fields,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the fixed-width file as the
// data source
api.addFixedWidthSource(sourceSettings);

// Import the Badge data


api.importBadges();

Example 2: Importing data from a fixed-width file while validating the file character set
includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the
// default settings will all be used.
var importParameters = {
updateBadges: true,
checkForDuplicates: true,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 108


WT&A API Specifications 18.3 Badge Import API

overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Define which fields are present in the fixed-width file, their starting
// positions, and their length.
var fields = new FixedWidthFields();
fields.setEmployeeId(0, 10); // The employee ID is the first 10 characters
fields.setBadge(10, 7); // The badge ID is the 7 characters after that

// Define the settings for the source data


var sourceSettings = {
// The file containing the badge data that should be processed
sourceFile: "interface/incoming/badge_data.txt",

// The field definitions for the file


fixedWidthFields: fields,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC

// Character set of the source file


characterSet: “UTF-8”,

// Specify whether to enforce character set encoding validation


enforceCharsetEncoding: true
};

// Add the source definition to the API, defining the fixed-width file as the
// data source
api.addFixedWidthSource(sourceSettings);

// Import the Badge data


api.importBadges();

Importing Badges Using a Custom Query


The Badge Import API can also be used to import Badges defined by a custom query. While this can be used
to query Badge information out of external databases, that practice is generally discouraged. More often this
would be used when Badge data is stored in a non-standard location within the WorkForce Time and
Attendance database, such as an LD table.
The following example demonstrates importing Badge data using a custom query to select the data to be
imported out of the LD20 table. The Badges will be placed in the Badge Group “ALL_BADGES”:

Example: Importing badges using a custom query


includeDistributedPolicy("BADGE_IMPORT_LIBRARY");

// Define the general settings for the Badge Import. In this case, the

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 109


WT&A API Specifications 18.3 Badge Import API

// default settings will all be used.


var importParameters = {
updateBadges: true,
checkForDuplicates: true,
overrideManualChanges: false,
allowOneBadgePerGroup: true
};

// Create a new instance of the Badge Import API, using the defined settings.
// This will be used for processing the source data.
var api = new BadgeImport(importParameters);

// Definitions of which fields in the query results correspond to which values


// The properties of this object are EMPLOYEE_ID, BADGE, BADGE_GROUP, EFF_DATE,
// END_EFF_DATE, and STATUS_CODE. EMPLOYEE_ID and BADGE are mandatory, the rest
// are optional based on the data that is being received.
var fieldNames = {
EMPLOYEE_ID: "LD1", // The name of the field containing the employee ID
BADGE: "OTHER_STRING1" // The name of the field containing the badge ID
};

// Define the query to use to select the badge data


var query = "select ld1, other_string1 from ld20";

// Define the settings for the source data


var sourceSettings = {
// The DB Connection Info policy defining which database should be queried
// to retrieve the badge information
dbConnectionPolicy: "EMPCENTER_DATABASE",

// Specify the query to use to select the badge data


externalQuery: query,

// The field name mappings for the file


fieldNames: fieldNames,

// The badge group the badges should be placed in


badgeGroup: "ALL_BADGES",

// Specify whether the badge ID are numeric or alpha-numeric


badgeIdType: BadgeIdType.ALPHA_NUMERIC
};

// Add the source definition to the API, defining the SQL query as the data source
api.addSqlSource(sourceSettings);

// Import the Badge data


api.importBadges();

Troubleshooting
The job log of the script using the Badge Import API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 110


WT&A API Specifications 18.3 Badge Import API

Error Message Problem Solution


defaultBadgeGroupReclassi The parameters for a badge source Ensure that all badge source
fication must be set when definition specified a Badge Group definitions that define a
defining reclassification map, but did not reclassification map also define a
badgeGroupReclassification specify a default value to use when default reclassification to use when
Map the Badge Group doesn’t match an the Badge Group doesn't match an
item in the map. This default value entry in the map.
is required so that the
reclassification process can
function correctly.
Badge number The Badge ID on the Badge record Ensure that Badge IDs are unique for
(BADGE_NUMBER) is a being processed matched a Badge all employees within the same Badge
duplicate badge. New ID already assigned to a different Group.
badge not created employee within the same Badge
Group.
Effective date prior to The effective date specified for the Ensure that the effective date
existing record; new record Badge record is earlier than the specified in the source data is the
effective START_TIME not existing start date for the Badge same or later than the effective date
imported. record. The Badge record’s active used to create the Badge record
range will not be extended initially.
backwards to include the
additional dates.
Employee does not exist in The employee ID associated with Ensure that all of the employee IDs
the system the Badge data does not match specified in the source data match
any of the employees defined in employees defined in WorkForce
WorkForce Time and Attendance. Time and Attendance. Matching is
always performed against the
display_employee field.
End effective date The end date provided in the Ensure that all of the end dates in the
END_DATE before effective source date was earlier than the source data are the same date or a
date START_DATE start date provided on that same later date than the start date on the
record. same record.
No app user value defined The employee ID specified in the Ensure that a user record exists in
for employee source data matches an employee WorkForce Time and Attendance for
EMPLOYEE_ID in WorkForce Time and all employees that should have a
Attendance, but that employee badge record.
does not have a corresponding
user record.
TABLE_PREFIX is not a valid The Badge Group specified for an Ensure that all table prefixes specified
table prefix WorkForce Time and Attendance in the Badge Group definition are
source indicated that Badge Group valid prefixes to be used. The allowed
should be pulled from a field in the values are e, a, am, au, grp, and sd.
tables, but the table prefix
specified is not one of the allowed
prefixes.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 111


WT&A API Specifications 18.3 Badge Import API

Source file doesn’t exist The specified file containing the Ensure that the source data file
source data for a CSV or fixed- specified exists in the indicated
width source could not be found in directory and is able to be read by
the specified directory. WorkForce Time and Attendance.
Table 26: Badge Import API common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to make best use of this section.
The Badge Import API uses the BadgeImport to import Badge data from a data source. The Badge Import API
takes advantage of FixedWidthFields, which define information about fields in a fixed-width file.
The following is a summary of the available methods and common uses:

BadgeImport
BadgeImport(importParameters)
Creates a new instance of the Badge Import API, which can be used for importing Badge and Badge Group
data.
The following parameters can be specified when creating a new instance of this object:
Parameter Name Description
updateBadges Determines whether Badge records allow updates,
or whether they will be deleted and replaced.
Defaults to allowing updates to Badge records.
Determines whether the import process will check
for duplicate Badge data or not. A Badge is
considered a duplicate if it shares the same Badge
checkForDuplicates ID as another Badge, the effective dates overlap,
and the Badges belong to different employees or
different Badge Groups. Defaults to checking for
duplicates.
overrideManualChanges Determines whether the import will allow a Badge
to be updated when it has been manually edited.
Defaults to not allowing updates to manually-edited
records.
allowOneBadgePerGroup Determines whether the import will enforce that an
employee only has a single Badge within a Badge
Group, ending their previous Badge if a new one is
imported in the same Badge Group. Defaults to
only allowing one Badge per employee in a Badge
Group.
Table 27: Allowed parameters when creating a new BadgeImport

addEmpCenterSource(sourceParameters)
Adds a new source of Badge data to the API, specifying that Badge data from the HR data was already
imported into the employee/assignment tables. This will be used to drive the import behavior when Badge
data is ultimately imported.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 112


WT&A API Specifications 18.3 Badge Import API

The following parameters can be specified when calling this method:


Parameter Name Description
badgeGroup Badge Group to add the badges to. Can be either a
hard-coded value or a database table/field
combination.
JavaScript function that calculates the Badge Group
badgeGroupFunction
to add the badge to based on the source data.
badgeIdField The database table/field combination to read the
Badge ID from.
badgeIdType The type of Badges being imported (either Alpha-
Numeric or Numeric).
criteria SQL criteria to use to determine if a badge should
be created or not.
scheduleCriteria SQL criteria to use to select which schedule record
should be used when keying Badge information off
the schedule_detail table.
trimString Character or string of characters that should be
recursively removed from the beginning of the
Badge ID.
comments Value to be added to the comments field of all
Badge records created.
policyProfiles Array of policy profiles that should have Badges
processed for this definition. If empty or not
specified, all policy profiles will be processed.
Table 28: Allowed parameters when creating new WorkForce Time and Attendance source

addSqlSource(sourceParameters)
Adds a new source of Badge data to the API, specifying that Badge data should be queried using a custom
query. This will be used to drive the import behavior when Badge data is ultimately imported.
The following parameters can be specified when calling this method:
Parameter Name Description
externalQuery Query to use to select badge information
dbConnectionPolicy DB Connection Info policy defining the database
connection to use to execute the query.
fieldNames JS object mapping, which maps from the expected
data component to the field in the source query
that contains values for that component.
Components that can be specified include
EMPLOYEE_ID, BADGE_GROUP, BADGE, EFF_DATE,
END_EFF_DATE, and STATUS_CODE.
badgeGroup Badge Group to add the badges to. Only used if
BADGE_GROUP is not defined in fieldNames.
JavaScript function that calculates the Badge Group
badgeGroupFunction
to add the badge to based on the source data.
badgeIdType The type of Badges being imported (either Alpha-
Numeric or Numeric).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 113


WT&A API Specifications 18.3 Badge Import API

badgeGroupReclassificationMap JS object mapping that maps Badge Group values in


the source data to the actual Badge Group policy
name that should be used.
defaultBadgeGroupReclassification Default Badge Group that should be assigned if the
Badge Group specified in the source data does not
match any mappings in the
badgeGroupReclassificationMap.
trimString Character or string of characters that should be
recursively removed from the beginning of the
Badge ID.
comments Value to be added to the comments field of all
Badge records created.
dateFormat Format of dates found in the source fields.
Table 29: Allowed parameters when creating new SQL-based source

addCsvSource(sourceParameters)
Adds a new source of Badge data to the API, specifying that Badge data should be read from a CSV file. This
will be used to drive the import behavior when Badge data is ultimately imported.
The following parameters can be specified when calling this method:
Parameter Name Description
sourceFile The fully-qualified file name for the file containing
the Badge data to be imported.
fieldNames JS object mapping, which maps from the expected
data component to the field in the source data that
contains values for that component. Components
that can be specified include EMPLOYEE_ID,
BADGE_GROUP, BADGE, EFF_DATE,
END_EFF_DATE, and STATUS_CODE.
badgeGroup Badge Group to add the badges to. Only used if
BADGE_GROUP is not defined in fieldNames.
JavaScript function that calculates the Badge Group
badgeGroupFunction
to add the badge to based on the source data.
badgeIdType The type of Badges being imported (either Alpha-
Numeric or Numeric).
badgeGroupReclassificationMap JS object mapping that maps Badge Group values in
the source data to the actual Badge Group policy
name that should be used.
defaultBadgeGroupReclassification Default Badge Group that should be assigned if the
Badge Group specified in the source data does not
match any mappings in the
badgeGroupReclassificationMap.
trimString Character or string of characters that should be
recursively removed from the beginning of the
Badge ID.
comments Value to be added to the comments field of all
Badge records created.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 114


WT&A API Specifications 18.3 Badge Import API

dateFormat Format of dates found in the source fields.


encrypted Boolean to specify if the source file is encrypted.
characterSet Optional character encoding to use for the file. The
valid options include the following:
• US-ASCII
• ISO-8859-1
• UTF-8
• UTF-16BE
• UTF-16LE
• UTF-16
Defaults to UTF-8 if not specified.
enforceCharsetEncoding Boolean value for enforcing character set encoding
validation.
Delimiter Optional. Delimiter for the csv file. Default value is
comma (“,”).
Table 30: Allowed parameters when creating new CSV-based source

addFixedWidthSource(sourceParameters)
Adds a new source of Badge data to the API, specifying that Badge data should be read from a fixed-width
file. This will be used to drive the import behavior when Badge data is ultimately imported.
The following parameters can be specified when calling this method:
Parameter Name Description
sourceFile The fully-qualified file name for the file containing
the Badge data to be imported.
fixedWidthFields FixedWidthFields object defining the fields in the
file, their sizes, and relative positions.
badgeGroup Badge Group to add the badges to. Only used if
BADGE_GROUP is not defined in fixedWidthFields.
JavaScript function that calculates the Badge Group
badgeGroupFunction
to add the badge to based on the source data.
badgeIdType The type of Badges being imported (either Alpha-
Numeric or Numeric).
badgeGroupReclassificationMap JS object mapping that maps Badge Group values in
the source data to the actual Badge Group policy
name that should be used.
defaultBadgeGroupReclassification Default Badge Group that should be assigned if the
Badge Group specified in the source data does not
match any mappings in the
badgeGroupReclassificationMap.
trimString Character or string of characters that should be
recursively removed from the beginning of the
Badge ID.
comments Value to be added to the comments field of all
Badge records created.
dateFormat Format of dates found in the source fields.
encrypted Boolean to specify if the source file is encrypted.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 115


WT&A API Specifications 18.3 Badge Import API

characterSet Optional character encoding to use for the file. The


valid options include the following:
• US-ASCII
• ISO-8859-1
• UTF-8
• UTF-16BE
• UTF-16LE
• UTF-16
Defaults to UTF-8 if not specified.
enforceCharsetEncoding Boolean value for enforcing character set encoding
validation.
Table 31: Allowed parameters when creating new fixed-width-file-based source

addWebserviceSource(sourceParameters)
Adds a new source of Badge data to the API, specifying that Badge data should be read from the payload of a
web service call. This will be used to drive the import behavior when Badge data is ultimately imported.
The following parameters can be specified when calling this method:
Parameter Name Description
badgeData The WebserviceBadgeList object holding the data
from the webservice payload.
badgeGroup Badge Group to add the badges to. Only used if
BADGE_GROUP is not defined in the source data.
JavaScript function that calculates the Badge
badgeGroupFunction Group to add the badge to based on the source
data.
badgeIdType The type of Badges being imported (either Alpha-
Numeric or Numeric).
badgeGroupReclassificationMap JS object mapping that maps Badge Group values
in the source data to the actual Badge Group
policy name that should be used.
defaultBadgeGroupReclassification Default Badge Group that should be assigned if the
Badge Group specified in the source data does not
match any mappings in the
badgeGroupReclassificationMap.
trimString Character or string of characters that should be
recursively removed from the beginning of the
Badge ID.
comments Value to be added to the comments field of all
Badge records created.
Table 32: Allowed parameters when creating new web-service-based source

importBadges()
Imports Badge data using all of the defined Badge sources, in the order in which they were defined.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 116


WT&A API Specifications 18.3 Badge Import API

FixedWidthFields
FixedWidthFields
Defines a new object to store information about field widths and positions within a fixed-width file.

setEmployeeId(start, width)
Specifies the width of the Employee ID field in the file and the column position where the data begins.

setBadgeGroup(start, width)
Specifies the width of the Badge Group field in the file and the column position where the data begins.

setBadge(start, width)
Specifies the width of the Badge field in the file and the column position where the data begins.

setEffDate(start, width)
Specifies the width of the Eff Date field in the file and the column position where the data begins.

setEndEffDate
Specifies the width of the End Eff Date field in the file and the column position where the data begins.

setStatusCode(start, width)
Specifies the width of the Status Code field in the file and the column position where the data begins.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 117


WT&A API Specifications 18.3 Bank Export API

Bank Export API


Definitions of Terms Used in This Section
Adapter – Class that defines how the Bank Export API should filter and manipulate the bank data in order to
arrive at the data that should be exported, and how that data should be written to the Output Destination.
Custom Hooks – JavaScript functions that can be defined that will be executed at pre-determined points in
the export process in order to allow custom behavior to be added above and beyond what is defined by the
Adapter. Used when using a pre-defined standard Adapter to introduce customer-specific behavior.
Export Control – Object containing customer-specific settings that control the export behavior as defined by
the Adapter.
Output Destination – Definition of a location, such as a file or a database table, where the exported data can
be written to. Also defines how the exported data will be written to that location.

Overview and Capabilities


The Bank Export API provides a mechanism for calculating, processing, and exporting bank data. It is
expected to be used as part of a larger job that needs to extract the most current bank balance, accrual, or
usage information from WorkForce Time and Attendance for a range of dates in order to place that data into
a file, a database table, or some other destination as needed.
As part of its processing, the Bank Export API will calculate all timesheets in the specified range for the
identified employees as needed in order to ensure that the bank data being processed reflects all of the
latest timesheet information. This is done in a multi-threaded fashion to ensure overall performance when
processing the employees, with the results being loaded into the BANK_EXPORT table. The resulting data in
that table is then queried, sorted, and filtered as needed by the API in order to get the final set of records
that will be written out to the export destination. The data in BANK_EXPORT will remain there until cleaned
out by the Clean Tables process, and can be used for troubleshooting the export behavior after the fact.
The way the data is processed by the API is controlled by an export Adapter, which defines what bank
information is being written to the Output Destination and how the data that is being written is formatted.
While certain standard Output Destinations and processing Adapters are provided as part of the API itself—
such as an Adapter to write the information to a CSV file—the API also allows for custom Adapters and
Output Destinations to be defined as needed in order to meet a customer’s requirements.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• WorkForce Time and Attendance banks and accruals/usage

Components
This API consists of the following component(s):
• The distributed JavaScript library BANK_EXPORT_API

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 118


WT&A API Specifications 18.3 Bank Export API

Setup
No setup is necessary for the Bank Export API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Exporting Data Using the Standard CSV Adapter
The Bank Export API includes a standard Adapter that can be used to write data to a CSV file. With this
Adapter, data is mapped from the EMPLOYEE, ASGNMT, and BANK_EXPORT tables by means of a Decoder
policy. The field names specified for the destination in the Decoder will be used as the field names that are
created in the file, if a header row is being written.
This Adapter supports the following additional Export Control settings (beyond the standard ones supported
by all Adapters):
Property Name Required Description
filePath Y The directory in which the export
file should be created.
The name of the export file that
filename Y
should be created.
createHeader N True if a header row should be
written to the file, false if not.
Defaults to true if not specified.
Delimiter N The delimiter that should be
placed between fields in the CSV
file. Defaults to a comma (,) if not
specified.
Decoder Y The name of the Decoder policy
that should be used to map the
data to the output file.
decoderDestination N The name of the column in the
Decoder policy that specifies the
export file mappings. Defaults to
DESTINATION if not specified.
Table 33: Additional Export Control settings for the standard CSV Adapter

A sample decoder for use with this Adapter would be:


EMPLOYEE , ASGNMT , BANK_EXPORT , TYPE , DESTINATION
DISPLAY_EMPLOYEE , , , STRING , EmployeeID
, POLICY_PROFILE , , STRING , PolicyProfile
, , BANK , STRING , BankName
, , BALANCE , NUMBER , Balance
, , AS_OF_DATE , DATE , Date

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 119


WT&A API Specifications 18.3 Bank Export API

With that Decoder, the resulting file would include the header row:
EmployeeID,PolicyProfile,BankName,Balance,Date
The order of the fields in the Decoder determines the order in which the fields will be generated in the file.

Example 1: Exporting data without any custom hooks


The most basic case for using the standard CSV Adapter is to use it without defining any Custom Hooks to
execute customer-specific logic. The following script example demonstrates what this might look like:
includeDistributedPolicy("BANK_EXPORT_API");

// Get the adapter to use for exporting the data


var adapter = BankExportAPI.getCSVAdapter();

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

// Condition to select which assignments should be exported. In this case, only


// assignments in the NON_EXEMPT profile will be exported
asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",
MatchOperator.EQUALS, "NON_EXEMPT"),

// The name of the directory the export file should be created in


filePath: "interface/outgoing/",

// The name of the file that should be created


fileName: "bank_export.csv",

// The name of the decoder policy to use to define the mappings


decoder: "BANK_EXPORT_DECODER"
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

// Export the data for the date range


api.exportBankData(startDate, endDate);

Example 2: Exporting data with custom hooks defined


Custom Hooks can be defined in order to introduce additional customer-specific logic into the export process.
The following script demonstrates defining a custom recordFilter hook that will prevent consecutive identical
records from being exported and a custom recordMapping hook that formats the bank balance being
exported to only include a single decimal place:
includeDistributedPolicy("BANK_EXPORT_API");

// Get the adapter to use for exporting the data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 120


WT&A API Specifications 18.3 Bank Export API

var adapter = BankExportAPI.getCSVAdapter();

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

// Condition to select which assignments should be exported. In this case, only


// assignments in the NON_EXEMPT profile will be exported
asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",
MatchOperator.EQUALS, "NON_EXEMPT"),

// The name of the directory the export file should be created in


filePath: "interface/outgoing/",

// The name of the file that should be created


fileName: "bank_export.csv",

// The name of the decoder policy to use to define the mappings


decoder: "BANK_EXPORT_DECODER",

// Custom recordFilter hook. Filters out consecutive identical records, such as


// the records that are created at the beginning of each period if there isn't a
// corresponding balance change on that date
recordFilter: function(employee, asgnmt, bankData) {
if (typeof priorData == "undefined") {
priorData = {employee: null, asgnmt: null, bank: null, balance: null};
}

if (priorData.employee != employee.employee ||
priorData.asgnmt != asgnmt.asgnmt ||
priorData.bank != bankData.bank ||
priorData.balance != bankData.balance) {
priorData = {
employee: employee.employee,
asgnmt: asgnmt.asgnmt,
bank: bankData.bank,
balance: bankData.balance
};
return true;
}
return false;
},

// Custom recordMapping function. Only exports a single decimal place for the
// bank balance, instead of the full precision
recordMapping: function(record, destination, employee, asgnmt, bankData) {
record.balance = new WFSDecimal(record.balance).toString("0.#"); }
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 121


WT&A API Specifications 18.3 Bank Export API

// Export the data for the date range


api.exportBankData(startDate, endDate);

Example 3: Defining a custom sort order


The data that is processed through to the export file will always be processed in a sorted order. By default,
the employee and assignment records will be ordered by their employee.employee and asgnmt.asgnmt
values, from lowest to highest, while the banks will be ordered by their policy IDs in alphabetical order.
These sorting orders can be overridden as desired if a custom ordering is needed for a specific configuration.
The following script example demonstrates how to change the sorting to order the employees by
display_employee value and to order the banks in reverse alphabetical order instead:
includeDistributedPolicy("BANK_EXPORT_API");
includeDistributedPolicy("PERSON_DATA_API");

// Get the adapter to use for exporting the data


var adapter = BankExportAPI.getCSVAdapter();

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

// Condition to select which assignments should be exported. In this case, only


// assignments in the NON_EXEMPT profile will be exported
asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",
MatchOperator.EQUALS, "NON_EXEMPT"),

// The name of the directory the export file should be created in


filePath: "interface/outgoing/",

// The name of the file that should be created


fileName: "bank_export.csv",

// The name of the decoder policy to use to define the mappings


decoder: "BANK_EXPORT_DECODER",

// Define a custom comparator to define how the employees will be sorted in the
// export file. In this case, employees will be sorted in alphabetical order by
// their display_employee value
employeeComparator: BankExportAPI.createComparator(function(first, second) {
var personDataApi = new PersonDataAPI();
var today = WFSDate.today();

var firstCondition = new MatchCondition(MatchTable.EMPLOYEE, "EMPLOYEE",


MatchOperator.EQUALS, first);
var firstEmployee = personDataApi.getEmployeeRecord(firstCondition, today);

var secondCondition = new MatchCondition(MatchTable.EMPLOYEE, "EMPLOYEE",


MatchOperator.EQUALS, second);
var secondEmployee = personDataApi.getEmployeeRecord(secondCondition, today);

if (first.display_employee == second.display_employee) {
return 0;
}
if (first.display_employee > second.display_employee) {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 122


WT&A API Specifications 18.3 Bank Export API

return 1;
}
return -1;
}),

// Define a custom comparator to define how the banks will be sorted in the
// export file. In this case, banks will be sorted in reverse alphabetical order
bankComparator: BankExportAPI.createComparator(function(first, second) {
var firstStr = "" + first;
var secondStr = "" + second;

if (firstStr == secondStr) {
return 0;
}
if (firstStr > secondStr) {
return -1;
}
return 1;
}
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

// Export the data for the date range


api.exportBankData(startDate, endDate);

Exporting Data Using a Custom Adapter


In addition to the standard Adapters that are defined, the Bank Export API allows for custom Adapters to be
built. This allows the API to be used to handle unique situations where none of the standard Adapters are
sufficient to meet the customer’s needs.
Custom Adapters can make use of the standard Output Destinations that are available, such as an
unencrypted file, and encrypted file, or an LD table, or they can define their own custom Output Destinations
if none of the standard ones are sufficient.

Example 1: Using a standard output destination


The following script example demonstrates creating a custom Adapter that writes data to the LD7 table, using
the standard LD table Output Destination:
includeDistributedPolicy("BANK_EXPORT_API");

// Define the output destination that should be used to write the data to the LD
// table. In this case, the data will be written to the LD7 table and will have two
// key fields
var outputDestination = BankExportAPI.getLdTableOutputDestination(7, 2);

// Define the custom adapter. This adapter will only export data for employees in
// the EXEMPT policy profile, storing the data to be exported on records in the LD
// table.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 123


WT&A API Specifications 18.3 Bank Export API

var adapter = BankExportAPI.createNewAdapter({

// Adapter method to access the output destination that should be used


getOutputDestination: function() {
return outputDestination;
},

// Adapter method to filter which employees should have data exported


recordFilter: function(employee, asgnmt, bankData) {
// Filter out any assignments that are not in the EXEMPT policy profile
return (asgnmt.policy_profile == "EXEMPT");
},

// Adapter method to build the initial data mappings to be exported


recordMapping: function(employee, asgnmt, bankData) {
var exportData = new BankExportData();
exportData.ld2 = employee.display_employee;
exportData.ld1 = bankData.bank;
exportData.other_date1 = bankData.as_of_date;
exportData.other_number1 = bankData.balance;
exportData.other_number2 = bankData.accrued;
exportData.other_number3 = bankData.used;
exportData.other_number4 = bankData.cleared;
exportData.other_number5 = bankData.terminated;
exportData.other_number6 = bankData.transferred;
return exportData;
},

// Adapter method to write the fully-mapped bank export data to the output
// destination
recordProcessing: function(data) {
var ldRec = new DbRec("LD_STAGE");
ldRec.ld2 = data.ld2;
ldRec.ld1 = data.ld1;
ldRec.other_date1 = data.other_date1;
ldRec.other_number1 = data.other_number1;
ldRec.other_number2 = data.other_number2;
ldRec.other_number3 = data.other_number3;
ldRec.other_number4 = data.other_number4;
ldRec.other_number5 = data.other_number5;
ldRec.other_number6 = data.other_number6;
outputDestination.writeData(ldRec);
},

// Adapter method to cleanup the output destination. Will process the newly
// written LD_STAGE records through to the actual table.
cleanupOutputDestination: function() {
outputDestination.close();
}
});

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

// Condition to select which assignments should be exported. In this case, all


// assignments that are not in the NON_EXEMPT policy profile will be exported

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 124


WT&A API Specifications 18.3 Bank Export API

asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",


MatchOperator.NOT_EQUALS, "NON_EXEMPT")
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

// Export the data for the date range


api.exportBankData(startDate, endDate);

Example 2: Using a custom output destination


The following script demonstrates using a custom Adapter to export data to the LD7 table, using a custom
Output Destination to write the data:
includeDistributedPolicy("BANK_EXPORT_API");

// Define the output destination that should be used to write the data to the LD
// table. In this case, the data will be written to the LD7 table and will have two
// key fields
var outputDestination = BankExportAPI.createOutputDestination( {

// Define how data should be written to the table


writeData: function(data) {
// Create a DbRecList to store the records being exported.
if (typeof this.dbRecList == "undefined") {
this.dbRecList = new Packages.com.workforcesoftware.Data.DbRecList();
}

// Map the data from the export record mapping to the LD record
var record = new DbRec("LD7");
record.ld2 = data.ld2;
record.ld1 = data.ld1;
record.other_date1 = data.other_date1;
record.other_number1 = data.other_number1;
record.other_number2 = data.other_number2;
record.other_number3 = data.other_number3;
record.other_number4 = data.other_number4;
record.other_number5 = data.other_number5;
record.other_number6 = data.other_number6;
record.eff_dt = WFSDate.VERY_EARLY_DATE;
record.end_eff_dt = WFSDate.VERY_LATE_DATE;

// Add the LD record to the list of records to be written to the table


this.dbRecList.add(record);
},

// Perform any cleanup necessary. This will commit the records to the LD table.
close: function() {
Packages.com.workforcesoftware.Util.DB.ListWriter.writeList(this.dbRecList);
}
});

// Define the custom adapter. This adapter will only export data for employees in

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 125


WT&A API Specifications 18.3 Bank Export API

// the EXEMPT policy profile, storing the data to be exported on records in the LD
// table.
var adapter = BankExportAPI.createNewAdapter({

// Adapter method to access the output destination that should be used


getOutputDestination: function() {
return outputDestination;
},

// Adapter method to filter which employees should have data exported


recordFilter: function(employee, asgnmt, bankData) {
// Filter out any assignments that are not in the EXEMPT policy profile
return (asgnmt.policy_profile == "EXEMPT");
},

// Adapter method to build the initial data mappings to be exported


recordMapping: function(employee, asgnmt, bankData) {
var exportData = new BankExportData();
exportData.ld2 = employee.display_employee;
exportData.ld1 = bankData.bank;
exportData.other_date1 = bankData.as_of_date;
exportData.other_number1 = bankData.balance;
exportData.other_number2 = bankData.accrued;
exportData.other_number3 = bankData.used;
exportData.other_number4 = bankData.cleared;
exportData.other_number5 = bankData.terminated;
exportData.other_number6 = bankData.transferred;
return exportData;
},

// Adapter method to write the fully-mapped bank export data to the output
// destination
recordProcessing: function(data) {
var ldRec = new DbRec("LD_STAGE");
ldRec.ld2 = data.ld2;
ldRec.ld1 = data.ld1;
ldRec.other_date1 = data.other_date1;
ldRec.other_number1 = data.other_number1;
ldRec.other_number2 = data.other_number2;
ldRec.other_number3 = data.other_number3;
ldRec.other_number4 = data.other_number4;
ldRec.other_number5 = data.other_number5;
ldRec.other_number6 = data.other_number6;
outputDestination.writeData(ldRec);
},

// Adapter method to cleanup the output destination. Will process the newly
// written LD_STAGE records through to the actual table.
cleanupOutputDestination: function() {
outputDestination.close();
}
});

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 126


WT&A API Specifications 18.3 Bank Export API

// Condition to select which assignments should be exported. In this case, all


// assignments that are not in the NON_EXEMPT policy profile will be exported
asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",
MatchOperator.NOT_EQUALS, "NON_EXEMPT")
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

// Export the data for the date range


api.exportBankData(startDate, endDate);

Example 3: Using custom hooks with a custom adapter


Custom Adapters continue to support the use of Custom Hooks, which behave in the exact same way that
they do when used with the standard Adapters. While in many scenarios the use of Custom Hooks alongside
custom Adapters is discouraged (if you’re building a custom Adapter that can do all of the processing, in
general there should be no need to add Custom Hooks as well), if the custom Adapter is going to be shared
between multiple uses—e.g. as part of a common library—then the Adapter should just contain the common
behavior and Custom Hooks can be used to define any necessary process-specific logic.
The following script example demonstrates defining Custom Hooks alongside a custom Adapter:
includeDistributedPolicy("BANK_EXPORT_API");

// Define the output destination that should be used to write the data to the LD
// table. In this case, the data will be written to the LD7 table and will have two
// key fields
var outputDestination = BankExportAPI.getLdTableOutputDestination(7, 2);

// Define the custom adapter. This adapter will only export data for employees in
// the EXEMPT policy profile, storing the data to be exported on records in the LD
// table.
var adapter = BankExportAPI.createNewAdapter({

// Adapter method to access the output destination that should be used


getOutputDestination: function() {
return outputDestination;
},

// Adapter method to filter which employees should have data exported


recordFilter: function(employee, asgnmt, bankData) {
// Filter out any assignments that are not in the EXEMPT policy profile
return (asgnmt.policy_profile == "EXEMPT");
},

// Adapter method to build the initial data mappings to be exported


recordMapping: function(employee, asgnmt, bankData) {
var exportData = new BankExportData();
exportData.ld2 = employee.display_employee;
exportData.ld1 = bankData.bank;
exportData.other_date1 = bankData.as_of_date;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 127


WT&A API Specifications 18.3 Bank Export API

exportData.other_number1 = bankData.balance;
exportData.other_number2 = bankData.accrued;
exportData.other_number3 = bankData.used;
exportData.other_number4 = bankData.cleared;
exportData.other_number5 = bankData.terminated;
exportData.other_number6 = bankData.transferred;
return exportData;
},

// Adapter method to write the fully-mapped bank export data to the output
// destination
recordProcessing: function(data) {
var ldRec = new DbRec("LD_STAGE");
ldRec.ld2 = data.ld2;
ldRec.ld1 = data.ld1;
ldRec.other_date1 = data.other_date1;
ldRec.other_number1 = data.other_number1;
ldRec.other_number2 = data.other_number2;
ldRec.other_number3 = data.other_number3;
ldRec.other_number4 = data.other_number4;
ldRec.other_number5 = data.other_number5;
ldRec.other_number6 = data.other_number6;
outputDestination.writeData(ldRec);
},

// Adapter method to cleanup the output destination. Will process the newly
// written LD_STAGE records through to the actual table.
cleanupOutputDestination: function() {
outputDestination.close();
}
});

// Define the export control settings to use when exporting data


var exportControl = {
// Name of the bank set defining which banks should be exported
banks: "BANKS_TO_EXPORT",

// Condition to select which assignments should be exported. In this case, all


// assignments that are not in the NON_EXEMPT policy profile will be exported
asgnmtCondition: new MatchCondition(MatchTable.ASGNMT, "POLICY_PROFILE",
MatchOperator.NOT_EQUALS, "NON_EXEMPT"),

// Custom recordFilter hook. Filters out consecutive identical records, such as


// the records that are created at the beginning of each period if there isn't a
// corresponding balance change on that date
recordFilter: function(employee, asgnmt, bankData) {
if (typeof priorData == "undefined") {
priorData = {employee: null, asgnmt: null, bank: null, balance: null};
}

if (priorData.employee != employee.employee ||
priorData.asgnmt != asgnmt.asgnmt ||
priorData.bank != bankData.bank ||
priorData.balance != bankData.balance) {
priorData = {
employee: employee.employee,
asgnmt: asgnmt.asgnmt,
bank: bankData.bank,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 128


WT&A API Specifications 18.3 Bank Export API

balance: bankData.balance
};
return true;
}
return false;
}
};

// Create a new instance of the API, using the desired adapter and export control
// settings
var api = new BankExportAPI(adapter, exportControl);

// Define the date range that should be exported


var startDate = new WFSDate(2016, 3, 17);
var endDate = new WFSDate(2016, 6, 21);

// Export the data for the date range


api.exportBankData(startDate, endDate);

Troubleshooting
The job log of the script using the Bank Export API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No adapter specified; unable A new BankExportAPI was created Ensure that an Adapter is specified
to export data without an Adapter having been whenever a new BankExportAPI object
specified. is instantiated.
No export control settings A new BankExportAPI was created Ensure that Export Control settings are
specified; unable to export without an Export Control having provided whenever a new
data been specified. BankExportAPI object is instantiated.
No period defined for policy An attempt was made to export Ensure that all policy profile groups
profile group GROUP_ID data for an assignment where that linked to assignments being processed
that includes the date DATE. assignment’s policy profile belongs are initialized and that they have
Please check the policy to a policy profile group that does periods defined that cover the date
profile group to ensure it not have any periods defined that range being exported.
has been initialized and that overlap the beginning of the date
periods are defined for the range being exported.
necessary date range
(DATE_RANGE)
No bank set found with The bank set that was specified on Ensure that the bank set specified in
name BANK_SET_NAME the Export Control did not the Export Control settings
correspond to a Bank Set defined in corresponds to a valid Bank Set
the WorkForce Time and defined in the WorkForce Time and
Attendance configuration. Attendance configuration.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 129


WT&A API Specifications 18.3 Bank Export API

Unable to identify The Export Control did not define Ensure that either the assignment
assignments to process; no either a MatchCondition to select selection condition or an assignment
match condition or assignments or an assignment group ID are specified in the Export
assignment group ID group ID. Control settings whenever a new
specified BankExportAPI object is instantiated.
No assignment group found The assignment group ID specified Ensure that the assignment group ID
with display ID on the Export Control did not specified in the Export Control settings
ASGNMT_GROUP_ID correspond to the display ID of any matches the display ID of an
assignments groups that are assignment group that exists.
currently defined.
Value provided for hook The value provided in the Export Ensure that all of the values provided
HOOK_NAME is expected to Control for one of the Custom in the Export Control settings for
be of type Function. Instead Hooks had a datatype other than Custom Hooks are functions.
it was of type TYPE Function.
Hook HOOK_NAME expects The function definition provided in Ensure that all Custom Hooks defined
to have ARG_COUNT the Export Control for the specified in the Export Control settings are
arguments, but instead Custom Hook included the wrong expecting to receive the right number
NUMBER arguments were number of arguments. of arguments for the type of Custom
specified Hook being defined.
No file path specified for the No value was provided for the Ensure that the filePath property is
export destination filePath property on the Export specified in the Export Control settings
Control when using the standard and that it points to the directory the
CSV Adapter. file should be exported to.

No file name specified for No value was provided for the Ensure that the fileName property is
the export destination fileName property on the Export specified in the Export Control settings
Control when using the standard and that it specifies the file name that
CSV Adapter. the export data should be written to.
No decoder policy specified No value was provided for the Ensure that the decoder property is
to define export mapping decoder property on the Export specified in the Export Control and that
Control when using the standard it specifies the name of the Decoder
CSV Adapter. policy that should be used to map data
from the employee/assignment/bank
data to the export file.
Call made to writeData with writeData was called on the Output Ensure that writeData is always called
a null value Destination with a null value for the with a non-null value when using the
data when using the standard LD standard LD Table Output Destination.
Table Output Destination.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 130


WT&A API Specifications 18.3 Bank Export API

Call made to writeData with writeData was called on the Output Ensure that writeData is always called
invalid object type. Object Destination with an invalid data with a DbRec for the LD_STAGE table
was expected to be of type type when using the standard LD when using the standard LD Table
com.workforcesoftware.Gen Table Output Destination. Output Destination.
.Other.DbRec.DbRecLd_stag
e, but instead it was of type
TYPE
Table 34: Bank Export API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Bank Export API makes use of:
1) The BankExportAdapter, which defines a set of behavior for exporting bank information.

2) The OutputDestination, which defines how data should be written out by the Adapter.

3) The BankExportData, which stores the data being mapped during the export process.

4) The BankExportAPI, which runs the actual export process and allows for custom BankExportAdapters
and OutputDestinations to be defined.

See the contents of the BANK_EXPORT_API policy in the Distributed JavaScript Library category for full
documentation on these methods. The following is a summary of the available methods and common uses:

BankExportAdapter
defineAdapterSettings(customerSettings)
Runs as the very first step of export processing, defining what the processing behavior for the Adapter should
be based on the customer-specific settings.

getOutputDestination()
Returns the Output Destination that is being used by the Adapter.

exportPreProcessing()
Defines the behavior that the export should execute after all initial setup is complete, but before executing
the step to calculate the relevant bank data and write it to the BANK_EXPORT table.

computationPostProcessing()
Defines the behavior that the export should execute after the relevant bank data has been written to the
BANK_EXPORT table but before anything has been queried from that table to be written out to the Output
Destination.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 131


WT&A API Specifications 18.3 Bank Export API

setupOutputDestination()
Performs any initial setup that is needed for the Output Destination, before any data is written to it. For
example, this could be used to make sure the target file exists and is ready for writing, and to write a header
row to that file.

employeePreProcessing(employee)
Runs at the beginning of processing a single employee. For example, this could be used to write an opening
tag for employee-specific data to an XML file.

assignmentPreProcessing(employee, asgnmt)
Runs at the beginning of processing one assignment for the employee. For example, this could be used to
write an opening tag for assignment-specific data to an XML file.

bankPreProcessing(employee, asgnmt, bankName)


Runs at the beginning of processing one bank for the assignment. For example, this could be used to write an
opening tag for bank-specific data to an XML file.

recordFilter(employee, asgnmt, bankData)


Evaluates to either true or false to specify whether a given combination of employee, assignment, and bank
data should be exported. Can be used to filter out undesired bank records, such as the records that occur on
the first day of a period even if there isn’t a change to the bank balance.

recordMapping(employee, asgnmt, bankData)


Constructs a mapping of data that should be written to the Output Destination.

recordProcessing(data)
Performs any processing necessary for the final mapped record, such as writing it to the Output Destination.

bankPostProcessing(employee, asgnmt, bankName)


Runs at the end of processing one bank for the assignment. For example, this could be used to write a closing
tag for bank-specific data to an XML file.

assignmentPostProcessing(employee, asgnmt)
Runs at the end of processing one assignment for the employee. For example, this could be used to write a
closing tag for assignment-specific data to an XML file.

employeePostProcessing(employee)
Runs at the end of processing a single employee. For example, this could be used to write a closing tag for
employee-specific data to an XML file.

exportPostProcessing()
Runs at the end of the export, after all employees have been processed. Allows for any final processing to be
done to write data to the Output Destination, such as writing a footer record to a CSV file.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 132


WT&A API Specifications 18.3 Bank Export API

cleanupOutputDestination()
Performs any cleanup needed to close and free up any resources used by the Output Destination, such as
closing the file handle or committing database changes. This should almost always call the close() method
on the Output Destination.

OutputDestination
writeData(data)
Writes the specified data to the Output Destination, in whatever fashion is appropriate for the target
destination. For instance, for a CSV file this could write out each property defined in the data, separated by a
comma, to the target file.

close()
Performs any cleanup needed to close and free up any resources used by the Output Destination, such as
closing the file handle or committing database changes.

BankExportData
BankExportData(fieldsAllowed…)
Creates a new record to contain mapped export data for processing by the Adapter and Custom Hooks. This
should be created during the recordMapping stage of the Adapter, and can be further modified during the
recordMapping Custom Hook. It will then be passed to the Output Destination to complete the export of the
record.
If one or more allowed fields are specified, only properties corresponding to one of the named fields will be
allowed to be populated on the BankExportData object. This allows the Adapter to enforce that only specific
fields are being mapped, such as when a file is going to contain only a fixed set of fields.

BankExportAPI
BankExportAPI(adapter, exportControlSettings)
Creates a new instance of the Bank Export API, using the specified Adapter and Export Control settings.
The Export Control includes the following standard properties:
Property Name Description
Banks Name of the Bank set that identifies which banks
should be processed by the export.
MatchCondition specifying which assignments
asgnmtCondition
should be processed by the export.
asgnmtGroup The display ID of the assignment group containing
the assignments that should be processed by the
export. (If both asgnmtCondition and asgnmtGroup
are specified, the asgnmtCondition will be used to
select the assignments.)
employeeComparator Comparator used to define the order in which
employees should be processed by the export.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 133


WT&A API Specifications 18.3 Bank Export API

asgnmtComparator Comparator used to define the order in which


assignments should be processed by the export.
(Assignments are only sorted within a single
employee.)
bankComparator Comparator used to define the order in which banks
are processed by the export. (Banks are only sorted
within a single assignment.)
debuggingEnabled Indicates if debug output should be written to the
job log or not.
displayCalculationLogContent Indicates if the log output generated during the step
to compute the bank data and write it to the
BANK_EXPORT table should be included in the job
log or not.
Table 35: Standard Export Control properties that are available

In addition to the standard properties, the following Custom Hooks can also be defined:
Hook Name Definition
preprocessing Allows custom logic to be executed after the export
is set up but before the step to write data to
BANK_EXPORT is performed.
Allows custom logic to be executed after the step to
write data to BANK_EXPORT is completed but
postComputation
before doing any processing on the data that was
loaded into BANK_EXPORT.
employeePreProcessing Allows custom logic to be executed at the beginning
of processing each new employee.
asgnmtPreProcessing Allows custom logic to be executed at the beginning
of processing each new assignment for an
employee.
bankPreProcessing Allows custom logic to be executed at the beginning
of processing each new bank for an assignment.
recordFilter Allows custom logic to be defined to filter out bank
records that should not be exported. Cannot be
used to override the filter conditions defined by the
Adapter.
recordMapping Allows custom logic to be defined to update the
mapped data built by the Adapter before it is
processed to the Output Destination.
bankPostProcessing Allows custom logic to be executed at the end of
processing a bank for an assignment.
asgnmtPostProcessing Allows custom logic to be executed at the end of
processing an assignment for an employee.
employeePostProcessing Allows custom logic to be executed at the end of
processing a single employee.
postprocessing Allows custom logic to be executed at the end of
processing all employees.
Table 36: Custom Hooks that can be defined on the Export Control object

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 134


WT&A API Specifications 18.3 Bank Export API

Additional settings beyond those listed in the above two tables can also be specified. These settings and
their use are defined by the specific Adapter being used.

exportBankData(startDate, endDate)
Executes the export process to evaluate all bank changes that fall within the specified start and end dates for
the applicable assignments. If an assignment doesn’t have a change to the bank on the specified start date, a
record will still be processed for that date containing the balance as of that date (with no other usage/accrual
associated with it).

createNewAdapter(adapterDefinition)
Static function that creates a new custom Adapter using the provided definition. The Adapter definition
provided needs to be a JavaScript object that defines functions implementing some/all of the methods
defined in the BankExportAdapter section._BankExportAdapter

createOutputDestination(destinationDefinition)
Static function that creates a new custom Output Destination using the provided definition. The Output
Destination definition provided needs to be a JavaScript object that defines functions implementing some/all
of the methods defined in the OutputDestination section._OutputDestination

createComparator(comparisonFunction)
Static function that creates a new Comparator to use for sorting the employees, assignments, or banks that
are being processed by the export. The comparison function should accept two arguments and return -1 if
the first argument should come before the second argument, 1 if the first argument should come after the
second argument, or 0 if both arguments should be treated as having the same value.

getCSVAdapter(enableDebugging)
Returns the standard Adapter for writing to a CSV file.

getFileOutputDestination(filePath, fileName, encryptionAlias, charset)


Returns the standard OutputDestination for writing to a file in the specified directory with the indicated file
name. The encryptionAlias, if provided, is used to find key to use to encrypt the file. Optionally, the charset
parameter specifies character encoding to use for the file. Valid options are:
US-ASCII
ISO-8859-1
UTF-8
UTF-16BE
UTF-16LE
UTF-16
Defaults to UTF-8 if not specified

getLdTableOutputDestion(tableNumber, keyFields)
Returns the standard OutputDestination for writing to the indicated LD table, treating the data as containing
the indicated number of key fields.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 135


WT&A API Specifications 18.3 Bank Import API

Bank Import API


Overview and Capabilities
The Bank Import API provides methods to aid in importing bank balance information. It is intended to be
used from within a CSV Employee Import Control or SQL Employee Import Control batch job.

Prerequisites
To use this API, you should know the following:

• Basic JavaScript coding

Components
The component(s) of the Bank Import Library include the following:

• The BANK_BALANCE_LIBRARY Distributed JavaScript library

Setup
No setup is necessary for the Bank Balance API. The distributed library is automatically available within
WT&A.

Use Cases
Import bank balance data using a policy. Since this is a policy driven library, the source configuration
(whether it’s SQL, CSV, etc.) will be handled via the policy.

// include the library


includeDistributedPolicy("BANK_IMPORT_LIBRARY");
// specify field names to verify in source
var fieldNames = ["EMPLOYEE_ID", "ASGNMT_ID", "AS_OF_DATE", "BANK", "HOURS"];
// create a new instance of api
var bankBalanceImport = new BankBalanceImportAPI(fieldNames);
// setup configurations
bankBalanceImport.setDateFormat("yyyy-MM-dd");
bankBalanceImport.setRequirePeriodEndDate(false);
bankBalanceImport.setUseCurrentPeriodDate(false);
bankBalanceImport.setDeleteExistingRecords(false);
bankBalanceImport.setTesting(false);
// initiate import for employee and assignment in scope
bankBalanceImport.importBankBalances(employee, assignment, mappingFunction);

function mappingFunction(source) {
var AGGREGATE_BANKS = ["PTO_AGG"];

bankBalanceImport.importToAggregateBanks(AGGREGATE_BANKS.indexOf(source.BANK) >= 0);


if (source.BANK == "HOURS_WORKED_PER_JOB*_3F6F52AA") {
bankBalanceImport.setDynamicBankImport(true);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 136


WT&A API Specifications 18.3 Bank Import API

var data = source.BANK.split("*");


}
return {
"employeeId": source.EMPLOYEE_ID,
"asgnmtId": source.ASGNMT_ID,
"asOf": source.AS_OF_DATE,
"bank": (typeof data == "undefined") ? source.BANK : data[0],
"instance": (typeof data == "undefined") ? null : data[1],
"balance": source.HOURS
};
}

Troubleshooting
The job log of the script using the Bank Import Library will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.
Error Message Problem Solution
No employeeId specified Self-explanatory Correct any error in file and retry
No asgnmtId specified Self-explanatory Correct any error in file and retry
No asOf date specified Self-explanatory Correct any error in file and retry
No balance specified Self-explanatory Correct any error in file and retry
Non-numeric balance Self-explanatory Correct any error in file and retry
<balance> specified
Static/Dynamic Bank <bank> Self-explanatory Make sure it exists and the name is
does not exist correct
Missing expected fields in Field list provided, are not present Make sure the fields provided and the
source data: <field names> in the source fields present in source match
As-of date <date> does not Self-explanatory As-of date must coincide with period
fall on a period end date end date
Specified locale parameter is Invalid locale parameter type or Make sure correct type is being passed
not a valid java.util.Locale missing locale parameter in
object setDateFormat

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Bank Import Library consists of the following public initializer component:
• BankBalanceImportAPI. It contains the following public methods:
o importBankBalances
o setTesting
o importToAggregateBanks
o setDateFormat
o setRequirePeriodEndDate
o setUseCurrentPeriodDate

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 137


WT&A API Specifications 18.3 Bank Import API

o setDeleteExistingRecords
o setDynamicBankImport
The following is a summary of the available methods and common uses:

BankBalanceImportAPI(fieldNames, isDynamicBank)
Creates a new instance of the Bank Import API.

importBankBalances (employee: Scriptable


assignment: Scriptable
mappingFunction: jsFunction
sqlEmployeeImportPolicy: String
mappingAdjustmentFunction: jsFunction)
Imports balance data.

setTesting (isTesting: boolean)


Activates/deactivates testing mode. Data is not written to table in testing mode.

importToAggregateBanks (useAggregateBanks: boolean)


Determines whether or not the data being imported should be mapped to the aggregate assignment. For
multiple assignment configurations only.

setDateFormat (formatStr: String, locale: java.util.Locale)


Sets the expected format for dates being imported.

setRequirePeriodEndDate (requirePeriodEndDate: boolean)


Controls whether or not the import should validate that the as-of date for the record being imported is a
period end date.

setUseCurrentPeriodDate (useCurrentPeriodDate: boolean)


Controls whether or not the import should default the day before the current period begin date as the as-of
date for the record if no as-of date is specified in the import data.

setDeleteExistingRecords (deleteExistingRecords: boolean)


Controls whether the record being imported should be used only to delete existing records. If True, no new
records will be imported.

setDynamicBankImport (isDynamicBank: boolean)


Determines whether dynamic bank is to be imported.

getNamespaceUri() -> String


Returns the namespace URI.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 138


WT&A API Specifications 18.3 Batch Job Log Policy Tracker API

Batch Job Log Policy Tracker API


Overview and Capabilities
The Batch Job Log Policy Tracker API provides scripts running in WorkForce Time and Attendance the ability
to query for batch job logs using a string constant. The functionality provided by this API can either be used
within a script solely dedicated to that purpose, such as a script to get a summary of a specific job, or it can
be used as part of a larger process to accomplish just a portion of the desired task.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The BATCH_JOB_LOG_POLICY_TRACKER_API Distributed JavaScript library
• This automatically includes the API_UTIL Distributed JavaScript library

Setup
No setup is necessary for the Batch Job Log Policy Tracker API. The distributed library is automatically
available within WorkForce Time and Attendance.

Use Cases
Getting summary for a particular job
The Batch Job Log Policy Tracker API allows a script to lookup the summary of a particular job including run
count, successful run count, last run time etc. This is useful if a certain action needs to be performed after
the success of a particular job.

Example: getting summary of a batch job


includeDistributedPolicy("BATCH_JOB_LOG_POLICY_TRACKER_API");

// Create an instance of the API


var api = new BatchJobLogPolicyTrackerAPI ();

// get a record for a particular job by providing policy id and batch job type
var batchJobLogPolicyTracker = batchJobLogPolicyTrackerAPI
.getRecordByPolicyIdAndBatchJobType('INT_1065_LD_KEY_LD_IMPORT_TEST', 'SCRIPT_RUNNER');

log.info("Number of times this job has executed: " + batchJobLogPolicyTracker.RUNS_COUNT);

Note: If the condition specified matches more than one assignment, an exception will be generated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 139


WT&A API Specifications 18.3 Batch Job Log Policy Tracker API

Troubleshooting
The job log of the script using the Batch Job Log Policy Tracker API will contain information messages and, in
the case of problems, any error messages generated during processing. This job log should be reviewed if
there are any problems encountered while using the API.

Error Message Problem Solution


More than one The policy id and batch job type Escalate this issue. This shouldn’t have
BatchJobLogPolicyTracker provided returned multiple rows. happened
records found matching Encountering this error means that
condition there is a problem with the way this
API is functioning. You should not
get this error in normal
circumstances.
ArrayIndexOutOfBoundsExc The policy id and batch job type Ensure that the parameters being used
eption specified did not match the log are correct and should actually have a
records. log. It could also indicate that the job
has not yet run.
Table 37: Batch Job Log Policy Tracker API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Batch Job Log Policy Tracker API consists of just one public component:
• BatchJobLogPolicyTrackerAPI
o It contains just 1 public method defined as, getRecordByPolicyIdAndBatchJobType(policyId:
String, batchJobType: String). returns a Readonly record of Batch_job_log_policy_tracker
class
The following fields are available in the returned record:

Batch_job_log_policy_tracker
BATCH_JOB_TYPE
An integer number that is used by the system to recognize this job internally (may not be of much use to the
script writers).

LAST_RUN_DTTM
WFSDateTime object for the last time this job ran regardless of success.

LAST_SUCCESSFUL_RUN_DTTM
WFSDateTime object for the last time this job ran successfully.

POLICY_ID
The policy ID for this job. Should be the same as what was supplied in the API get method.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 140


WT&A API Specifications 18.3 Batch Job Log Policy Tracker API

RUNS_COUNT
Number of times this job executed regardless of success.

SUCCESSFUL_RUNS_COUNT
Number of times this job ran successfully.

SYSTEM_RECORD_ID
A number for this record that is unique across the entire database.

SYSTEM_TIMESTAMP
Last timestamp this record was written at.

SYSTEM_UPDATE_COUNTER
The number of times this record has been updated.

BatchJobLogPolicyTrackerAPI
Creates a new instance of the Timesheet Operations API.

getRecordByPolicyIdAndBatchJobType(policyId: String, batchJobType: String)


Queries database for the policyId and batchJobType provided in the batch job log policy tracker table and
returns a Read only record of type Batch_job_log_policy_tracker.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 141


WT&A API Specifications 18.3 Decoder API

Decoder API
Overview and Capabilities
A “decoder” is an easy way to define column mappings between third-party source files and WT&A tables via
a Decoder Policy. The goal is to be able to define all the mappings in a single place, and then use the decoder
to access the mappings in the code. This way, if the mappings need to be changed in the future, only the
Decoder Policy needs to be changed.
To use the decoder, first define a Decoder Policy in the Policy Editor. In the Decoder Text field, enter the
column mappings as you would a CSV file, with a heading row and delimited columns. After the Decoder
Policy has been defined, the decoder can be used by importing DECODER_API in a script and using the
methods defined in this Distributed JavaScript Library.

Prerequisites
To use this API, you should know the following:
• Basic JavaScript coding
• How to create a Decoder Policy
• Understand how a decoder works

Components
This Distributed JavaScript Library consists of a single component, DECODER_API.

Setup
No setup is necessary for Decoder API. This distributed library is automatically available within WorkForce
Time and Attendance.
You must create a Decoder Policy in the Policy Records > Interfaces > Decoder Policy section and refer to that
policy name in your script that uses the DECODER_API.

Use Cases
Creating a Decoder
The following example shows sample decoder text that has been entered into a Decoder Policy:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 142


WT&A API Specifications 18.3 Decoder API

For more information on the Decoder Policy, see the WorkForce Time and Attendance Policy Configuration
Guide.

Creating and Using a Decoder Object


Example 1: Using the decoder for CSV-based source data
includeDistributedPolicy("DECODER_API");
importClass(Packages.com.workforcesoftware.Gen.Choice.Import_source);

var sourceFile = "Employees.csv";


// Defines decoder name
var decoderPolicy = "DECODER_POLICY";

// Creates a Decoder object


var decoder = new Decoder(decoderPolicy, true, "SOURCE", Import_source.CSV);
var source = new CSVResultSet(sourceFile);

// Validates source data contains all the fields defined in decoder source column
decoder.validateSourceColumns(source, false);

// Returns an array of string having header values


var header = decoder.getHeader();
for (i = 0; i < header.length; i++) {
log.info("Column " + (i + 1) + " : " + header[i]);
}

// Validates all the required fields are populated


decoder.validateRequired(source, true);

// Validates source data with defined valid values


decoder.validateValues(source, true);

// Validates source data with specified format


decoder.validateFormats(source, true);

// Gets decoder map object


appUserMap = decoder.getMap("SOURCE", "APP_USER");

// Returns an array of string having keys of the map


var keys = appUserMap.getKeys().sort();
for (i = 0; i < keys.length; i++) {
log.info((i + 1) + " : " + keys[i]);
}

// Returns an array of string having values of the map


var values = appUserMap.getValues().sort();
for (i = 0; i < values.length; i++)
log.info((i + 1) + " : " + values[i]);

// Call this method to change which column of the decoder text is being treated as the source
(i.e. to have the Decoder override the defined source column)
var tableName = "EMPLOYEE_STAGE";
decoder.setSourceColumn(tableName);

// Returns string array of all the fields for specified column name
var tableFields = decoder.getFieldsInColumn(tableName);
for (i = 0; i < tableFields.length; i++){

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 143


WT&A API Specifications 18.3 Decoder API

log.info((i + 1) + " : " + tableFields[i]);


}

Example 2: Using the decoder for SQL-based source data


includeDistributedPolicy("DECODER_API");
importClass(Packages.com.workforcesoftware.Gen.Choice.Import_source);

// Defines decoder name


var decoderPolicy = "DECODER_POLICY";

// Creates decoder object


var decoder = new Decoder(decoderPolicy);

// Sets value of source type as SQL


decoder.setSourceType(Import_source.SQL);

// Enables automatically trim of input values


decoder.setAutoTrimValues(true);

// Turns ON logging of debug messages.


decoder.debugOn();
/* It can be closed at any point by calling decoder.debugOff() */

// Prints entire decoder text


decoder.print();

var connection;
var sql;

try {
connection = new Connection();
var query = "select e.eff_dt as EFF_DT, e.display_employee as EMP_ID, e.last_name as
LAST_NAME," + " e.first_name as FIRST_NAME, e.middle_name as MID_NAME, 'A' as PS_STATUS, null
as FTE," + " e.other_number1 as OTHER_NUMBER, e.emp_date1 as ORIG_HIRE, e.emp_date2 as
ADJ_HIRE," + " e.emp_date3 as TERM_DATE, e.ld1 as LD, au.last_login_dttm as TIMESTAMP from
employee e," + " app_user au where e.employee = au.employee";

// Creates SQL scriptable having source data


sql = new Sql(connection, query);

// Gets decoder map object


employeeMap = decoder.getMap("SOURCE_DATA", "EMPLOYEE");
assignmentMap = decoder.getMap("SOURCE_DATA", "ASGNMT");

// Validates if source data contains all the fields defined in decoder source column
decoder.validateSourceColumns(sql, false);

while (sql.next()) {

// Validates required fields, valid values and specified format of source data
decoder.validateSource(sql, true);

// Creates DbRec Scriptables for target objects


var employee = new DbRec("EMPLOYEE");
var asgnmt = new DbRec("ASGNMT");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 144


WT&A API Specifications 18.3 Decoder API

// Sets all fields from source result set to target object


decoder.setFieldsFromSource(employee, sql, employeeMap);
decoder.setFieldsFromSource(asgnmt, sql, assignmentMap);

try {
if (employee.emp_date2 != WFSDate.valueOf("2018-01-01", "yyyy-MM-dd")) {
throw "employee.emp_date2";
}
else if (employee.middle_name != "ABC") {
throw "employee.middle_name";
}
} catch (e) {
throw "" + e + " field not set with default value";
}
}
}
catch (e) {
log.error(e);
}
finally {
if (connection)
connection.close();
if (sql)
sql.close();
}

Example 3: Using the decoder for CSV-based source data in File Manager Object
includeDistributedPolicy("DECODER_API");
includeDistributedPolicy("FILE_MANAGER_API");
importClass(Packages.com.workforcesoftware.Gen.Choice.Import_source);

var sourceFile = "Employees.csv";


var sourcePath = "/importCsv/";

// Defines decoder name


var decoderPolicy = "DECODER_POLICY";

// Creates a Decoder object


var decoder = new Decoder(decoderPolicy);

//Declare and Initialize new object for File Manager API


var fileManager = new FileManager();
fileManager.setDateFormat("MM/dd/yyyy");
fileManager.setFile(sourcePath, sourceFile);

//Set File Manager API Parameters


var fileParams = {
delimiter: ",",
hasHeaderRecord: true,
useUppercaseHeaders: true,
discardBOM: false,
fileHeader: decoder3.getFieldsInColumn("SOURCE_DATA").map(String), //Replace SOURCE_DATA
with the source column name in decoder
charSet: "UTF-8",
encrypted: false

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 145


WT&A API Specifications 18.3 Decoder API

};
fileManager.openFile(fileParams);

// Validates source data contains all the fields defined in decoder source column
decoder.validateSourceColumns(fileManager, false);

// Returns an array of string having header values


var header = decoder.getHeader();
for (i = 0; i < header.length; i++) {
log.info("Column " + (i + 1) + " : " + header[i]);
}

// Validates all the required fields are populated


decoder.validateRequired(fileManager, true);

// Validates source data with defined valid values


decoder.validateValues(fileManager, true);

// Validates source data with specified format


decoder.validateFormats(fileManager, true);

// Gets decoder map object


appUserMap = decoder.getMap("SOURCE_DATA", "APP_USER");

// Returns an array of string having keys of the map


var keys = appUserMap.getKeys().sort();
for (i = 0; i < keys.length; i++) {
log.info((i + 1) + " : " + keys[i]);
}

// Returns an array of string having values of the map


var values = appUserMap.getValues().sort();
for (i = 0; i < values.length; i++)
log.info((i + 1) + " : " + values[i]);

// Call this method to change which column of the decoder text is being treated as the source
(i.e. to have the Decoder override the defined source column)
var tableName = "EMPLOYEE_STAGE";
decoder.setSourceColumn(tableName);

// Returns string array of all the fields for specified column name
var tableFields = decoder.getFieldsInColumn(tableName);
for (i = 0; i < tableFields.length; i++){
log.info((i + 1) + " : " + tableFields[i]);
}

Creating and Using a Decoder Map Object


includeDistributedPolicy("DECODER_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Creates decoder object with autoTrimValues to true


var decoder = new Decoder(decoderPolicy, true);
var sourceFile = "Employees.csv";
var source = new CSVResultSet(sourceFile);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 146


WT&A API Specifications 18.3 Decoder API

try {
// Gets decoder map object
employeeMap = decoder.getMap("SOURCE_DATA", "EMPLOYEE");
assignmentMap = decoder.getMap("SOURCE_DATA", "ASGNMT");
appUserMap = decoder.getMap("SOURCE_DATA", "APP_USER");

// Validates source data contains all the fields defined in decoder source column
decoder.validateSourceColumns(source, false);

while (source.next()) {

// Validates required fields, valid values and specified format of source data
decoder.validateSource(source, false);

var employee = new DbRec("EMPLOYEE");


var asgnmt = new DbRec("ASGNMT");

// Sets all fields from source result set to target object


decoder.setFieldsFromSource(employee, source, employeeMap);
decoder.setFieldsFromSource(asgnmt, source, assignmentMap);

try {
if (employee.emp_date2 != WFSDate.valueOf("2018-01-01", "yyyy-MM-dd")) {
throw "employee.emp_date2";
}
else if (employee.middle_name != "ABC") {
throw "employee.middle_name";
}
} catch (e) {
throw "" + e + " field not set with default value";
}
}

// Returns mapped value of provided key


var empId = employeeMap.get("EMP_ID");
if (empId != "DISPLAY_EMPLOYEE")
throw "Unexpected field name " + empId;

var empMatchId = assignmentMap.getOne("EMP_ID");


if (empMatchId != "COMPUTED_MATCH_ID")
throw "Unexpected field name " + empMatchId;

// Returns an array of mapped values


var empName = employeeMap.getAll("FIRST_NAME");

// Returns an array of string having keys of the map


var keys = appUserMap.getKeys().sort();
log.info("Total keys of appUserMap: " + keys.length);

// Returns an array of string having values of the map


var values = appUserMap.getValues().sort();
log.info("Total values of appUserMap: " + values);
}
catch (e) {
log.error(e);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 147


WT&A API Specifications 18.3 Decoder API

Troubleshooting
Following table lists some common exceptions and error messages caused by the Decoder API, their causes,
and possible solutions.

Error Message Cause Solution


Key mapped to multiple values Multiple values are returned by In case of multiple values
(key --> value). Usage of get() decoderMap.get(key) method. against a single key, use
presupposes that key maps to a the getOne(key) or
single value. In the case of getAll(key) method
multiple mapped values, instead.
getOne() or getAll() must be
called.
Source object must be of type Invalid source type provided in Provide the appropriate
Scriptable or ResultSet the source type (Scriptable or
validateSourceColumns(source) ResultSet)
method
Expected field does not exist in Decoder source field does not exist in Provide correct field
the source data actual source data names in the decoder
<columnName> is not a valid Incorrect or empty column name Provide valid column name
column in the Decoder Text provided in
setSourceColumn(sourceColumnOverride)
method of decoder
The Import_source choice is not Import_source choice type is neither SQL Provide allowable
supported by the Decoder nor CSV Import_source choice type
(SQL or CSV)
Invalid value specified for Invalid value is provided in source data Provide valid value of
<field>. Valid options are: source data
<validOptions>
Integer/Number does not match Incorrect integer or number format of Provide value in valid
defined format source data format
String is longer than the defined Length of source data string is greater Provide valid value of
max length than defined format in decoder source data
No functionality defined for call Invalid destination object type provided in Provide allowable type
to setFields with a target object setFieldsFromSource method (that is, DbRec or
Scriptable)
Error creating DecoderMap Possible SQL Exception occurred Check DB connection
from <sourceColumn> to information
<destinationColumn > (Decoder
Policy ID: <decoderPolicy>)
Error parsing decoder text from Possible SQL Exception occurred Check DB connection
Decoder Policy ID: information
<decoderPolicy>
Error printing decoder text from Possible SQL Exception occurred Check DB connection
Decoder Policy ID: information
<decoderPolicy>

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 148


WT&A API Specifications 18.3 Decoder API

Error Message Cause Solution


Error retrieving fields defined in Possible SQL Exception occurred Check DB connection
column (Decoder Policy ID: information
<decoderPolicy>)

API Reference
Decoder
Decoder object can be created in a script by simply calling the constructor with the policy ID of the decoder.

Decoder(decoderPolicy, autoTrimValues, sourceColumnOverride, sourceType)


To create a decoder object that can be used in a script, call the constructor with the policy ID of the desired
Decoder Policy as a single argument.
For example:
var decoder = new Decoder("DECODER_POLICY_ID", autoTrimValues, sourceColumnOverride,
sourceType);

Parameter Description
decoderPolicy: String Name of the Decoder Policy to use for building data maps
autoTrimValues: Boolean To have the decoder automatically trim leading and trailing
whitespace on all input data, set autoTrimValues to true
(default is false)
sourceColumnOverride: String To override what column of the Decoder Text is treated as
the source, use the sourceColumnOverride parameter
sourceType: Object To specify the type of the import source (CSV or SQL), use
the sourceType parameter (default is Import_type.CSV)

debugOn()
Turns on logging of debug messages.

debugOff()
Turns off logging of debug messages.

getHeader()
This method returns all of the header values (the column names) from the decoder as an array of strings.

getMap(sourceColumn, destinationColumn, customLog)


This method creates a map between two columns in the decoder, mapping the values in the source column
with the corresponding values from the destination column. This method returns DecoderMap object.
Parameter Description
sourceColumn: String Name of the source column
destinationColumn: String Name of the destination column
customLog: LogPrintWriter The log object to use

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 149


WT&A API Specifications 18.3 Decoder API

validateSourceColumns(source, logErrors)
This method checks to ensure all of the fields specified in the source column of the decoder text actually
appear as columns in the source data.
Parameter Description
source: Scriptable/ResultSet Scriptable or ResultSet holding source data
logErrors: Boolean True: Will call log.error() and also throws an exception.
False: Will not call log.error(). Only throws an exception.

print()
This method pretty-prints the entire Decoder text to the script log, using log.info(). The output will appear
the same as the Decoder Text appears in the Policy Editor (after it is auto-formatted upon saving).

validateRequired(source, logErrors)
This method checks the source datato ensure that all fields with REQUIRED = Y are populated with a value.
Parameter Description
source: Scriptable/ResultSet Scriptable or ResultSet holding source data
logErrors: Boolean True: Will call log.error() and also throws an exception.
False: Will not call log.error(). Only throws an exception.

validateValues(source, logErrors)
This method checks the source data and ensures that all fields have one of the valid values (if a set of valid
values is defined for that column).
Parameter Description
source: Scriptable/ResultSet Scriptable or ResultSet holding source data
logErrors: Boolean True: Will call log.error() and also throws an exception.
False: Will not call log.error(). Only throws an exception.

validateFormats(source, logErrors)
This method checks the source data and ensures that all format specifications are valid.
Parameter Description
source: Scriptable/ResultSet Scriptable or ResultSet holding source data
logErrors: Boolean True: Will call log.error() and also throws an exception.
False: Will not call log.error(). Only throws an exception.

validateSource(source, logErrors)
This method validates the required fields, valid values and the format specifications for the source data. If
any of the required/valid values/format columns is not present in the Decoder Text, the method does not
perform that part of the validation.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 150


WT&A API Specifications 18.3 Decoder API

Parameter Description
source: Scriptable/ResultSet Scriptable or ResultSet holding source data
logErrors: Boolean True: Will call log.error() and also throws an exception.
False: Will not call log.error(). Only throws an exception.

setAutoTrimValues(bool)
Call this method to change the value of autoTrimValues.
Parameter Description
bool: Boolean sets autoTrimValues to the specified Boolean value (default is
false). This value can also be defined in the constructor.

setFieldsFromSource(destination, source, fieldMap, dateFormat, dateTimeFormat,


customLog)
This method is used to set all fields on the target object from the source ResultSet or Scriptable.
Parameter Description
destination: Scriptable/ DbRec Destination for the data which will have its value set
source: Scriptable/ ResultSet Scriptable or ResultSet holding source data
fieldMap: DecoderMapJava Maps the fields on the source object to the fields on the DbRec
dateFormat: String Optional field to specify date format in the case where format
column is not being used
dateTimeFormat: String Optional field to specify datetime format in the case where
format column is not being used
customLog: LogPrintWriter Optional parameter to specify a LogPrintWriter object other
than the default one that was passed to the constructor. This is
useful when we have multiple threads calling this method and
we want each thread to have their own LogPrintWriter.

setSourceColumn(sourceColumnOverride)
Call this method to change which column of the Decoder Text is being treated as the source (that is, to have
the decoder override the defined source column).
Situations where you would want to do this would be when importing from a staging table to the actual
table.
For example, if your source ResultSet is the result of querying the EMPLOYEE_STAGE table, and you want to
import this data into the EMPLOYEE table, you would have to set the source to EMPLOYEE_STAGE (that is,
decoder.setSourceColumn("EMPLOYEE_STAGE") ).
This value can also be defined in the constructor.
Parameter Description
sourceColumnOverride: String Name of the table

setSourceType(sourceType)
Call this method to change the value of sourceType.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 151


WT&A API Specifications 18.3 Decoder API

Parameter Description
sourceType: Import_source Import_source choice is used to define the type of source.
Allowable options are Import_source.CSV and
Import_source.SQL as Scriptable or String. Default value is
Import_source.CSV.

getFieldsInColumn(column)
Returns a list of all the fields that are defined in the decoder for the specified column.
Return type: Array of strings
Parameter Description
column: String Name of the column

Decoder Map
This is a private class and its constructor should not be called directly from a script. Call decoder.getMap() of
Decoder class to retrieve its object and corresponding methods. Following are the description of methods
defined in this class.

DecoderMap(decoderMapJava)
This constructor should not be called directly from a script. To retrieve a DecoderMap object, you should call
the decoder.getMap() method, which returns a DecoderMap.

Parameter Description
decoderMapJava: DecoderMapJava DecoderMapJava object

get(key)
This method assumes that each key value maps to only a single field. If the specified key maps to more than
one than one value, this method will throw an exception. If multiple fields are mapped to by a key, then
getOne or getAll should be called.

Pass in the key (source field name), and this will return the mapped value (destination field name) as string or
null if the key does not map to any value.

For example, if you have a source field, "EMP_ID", and this maps to "EMPLOYEE.EMPLOYEE", then if you have
a map from "SOURCE" to "EMPLOYEE", calling map.get("EMP_ID") would return "EMPLOYEE".

Parameter Description
key: String Source field name

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 152


WT&A API Specifications 18.3 Decoder API

getOne(key)
This method should be used in the case that a key value may map to multiple fields; however, only one of the
mapped values is needed (and it does not matter which of those values is returned). If the specified key maps
to more than one than one value, this method will return one, and only one, of the mapped values (there is
no guarantee as to which value will be returned). If all of the multiple fields mapped to a key are desired,
then getAll(key) should be called.

Pass in the key (source field name), and this will return the mapped value (destination field name) as string or
null if the key does not map to any value.

For example, if you have a source field, "EMP_ID", and this maps to "EMPLOYEE.EMPLOYEE" and
"EMPLOYEE.DISPLAY_EMPLOYEE", then if you have a map from "SOURCE" to "EMPLOYEE", calling
map.getOne("EMP_ID") would return either "EMPLOYEE" or "DISPLAY_EMPLOYEE".

Parameter Description
key: String Source field name

getAll(key)
This method should be used in the case that a key maps to multiple fields, and all of the mapped fields are
desired values as needed (and it does not matter which of those values is returned). If the specified key maps
to more than one than one value, this method will return one, and only one, of the mapped values (there is
no guarantee as to which value will be returned). If all of the multiple fields mapped to a key are desired,
then getAll(key) should be called.

Pass in the key (source field name), and this will return the mapped value (destination field name) as string
array or null if the key does not map to any value.

For example, If you have a source field, "EMP_ID", and this maps to "EMPLOYEE.EMPLOYEE" and
"EMPLOYEE.DISPLAY_EMPLOYEE", then if you have a map from "SOURCE" to "EMPLOYEE", calling
map.getAll("EMP_ID") would return ["EMPLOYEE", "DISPLAY_EMPLOYEE"].

Parameter Description
key: String Source field name

getKeys()
Returns all the keys for the map as an array of strings.

getValues()
Returns all of the values from the key-value pairs (as an array of strings) that make up the map. If the array
has keys which map to multiple values, the multiple values are listed individually, with nothing linking exactly
which of the values are values for the same key. If you need this information, you must call
getValuesAsArrays().

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 153


WT&A API Specifications 18.3 Decoder API

getValuesAsArrays()
Returns all of the values from the key-value pairs (as an array of arrays of strings: String [][]) that make up the
map. Each value is returned as an array.

For keys that map to a single value, the array will have length of 1.

For keys which map to multiple values, the multiple values are grouped together into an array.

The array returned by this method would be equivalent to calling getAll(key) on all the keys in the map, and
then making an array of those results.print().
This method prints the contents of DecoderMap to the script log.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 154


WT&A API Specifications 18.3 Email API

Email API
Overview and Capabilities
The Email API provides a mechanism for scripts to send email notifications during processing. This can be
used either as an end in itself (e.g. a script to send notifications to users that one of their employees has not
punched in) or as part of a larger process (e.g. informing users of errors that occurred while processing data).
Emails generated in this fashion can be sent to any number of users, using the To, CC, or BCC options, and can
include attachments if desired.
Additionally, the Email API supports generating emails that are processed through the EmpCenter Email
Aggregator. This allows for many similar email messages intended for the same user to be created and then
combined into a single email sent to that user, eliminating many duplicate messages that the user would
otherwise receive. Emails sent in this fashion cannot include attachments, however, since the Email
Aggregator does not support attachments.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• How EmpCenter’s Email Dispatcher and Aggregator function

Components
This API consists of the following component(s):
• The Distributed JavaScript Library EMAIL_API

Setup
No setup is necessary for the Email API. The distributed library is automatically available within WorkForce
Time and Attendance.

Use Cases
Sending an Email
The most common use for the Email API is to generate an email notification that will be sent out
immediately. Emails sent in this fashion will go directly to the Email Dispatcher, which will send them out to
the target recipients the next time it triggers.
The following example shows how to create and send an email from within a script:

Example 1: Sending an email


includeDistributedPolicy("EMAIL_API");

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email
recipients: Email.createRecipientList("johnDoe@email.com<John Doe>", "TO"),
// Define the subject line for the email

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 155


WT&A API Specifications 18.3 Email API

subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message<br>HTML content <u>will" +
" not</u> be evaluated",

// Specify whether the email should be sent as plain text or HTML


format: "PLAIN_TEXT",
// Indicate which name should appear for the sender
senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com"
};

// Queue the email with the Dispatcher, which will send it out when it next triggers
Email.createAndSendEmail(parameters);

The email generated in the above example will be sent as plain text. This is often useful for messages where
the content does not require any special formatting. When this encoding format is used, the message body
will appear exactly as specified within the script:

This is the actual content of the email message<br>HTML content


<u>will not</u> be evaluated

However, in some cases the ability to format the message content is required in order to ensure that the
message conveys the needed information in the most efficient fashion, or to embed hyperlinks in the
message content. The following example demonstrates how to send an email message encoded in HTML:

Example 2: Sending an HTML-formatted email


includeDistributedPolicy("EMAIL_API");

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email
recipients: Email.createRecipientList("johnDoe@email.com<John Doe>", "TO"),
// Define the subject line for the email
subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message<br>HTML content <u>will" +
"</u> be evaluated",

// Specify whether the email should be sent as plain text or HTML


format: "HTML",
// Indicate which name should appear for the sender
senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com"
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 156


WT&A API Specifications 18.3 Email API

// Queue the email with the Dispatcher, which will send it out when it next triggers
Email.createAndSendEmail(parameters);

Emails generated in this fashion will evaluate any HTML tags embedded in the body text, and the user will see
the corresponding formatted message:

This is the actual content of the email message


HTML content will be evaluated

Queueing an Email for the Aggregator


If many similar emails are going to be generated by a process, it may not make sense to send each of them
out individually. If the same recipient will be receiving more than one similar message, the Email Aggregator
can be used to merge all of those messages into a single email that the recipient would receive. This helps
prevent cluttering up their inbox and allows them to actually focus on the message, instead of being
overwhelmed by the volume of emails they are receiving.
The following example demonstrates how emails can be queued for the Aggregator. Typically, this would be
something done only when generating a large number of emails; if only a single email is being generated, the
Aggregator will have nothing to aggregate and it will effectively be the same as sending it to the Dispatcher
directly.

Example: Queueing an email for the Aggregator


includeDistributedPolicy("EMAIL_API");

// Specify the time when the aggregator should send the emails
var sendTime = WFSDateTime.now().addMinutes(10);

// Iterate over some data source defining the emails that should be generated
while (source.next() ) {

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email
recipients: Email.createRecipientList("johnDoe@email.com<John Doe>", "TO"),
// Define the subject line for the email
subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message",

// Specify whether the email should be sent as plain text or HTML


format: "HTML",
// Indicate which name should appear for the sender
senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com",

// Specify when the Aggregator should send the email


sendTime: sendTime
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 157


WT&A API Specifications 18.3 Email API

// Queue the email with the Aggregator


Email.createEmailAndQueueForAggregator(parameters);
}

Specifying Multiple Recipients for an Email


Not all emails are targeted to just a single user. Many times it is necessary to send the same email message to
a number of different users. The Email API supports specifying as many different email recipients for a single
email as desired, using either the To, CC, or BCC options.
The following examples demonstrate several different ways to add multiple users to a single email:

Example 1: Specifying a list of users at once


includeDistributedPolicy("EMAIL_API");

// Define a single string containing the recipients that should receive the email
// Recipients should be delimited by semi-colons, and can optionally have their
// name specified within angle brackets
var recipientString = "johnDoe@email.com<John Doe>;";
recipientString += "janeDoe@email.com<Jane Doe>;";
recipientString += "tomSmith@email.com";

// Convert the recipient string into a list of recipients


var recipientList = Email.createRecipientList(recipientString, "TO");

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email. All three users in the list will
// receive the email.
recipients: recipientList,

// Define the subject line for the email


subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message",

// Specify whether the email should be sent as plain text or HTML


format: “PLAIN_TEXT”,

// Indicate which name should appear for the sender


senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com"
};

// Queue the email with the Dispatcher, which will send it out when it next triggers
Email.createAndSendEmail(parameters);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 158


WT&A API Specifications 18.3 Email API

Note: When using the createRecipientList method, all of the recipients in the list will share the same send
option.

Example 2: Building a list of recipients one recipient at a time


includeDistributedPolicy("EMAIL_API");

// Define an array to hold the recipients


var recipients = [];

// Iterate over a source data set containing the recipients to add


while (source.next() ) {
// Build the recipient object off the source data
var recipient = new EmailRecipient(source.email_address, source.name,
source.send_option);

// Add the recipeint to the array of recipients


recipients.push(recipient);
}

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email. All users added to the set will
// receive the email.
recipients: recipients,

// Define the subject line for the email


subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message",

// Specify whether the email should be sent as plain text or HTML


format: "PLAIN_TEXT",
// Indicate which name should appear for the sender
senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com"
};

// Queue the email with the Dispatcher, which will send it out when it next triggers
Email.createAndSendEmail(parameters);

Adding Attachments to an Email


The Email API can be used to generate email messages containing attachments. Messages containing
attachments must be sent directly through the Dispatcher, as the Aggregator does not support email
messages containing attachments.
The following example demonstrates how to create and send an email message containing attachments:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 159


WT&A API Specifications 18.3 Email API

Example: Sending an email containing attachments


includeDistributedPolicy("EMAIL_API");

// Define a JavaScript object containing information about the attachments to be


// included. The properties on this object correspond to the file paths for the
// attachments, and the property values reflect the content type for those files
var attachments = {
"/attachments/images/attachment1.jpg": "image/jpeg",
"/attachments/files/attachment2.pdf": "application/pdf",
"/attachments/files/attachment3.doc": "application/msword"
};

// Define the parameters for the email that should be sent. This is just
// a JavaScript object with properties corresponding to the email settings
var parameters = {
// Indicate who should receive the email
recipients: Email.createRecipientList("johnDoe@email.com<John Doe>", "TO"),
// Define the subject line for the email
subject: "Email Notification from Script",

// Define the text that makes up the body of the email message
body: "This is the actual content of the email message<br>HTML content <u>will" +
"</u> be evaluated",

// Specify whether the email should be sent as plain text or HTML


format: "HTML",
// Indicate which name should appear for the sender
senderName: "Time and Attendance System",

// Indicate which email address the message should appear to originate from
// (This will be the "reply-to" address for the message as well)
senderEmailAddress: "from@example.com",

// Indicate what attachments should be included in the email


attachments: attachments
};

// Queue the email with the Dispatcher, which will send it out when it next triggers
Email.createAndSendEmail(parameters);

Note: All attachments must be located on the application server. It is not possible to send client-side
attachments through this email process.

Using the Email Object


The previous use cases all show how email messages can be sent when you know all of the information for
the email message at the time you want to build it. However, the Email API offers an alternative method of
constructing email messages if they need to be built up in pieces over the course of a script.
The following examples demonstrate the use of the Email class, which is an alternate method that can be
used to send emails:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 160


WT&A API Specifications 18.3 Email API

Example 1: Sending a custom email message through the Dispatcher


includeDistributedPolicy("EMAIL_API");

// Define the email object


var email = new Email();

// Define the recipient for the email. (This can be repeated as necessary to add
// additional recipients)
var recipient = new EmailRecipient("johnDoe.email.com", "John Doe",
"TO");email.addRecipient(recipient);

// Specify the subject for the email


email.setSubject("Email Notification from Script");
// Add additional text to the end of the existing subject
email.appendToSubject(" - Custom");

// Specify the message body for the email


email.setBody("The following employees are covered by this email:\r\n");
// Add additional text to the end of the existing message body
while (employees.next() ) {
email.appendToBody("Employee " + employees.employeeId + "\r\n");
}

// Specify the content type of the email


email.setEmailFormat("PLAIN_TEXT");
// Add any attachments that are desired. (This can be repeated as necessary to add
// additional attachments)
email.addAttachment("/attachments/images/attachment1.jpg", "image/jpeg");

// Specify the sender for the email


email.setSender("from@example.com", "Time and Attendance System");

// Queue the email to be sent by the Dispatcher


email.send();

Example 2: Sending a custom email message through the Aggregator


includeDistributedPolicy("EMAIL_API");

// Define the email object


var email = new Email();

// Define the recipient for the email. (This can be repeated as necessary to add
// additional recipients)
var recipient = new EmailRecipient("johnDoe@email.com", "John Doe",
"TO");email.addRecipient(recipient);

// Specify the subject for the email


email.setSubject("Email Notification from Script");
// Add additional text to the end of the existing subject
email.appendToSubject(" - Custom");

// Specify the message body for the email


email.setBody("The following employees are covered by this email:\r\n");
// Add additional text to the end of the existing message body

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 161


WT&A API Specifications 18.3 Email API

while (employees.next() ) {
email.appendToBody("Employee " + employees.employeeId + "\r\n");
}

// Specify the content type of the email


email.setEmailFormat("PLAIN_TEXT");
// Specify the sender for the email
email.setSender("from@example.com", "Time and Attendance System");

// Queue the email to be sent by the Aggregator. It will be sent at the indicated
// time after having been aggregated with any similar emails that were generated in
// the meantime
var sendTime = WFSDateTime.now().addMinutes(10);
email.queueForAggregator(sendTime);

Troubleshooting
The job log of the script using the Email API will contain information messages and, in the case of problems,
any error messages generated during processing. This job log should be reviewed if there are any problems
encountered while using the API.

Error Message Problem Solution


A send time must be specified Emails can’t be queued with the Ensure that all messages being
when queuing emails for the Aggregator without specifying a queued with the Aggregator
aggregator time at which they should be sent have a send time specified at the
to the recipients time they are queued.
An email address must be A recipient was specified that did Ensure that all recipients that
specified when creating a not include the email address they are defined include an email
recipient should receive the email at address.
An email cannot be created An attempt was made to queue an Ensure that all emails have at
without specifying at least one email with either the Aggregator or least one recipient specified
recipient the Dispatcher without having any before attempting to send them.
recipients specified.
An email must have at least An attempt was made to queue an Ensure that all Email objects
one recipient in order to be Email object with either the have at least one recipient
sent Aggregator or the Dispatcher specified before attempting to
without having any recipients send them.
specified.
Table 38: Email API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Email API makes use of:
1. Static methods, which can be called without needing to instantiate any other objects.
2. The Email class, which allows for a message to be built through several different calls and then sent
out to recipients.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 162


WT&A API Specifications 18.3 Email API

3. The EmailRecipient class, which defines a single recipient for an email message and how that
message should be sent to that recipient
See the contents of the EMAIL_API policy in the Distributed JavaScript Library category for full documentation
on these methods. The following is a summary of the available methods and common uses:

Static Methods
Email.createAndSendEmail(emailParams)
Creates a new email and queues it up to be sent by the Dispatcher. The parameters that can be specified for
this method are:
Parameter Name Description
recipients A single recipient or Java Collection of recipients
who should receive the email
The string that should appear as the subject line of
subject
the email
body The message content to be included in the email
format The content type (plain text or HTML) that should
be used for the message
senderName The name that should appear as the sender for the
email
senderEmailAddress The email address that should appear as the source
for the email
actCaseID The ACT case that the email is associated with
actDocumentId The ID of the ACT case document attached to the
email
attachments Map from file path for the attachment to the
corresponding content type for the attachment
Table 39: Parameters for the Email.createAndSendEmail method

Email.createEmailAndQueueForAggregator()
Creates a new email and queues it up to be processed by the Aggregator. The parameters that can be
specified for this method are:
Parameter Name Description
recipients A single recipient or Java Collection of recipients
who should receive the email
The string that should appear as the subject line of
subject
the email
Body The message content to be included in the email
format The content type (plain text or HTML) that should
be used for the message
senderName The name that should appear as the sender for the
email
senderEmailAddress The email address that should appear as the source
for the email
actCaseID The ACT case that the email is associated with

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 163


WT&A API Specifications 18.3 Email API

sendTime The time when the Aggregator should send the


email
Table 40: Parameters for the Email.createAndQueueForAggregator method

Email.createRecipientList(recipients, sendOption)
Converts a single string containing all of the recipients that should receive an email into a list of recipients,
each associated with the specified send option.
The string to be converted by this method is expected to be in the form:
"johnDoe@email.com<John Doe>;janeDoe@email.com<Jane Doe>"

getSystemMailName()
Returns the name used on emails sent by WorkForce Time and Attendance to identify their source, as
defined in the build properties.

getSystemMailAddress()
Returns the email address used on emails sent by WorkForce Time and Attendance to identify their source,
as defined in the build properties.

validateEmailAddress(emailAddress)
Returns true if the specified email address conforms to RFC822 standards for a valid email address, false if it
does not.

Email
Email(emailParams)
Creates a new email message, which can be programmatically built up as needed and then sent once it is
finished being built. The parameters that can be specified when instantiating this object are:
Parameter Name Description
recipients An array of EmailRecipients who should receive the
email
The string that should appear as the subject line of
Subject
the email
Body The message content to be included in the email
Format The content type (plain text or HTML) that should
be used for the message
senderName The name that should appear as the sender for the
email
senderEmailAddress The email address that should appear as the source
for the email
actCaseID The ACT case that the email is associated with
actDocumentId The ID of the ACT case document attached to the
email
attachments Map from file path for the attachment to the
corresponding content type for the attachment
Table 41: Parameters for the Email constructor

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 164


WT&A API Specifications 18.3 Email API

addRecipient(recipientParam, sendOption)
Adds a single new recipient list to the list of recipients for the email.

addRecipients(recipients)
Adds the specified array of recipients to the email. This array of recipients can be built using the
Email.createRecipientList static method._createRecipientList(recipients,_sen

getRecipients()
Returns the array of all recipients currently set to receive their email, along with the send option associated
with them.

getSubject()
Returns the current subject text that will appear in the email.

setSubject(text)
Sets the subject line of the email message to the specified text.

appendToSubject(text)
Adds the specified text to the end of the existing subject line for the email.

getBody()
Returns the current message body text for the email.

setBody(text)
Sets the message body for the email message to the specified text.

appendToBody(text)
Adds the specified text to the end of the existing email message body.

setEmailFormat(format)
Specifies the content type of the email message body (either plain text or HTML).

getEmailFormat()
Returns the current content type of the email message body (either plain text or HTML).

addAttachment(filePath, contentType)
Adds an additional attachment to the email, attaching the file located at the specified file path and
associating it with the indicated content type.

addAttachments(attachments)
Adds the specified attachments to the email. The argument here is a JS object, with properties
corresponding to the file paths for the attachments and values corresponding to the content types for those
files.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 165


WT&A API Specifications 18.3 Email API

attachActDocument(documentId)
Attaches an ACT document with the specified ID to the email. The ACT Case ID must have been specified on
the email before calling this method.

setSender(emailAddress, name)
Specifies the email address and name that should appear as the originator for the email.

getSender()
Returns the email address and name that are currently set as the originator for the email.

setActCaseId(caseId)
Specifies which ACT Case this email is associated with.

getActCaseId()
Returns the current ACT Case that this email is associated with.

send()
Queues the email up for the Dispatcher, which will send it out to the identified recipients.

queueForAggregator(sendTime)
Queues the email up for the Aggregator, which will send it out to the identified recipients at the indicated
send time. Similar messages generated before that send time that are targeted to the same user will all be
combined into a single email message.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 166


WT&A API Specifications 18.3 Employee Import Library

Employee Import Library


Overview and Capabilities
The Employee Import Library provides a way to import employees and their corresponding assignment
records into WT&A. It provides different methods to fetch, update, or initialize employee related objects and
their attributes. It also checks and validates the data state of the system. Other pieces of information can also
be fetched using methods defined in this API. This distributed library also provides a way to create the
decoder and policy profile maps. Multiple utility functions are available as well that facilitate the employee
import process.

Prerequisites
To use this API, you should know the following:
• Basic JavaScript coding
• Background knowledge of Employee Import process.

Components
The components of the Employee Import API are as follows:
• EMPLOYEE_IMPORT_UTIL Distributed JavaScript library
• Wrapper class of Decoder using DECODER_API Distributed JavaScript library
• FILE_MANAGER_API Distributed JavaScript library
• JOB_QUEUE_API Distributed JavaScript library

Setup
No setup is necessary for the Employee Import Library. The distributed library is automatically available in
WorkForce Time and Attendance.

Use Cases
Creating and Accessing the Manager Map
The following script shows how to determine if an employee is a manager by creating the manager mapping.
// Returns a map of distinct values of a specified field (MANAGER_ID) from specified table
(ASGNMT_STAGE) for active employees
var ACTIVE_STATUSES = ["A", "L", "T"]; // Status codes indicating an employee is active

// Returns list of managers that are active


managerMap = mapManagers(connection, "ASGNMT_STAGE", "MANAGER_ID", ACTIVE_STATUSES);
var employeeId = employee.DISPLAY_EMPLOYEE;
var isManager = managerMap.containsKey(employeeId);
if (isManager) {
log.info(employeeId + " is a Manager");
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 167


WT&A API Specifications 18.3 Employee Import Library

Creating and Accessing the Policy Profile Map


Example 1: Defines the Policy Profile mapping to use
includeDistributedPolicy("EMPLOYEE_IMPORT_LIBRARY");

// Defines the mapping used to determine policy profile


var ppMap = new PolicyProfileMapping();

// Defines the set of fields that will be included in the comparison


ppMap.setFields("ECLASS", "FLSA");

// Defines mapping against each policy profile


ppMap.addMapping("OSU_SALARY_EXEMPT", "['CA','CB']", "Y");
ppMap.addMapping("OSU_SALARY_NONEXEMPT", "['CA','CB']", "!Y");
ppMap.addMapping("OSU_HOURLY", "['CD','CE']", "*");
ppMap.addMapping("OSU_EXEMPT", "['UA','UB','UC','UD','UE','UF','UG','UH']", "Y");

Example 2: Evaluating the Policy Profile map


// Creates File Manager object
var source = new FileManager();
source.standardDateFormat = stdDateFormat;
source.setFile(filePath, fileName);
source.openFile({delimiter: delimiter,
hasHeaderRecord: true,
useUppercaseHeaders: true,
discardBOM: false,
charSet: encodingType});
if (!source.validateFields(fieldNames, true)) {
throw "File " + fileName + " is missing expected fields - unable to import data";
}

// Evaluates provided mapping with provided value


var mapping = "Y";
var mappingValue = source.getStringValue("FLSA");
var matchFound = ppMap.evaluateMatch(mapping, mappingValue);

if (mappingValue == "Y" && !matchFound) {


throw "Policy Profile Mapping evaluateMatch() method failed.";
}

// Returns an array of entries for the specified mapping


var mappingParams = ppMap.getMappingParms(mapping);
var mappingList = mappingParams.getMapping();

if (!mappingList.contains("Y")) {
throw "Policy Profile Mapping mappingParams.getMapping() method failed.";
}

Example 3: Accessing the Policy Profile name against the specified source data
// Sets the policy profile based on the specified record values.
assignment.policy_profile = ppMap.getProfileFromRecord(source);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 168


WT&A API Specifications 18.3 Employee Import Library

// Returns the policy profile based on the specified data.


var policyProfile = ppMap.getProfile(flsa, job_function, per_org, empl_type, comp_freq,
pay_group, empl_class);

// Returns the policy profile based on values in the result set


var policyProfileFromSource = ppMap.getProfileFromSource(source);

if (policyProfile != policyProfileFromSource) {
throw "Policy Profile Mapping test using getProfileFromSource() method failed. Policy
profile expected: " + policyProfile + ", found: " + policyProfileFromSource;
}

Example 4: Accessing information against the specified Policy Profile


// Gets the information about policy profile group, current period begin and end dates for the
specified policy profile name
var curPeriodBegin = getPolicyProfilePeriodStatus(assignment.policy_profile).CurPrdBeg;
var curPeriodEnd = getPolicyProfilePeriodStatus(assignment.policy_profile).CurPrdEnd;
var policyProfileGroup = getPolicyProfilePeriodStatus(assignment.policy_profile).PPG;

log.info("Policy profile " + assignment.policy_profile + " lies in policy profile group " +
policyProfileGroup + " with current period begin date " + curPeriodBegin + " and current
period end date " + curPeriodEnd);

Example 5: Accessing Policy Profile maps from the database


// Returns lookup table of policy profile groups and periods
policyProfileMap = mapPolicyProfiles(connection);

// Custom validation based on assignment policy profile mapping


validation.error(!policyProfileMap.containsKey(assignment.policy_profile),
"Specified policy profile " + assignment.policy_profile + " does not exist or is not
initialized");

// Identifies change in policy profile group


if (employee.exists && assignment.exists) {
var oldAssignment = getOldAssignment(WFSDate.today());
if (oldAssignment != null && oldAssignment.policy_profile != assignment.policy_profile) {
var oldPpg = policyProfileMap.get(oldAssignment.policy_profile).PPG;
var newPpg = policyProfileMap.get(assignment.policy_profile).PPG;
if (oldPpg != newPpg) {
/* Split assignment occurs due to change in policy profile group */
}
}
}

Getting the Employee/Assignment Record


The following example provides a way to access the employee/assignment record as of a date.
var asOfDate = WFSDate.today();

// Gets the employee record as of a date


var oldEmp = getOldEmployeeAsOf(asOfDate);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 169


WT&A API Specifications 18.3 Employee Import Library

if (oldEmp != null) {
log.info("HR status of employee last record " + oldEmp.HR_STATUS + " with effective date "
+ oldEmp.EFF_DT + " and and effective date " + oldEmp.END_EFF_DT);
}
else {
log.error("Employee not found as of: " + asOfDate);
}

// Gets the assignment record as of a date


var oldAsgnmt = getOldAssignment(asOfDate);
var isOldActive = !(oldAsgnmt.isTerminated || oldAsgnmt.status_code1 == "T" ||
oldAsgnmt.soft_terminated);

The following example provides a way to access the last employee/assignment record.
// Gets the last employee record
var oldEmployee = getOldEmployee();
if (oldEmployee.TERMINATION_DATE != null) {
var oldTermDate = WFSDate.valueOf(oldEmployee.TERMINATION_DATE, "yyyy-MM-dd");
log.info("Termination date of employee last record " + oldTermDate);
}

// Gets last assignment record to check if assignment is active


var oldAsgnmt = getOldAssignment();
var isOldActive = !(oldAsgnmt.isTerminated || oldAsgnmt.status_code1 == "T" ||
oldAsgnmt.soft_terminated);

Creating Assignment Groups


The following example creates assignment groups based on the specified role of the current employee
record.
var right = new GeneralRight();

if (source.OTHER_STRING2 == "E" && !positiveExcessBank && source.OTHER_STRING1 != "OSB" &&


source.OTHER_STRING1 != "OSW" && source.OTHER_STRING1 != "HSS") {
right.right_grp = "MANAGER_GENERAL";
createAssignmentGroup(app_user.first_name + " " + app_user.last_name + " Employees",
"MANAGER_GROUP", "GROUP", "ASGNMT$OTHER_STRING", 10, "EQUALS", source.DISPLAY_EMPLOYEE,
"ASGNMT$OTHER_STRING", 10, "EQUALS", source.DISPLAY_EMPLOYEE);
}
else if (source.OTHER_STRING2 == "N" && !positiveExcessBank && source.OTHER_STRING1 != "OSB"
&& source.OTHER_STRING1 != "OSW" && source.OTHER_STRING1 != "HSS") {
right.right_grp = "MANAGER_WEBCLOCK_GENERAL";
createAssignmentGroup(app_user.first_name + " " + app_user.last_name + " Employees",
"MANAGER_GROUP", "GROUP", "ASGNMT$OTHER_STRING", 10, "EQUALS", source.DISPLAY_EMPLOYEE,
"ASGNMT$OTHER_STRING", 10, "EQUALS", source.DISPLAY_EMPLOYEE);
}
else if (source.OTHER_STRING2 == "N" && positiveExcessBank && (source.OTHER_STRING1 == "OSB"
|| source.OTHER_STRING1 == "OSW" || source.OTHER_STRING1 == "HSS")) {
right.right_grp = "MANAGER_WEBCLOCK_RATE_EXCESS_BANKS_GENERAL";
createAssignmentGroup(app_user.first_name + " " + app_user.last_name + " Employees",
"MANAGER_RATE_EXCESS_BANKS_GROUP", "GROUP", "ASGNMT$OTHER_STRING", 10, "EQUALS",
source.DISPLAY_EMPLOYEE, "ASGNMT$OTHER_STRING", 10, "EQUALS", source.DISPLAY_EMPLOYEE);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 170


WT&A API Specifications 18.3 Employee Import Library

else {
log.error("Unable to Determine Role");
}

Setting Status Codes, Leave Dates, and Split Date


The following API methods let you set status codes and leave dates for the employee/assignment record
being imported and detects split assignment if there is a change in the policy profile group.
// Initializes and sets status code, status date and effective dates for an employee record
if (PERFORM_EMPLOYEE_TERMINATIONS) {
setAllStatusAndEffectiveDt(employee, employee.HR_STATUS_CODE, ACTIVE_STATUSES,
LEAVE_STATUSES, GO_LIVE_DATE, employee.eff_dt, employee.ORIGINAL_HIRE_DATE,
employee.TERMINATION_DATE, employee.LATEST_HIRE_DATE, TERM_STATUSES);
}
else
setEmployeeOrAsgnmtLeaveStatus(employee, LEAVE_STATUSES, employee.HR_STATUS_CODE);

//Initializes all status codes/dates and effective dates for an assignment record
setAllStatusAndEffectiveDt(assignment, assignment.hr_status, ACTIVE_STATUSES, LEAVE_STATUSES,
GO_LIVE_DATE, assignment.eff_dt, assignment.emp_date1, assignment.emp_date3,
assignment.emp_date4, TERM_STATUSES);

// assignment record being imported has reflected a change in policy profile group from the
existing policy profile.
isSplitAssignment();

Creating the Decoder Map


The following example creates a decoder map that contains all the decoder information that needs to be
passed throughout an employee import.
// Creates a Decoder object
var decoderData = new DecoderData(DECODER, "SOURCE", STD_DATE_FMT,
Packages.com.workforcesoftware.Gen.Choice.Import_source.CSV);

// Defines a new Decoder Map from specified source field to specified destination field
decoderData.addDecoderMap("employeeMap", "EMPLOYEE_STAGE");
decoderData.addDecoderMap("asgnmtMap", "ASGNMT_STAGE");

// Defines a new Decoder Map from specified destination field to specified source field
decoderData.addReverseMap("employeeSourceMap", "EMPLOYEE_STAGE");

// Validates source data and its columns


var resultSet = new CSVResultSet(fullFileName, DELIMITER, CHAR_SET);
decoderData.validateSourceData(resultSet);

// Returns the DecoderMap that has been defined with the specified reference name
var reverseMap = decoderData.getMap("employeeSourceMap");
if (!reverseMap) {
throw "No mapping has been defined from the data source to the EMPLOYEE_STAGE table";
}

// Applies specified mapping to decode values from source record to employee/assignment record
var employee = new DbRec("EMPLOYEE_STAGE");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 171


WT&A API Specifications 18.3 Employee Import Library

var asgnmt = new DbRec("ASGNMT_STAGE");

// Decodes employee fields


decoderData.decodeData(employee, source, "employeeMap");

// Decodes assignment fields


decoderData.decodeData(asgnmt, source, "asgnmtMap");

Writing and Clearing Staging Table Records


The following API methods provide a way to write and delete staging table records.
// Creates DbRec object for employee/asgnmt stage tables
var employee = new DbRec("EMPLOYEE_STAGE");
var asgnmt = new DbRec("ASGNMT_STAGE");

// Adds DbRec objects of employee/asgnmt to DbRecList


log.info("Adding records to dbRecList");
addDbRecToList(employee);
addDbRecToList(asgnmt);

// Writes the DbRecList to employee and asgnmt stage tables


writeStageRecList();

// Removes all records in the employee_stage table that match the specified condition
var empMatchCondition = new MatchCondition('EMPLOYEE_STAGE', 'DISPLAY_EMPLOYEE',
MatchOperator.EQUALS, source.employeeId);
clearEmployeeStageRecords(empMatchCondition);

// Removes all records in the asgnmt_stage table that match the specified condition
var asgnmtMatchCondition = new MatchCondition('ASGNMT_STAGE', 'LD10', MatchOperator.EQUALS,
source.employeeId);
clearAsgnmtStageRecords(asgnmtMatchCondition);

// Removes all records in the employee/assignment stage tables


clearAllEmployeeStageRecords();
clearAllAsgnmtStageRecords();

Appending Split Assignment in Description


The following script appends the split date to the description of the old half of a split assignment to ensure
that the description doesn't overlap with the new half's description to preserve the uniqueness of assignment
descriptions. It is used in post-policy profile change script.
includeDistributedPolicy("EMPLOYEE_IMPORT_LIBRARY");

// Appends assignment master description for split assignment


log.info("Policy Profile change script");
appendSplitAsgnmtMasterDescription();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 172


WT&A API Specifications 18.3 Employee Import Library

Utility Functions
The following script extends the above examples and provides a way of using different utility methods.
// Creates a DB connection object
var connection = new Connection();

// Creates and returns a multi-map between specified key (login_id) and its corresponding
values (bo_user_id)
boUserIdMap = buildMapFromDBFields(connection, "login_id", "bo_user_id", "app_user");
// Checks if app_user.login_id exists in boUserIdMap
if (boUserIdMap.containsKey(app_user.login_id)) {
app_user.bo_user_id = boUserIdMap.get(app_user.login_id)[0];
}

// Creates a job queue object and initializes jobs for specified employee/assignment Import
Control policies
var jobQueue = createAndInitJobQueueForImport(connection, "EMPLOYEE_IMPORT_POLICY",
"ASGNMT_IMPORT_POLICY");
jobQueue.executeJobs();

// Gives randomly generated password


app_user.password = generatepass();

// Gives time zone based on the provided state


app_user.time_zone = getTimeZoneForState(source.STATE);

// Gets Maximum Job ID


var maxJobId = getMaxID(connection);
log.info("Current Job Id is " + maxJobId);

// doNotImport() prevents current employee record to be imported in the system


var isActive = inArray(ACTIVE_STATUSES, employee.HR_STATUS_CODE);
if (isActive) {
log.info("New hire employee " + employee. DISPLAY_EMPLOYEE);
}
else {
log.error("Terminated employee not in system");
doNotImport();
}

Troubleshooting
The job log of the script using the Employee Import Library contains error messages generated during
processing. Review this job log if problems are encountered while using this API.
The following table lists some common error messages, their causes, and possible solutions.
Error Message Cause Solution
Policy profile is not defined or has Specified policy profile does not Provide valid policy profile in
not been initialized. exist in policy profile map. getPolicyProfilePeriodStatus
method.
No active status codes specified. Array of ACTIVE_STATUSES is Must populate status code in
empty. ACTIVE_STATUSES array.
Assignment with asgnmt.eff_dt is earlier than Provide appropriate dates.
computed_match_id not imported. split date of last asgnmt record.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 173


WT&A API Specifications 18.3 Employee Import Library

Error Message Cause Solution


Can't import changes before
assignment split.
Error getting old assignment. Exception while getting old
assignment record.
Invalid number of arguments An error occurs if no filter Provide valid number of
supplied to criteria is specified, if too many arguments and filter criteria.
CreateAssignmentGroup function. filter criteria are specified, or if
the arguments for the filter
criteria are not specified in sets
of four values.
Effective date is earlier than The Provide appropriate dates.
existing effective date. allow_out_of_order_records
flag is set to false and the
effective date is earlier than
existing effective date.
Future termination effective on. Prevents future termination if Provide appropriate dates.
termination date is greater
than today.
Invalid status that does not match Current hr_status code is Provide valid hr_status code.
with any of the active or invalid.
terminated statuses.
Terminated employee not already Trying to terminate an Provide valid employee ID.
in system. employee that does not exist in
the system.
Record.exists returned true, but no If last effective dated asgnmt
old assignment was able to be record is null.
found. Please check match field
values for accuracy and
uniqueness.
Terminated assignment not already Trying to terminate an Provide valid employee ID.
in system. assignment that does not exist
in the system.
Unable to define profile mapping: If expected number of Provide valid number of
at least two arguments needed. arguments are not provided to arguments.
addMapping function.
setFields must be called prior to If fields are not set for policy Call setFields method before
addMapping. profile mapping prior to calling adding maps.
addMapping method.
Number of mappings do not match If number of policy profile Provide valid number of
number of fields. mapping arguments are not arguments.
same for setFields and
addMapping.
Number inputted policy profile If provided number of Provide valid number of
mapping parameters must be the arguments in getProfile method arguments.
same as the number of field labels are invalid.
that exist in the mapping itself.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 174


WT&A API Specifications 18.3 Employee Import Library

Error Message Cause Solution


Input record’s object type is not If record type provided in Provide appropriate record.
supported. getProfileFromRecord is invalid.

API Reference
Knowledge of JavaScript programming is necessary to make best use of this section.

Import Options
importOptions is an object having multiple flags for controlling employee import behavior. The following
table lists standard import options along with their description and valid values.
Parameter Description
importOptions.allow_out_of_order_records true = records with effective dates earlier than an
Controls whether out-of-order effective-dated records existing date for the employee/assignment can
are allowed. When records are imported out of order, be loaded.
all records with effective dates after the effective date false = records with effective dates earlier than
of the record being imported will be deleted. an existing date for the employee/assignment
will error out.
importOptions.allow_import_closed_periods true = assignment activations in closed periods
Controls whether new assignments can be created are allowed.
with active dates in closed periods. false = assignment activations in closed periods
will have their earliest active date moved to the
current period begin date.
importOptions.allow_import_term_if_previous_term true = new termination records will be allowed to
Controls whether a terminated assignment record can import successfully.
be imported for an assignment that is already false = new termination records will not be
terminated. imported.
importOptions.check_split_assignment true = import will check for split assignments.
Controls whether the import will attempt to create false = import will not check for split assignments.
split assignments if needed for a policy profile change.
importOptions.override_eff_dt true = import will use the termination/rehire date
Controls whether the import will override the as the effective date for assignments changing
specified effective date for terminations and/or status.
rehires. false = import will always use the provided
effective date as the date of the change.
importOptions.update_staging_table_status true = import will update the processed state.
Controls whether the import will update the false = import will not update the processed
processed state in the staging table when state.
updateStagingTableStatus is called.

mapPolicyProfiles(sourceConnection)
Loads lookup table of periods and policy profile groups and returns mapping from policy profile name to
attributes related to that policy profile:
• PPG – The policy profile group ID containing the policy profile

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 175


WT&A API Specifications 18.3 Employee Import Library

• CurPrdBeg – The current period begin date for the policy profile
• CurPrdEnd – The current period end date for the policy profile
Parameter Description
sourceConnection: Connection Local database connection to use for querying
the data. If no connection is specified a new
connection to the local database will be
established
(optional) - if passed null or empty the method
will create the connection to the local database
and then in the end of the method the
connection will be closed).

getPolicyProfilePeriodStatus(policyProfile)
Determines the information about the current period for the specified policy profile. Returns object with
following attributes:
• PPG – The policy profile group ID containing the policy profile
• CurPrdBeg – The current period begin date for the policy profile
• CurPrdEnd – The current period end date for the policy profile
Parameter Description
policyProfile: String Name of policy profile to be evaluated

mapManagers(sourceConnection, table, field, activeStatuses)


Creates a table listing all known managers by querying either the employee or asgnmt tables (or their stage
equivalents) and returns a lookup table map of distinct values of a specified field from records that are active.
Parameter Description
sourceConnection: Connection Local database connection to use for querying
the data
(optional - if passed null or empty the method
will create the connection to the local database
and then in the end of the method the
connection will be closed).
table: String Name of the table to be queried.
field: String Field name within the table containing the
manager IDs.
activeStatuses: String[ ] Array of valid hr_status values that are
considered active. If undefined, default array with
values [‘A’,’L’,’P’] would be created.

getOldEmployee(asOfDate)
Finds and returns the last employee record.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 176


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
asOfDate: WDate If provided, it will select the record that is
effective on this date.

getOldEmployeeAsOf(asOfDate)
Finds and returns the last employee record.
Parameter Description
asOfDate: WDate Selects the record that is effective on this date.

getOldAssignment(asOfDate)
Finds and returns the assignment as of date record.

Parameter Description
asOfDate: WDate If provided, it will select the record that is
effective on this date.

isSplitAssignment()
Checks if the assignment record being imported reflects a change in the policy profile group from the existing
policy profile for that assignment. If so, changes the effective date as needed and sets up the policy
configuration and split date fields to reflect a split assignment. Returns true if the assignment was split, false
if it was not.

Note: This function must be called after the status has been set on the assignment record.

doNotImport()
Sets all the import flags to false, preventing any import operation.

createAssignmentGroup(description, role, roleType)


Creates the specified assignment group if it doesn't already exist (using the matching defined in the Employee
Import Control policy linked to this import), and then returns the group right object that is delegated to the
user being processed using the specified role. Returns group right object containing information of provided
arguments.

generatepass(length)
Random Password Generator (used for LDAP configurations).
Returns randomly generated password using ASCII characters in the decimal range 33 (!) to 122 (z). This
includes all upper and lower case alpha-numeric characters as well as printable characters such as
~!@#$%^&*()_+{}|:"';?><,.'\ etc.
Parameter Description
Length: Integer (Optional) - Number of characters in the
generated password. Default is 8. If length is less

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 177


WT&A API Specifications 18.3 Employee Import Library

than 0 or greater than 20 then an empty string is


returned.

getMaxID(workforceConn)
Gets the job id of the last job ran (should be the current job).
Parameter Description
workforceConn: Connection Local database connection to use for querying
the data
(optional) - if passed null or empty the method
will create the connection to the local database
and then in the end of the method the
connection will be closed.

getTimeZoneForState(state)
Returns best guess as to time zone based on specified state.
Parameter Description
state: String Name of state to determine its time zone.

initializeEmployeeStatus(record, currentStatus, validActiveStatuses, sourceEffDate,


sourceLastActiveDate, validTerminatedStatuses)
Evaluates the provided data and determines if the employee record should be terminated. Requires that the
employee match field is computed_match_id and that that field has been initialized on the record.
Parameter Description
record: DbRecEmployeeScriptable The employee record to be evaluated
currentStatus: String The employee-level status for the record being
evaluated
validActiveStatuses: String[ ] Array of status codes that are considered to be
active
sourceEffDate: WDate The effective date that should be used (overrides
standard calculated value)
sourceLastActiveDate: WDate The last-active date that should be used
(overrides standard calculated value)
validTerminatedStatuses: String[ ] Array of status codes that are considered to be
terminated

setEmployeeOrAsgnmtLeaveStatus(record, leaveStatuses, currentStatus)


Sets status_code2 and status_date2 if the employee or assignment has a status that is included in the
specified array of leave codes.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 178


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
record: DbRecScriptable Either an employee or assignment record
leaveStatuses: String[ ] Array of valid string values that correspond to a leave
status
currentStatus: String Current status of the record. Defaults to the value of
the HR_STATUS field.

setAllStatusAndEffectiveDt(record, currentStatus, validActiveStatuses, leaveStatuses,


goLiveDate, sourceEffDate, sourceOriginalHireDate, sourceLastActiveDate,
sourceLatestHireDate, validTerminatedStatuses)
Initializes all status code and date and effective dates for an employee or assignment record. Requires that
the record is either an assignment or employee and that hr_status and emp_dates are initialized.
Parameter Description
record: DbRecScriptable Either an employee or assignment record
currentStatus: String String value corresponding to the active status found
from the source
validActiveStatuses: String[ ] Array of valid string values that correspond to active
status
leaveStatuses: String[ ] Array of valid string values that correspond to leave
status
goLiveDate: WDate Date for which the client went live
sourceEffDate: WDate Effective date from the source data for the record
being processed
sourceOriginalHireDate: WDate Original hire date from the source data for the record
being processed
sourceLastActiveDate: WDate Last active date from the source data for the record
being processed
sourceLatestHireDate: WDate Latest hire date from the source data for the record
being processed
validTerminatedStatuses: String[ ] Array of status codes that are considered to be
terminated

initializeAsgnmtStatus(record, currentStatus, validActiveStatuses, goLiveDate, sourceEffDate,


sourceOriginalHireDate, sourceLastActiveDate, sourceLatestHireDate,
validTerminatedStatuses)
Evaluates the provided data to determine the correct effective date and status for the assignment record.
Requires that the assignment match field is computed_match_id and that that field has been initialized on
the record. Also requires that the policy profile has been set on the record.
Parameter Description
record: DbRecAsgnmtScriptable The assignment record to be evaluated.
currentStatus: String The assignment-level status for the record being
evaluated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 179


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
validActiveStatuses: String[ ] Array of status codes that are considered to be
active.
goLiveDate: WDate The earliest date the assignment should be able
to be active on.
sourceEffDate: WDate The effective date that should be used (overrides
standard calculated value).
sourceOriginalHireDate: WDate The original hire date for the assignment.
sourceLastActiveDate: WDate The last-active date for the assignment.
sourceLatestHireDate: WDate The most recent hire date for the assignment.
validTerminatedStatuses: String[ ] Array of status codes that are considered to be
terminated.

PolicyProfileMapping()
The PolicyProfileMapping object provides the means to store mappings for policy profiles and to determine
which policy profile is applicable based on a specified set of values.

setFields()
Sets the names of the fields being mapped for logging purposes. Field names to set should be passed as an
argument, as shown below:

ppm.setFields("Field name 1", "Field name 2", "Field name 3"...) ;

addMapping(profile, matchValue1, matchValue2, matchValue3 …. )


Adds a policy profile mapping definition.
The first argument is the profile, the rest are the necessary criteria.
Allows for wild card values (*) for fields, negations of values (!), a check if a value is contained within a string
with IN(...). Arrays of any of these can be specified using [ ], and a mapping of values not in an array can be
specified with ![ ].

getProfile()
Returns the policy profile to use based on the specified data, null if no corresponding profile found.
You must pass in the same number of arguments as there are field labels for the mapping. Field data should
be passed as an argument:

ppm.getProfile(value 1, value 2, value 3...) ;

getProfileFromRecord(record)
Returns the policy profile based on the values in the record, null if no corresponding profile found. Fields
array is used to determine values to pull, so needs to be setup before this call, using the actual field names
present in the source data.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 180


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
record: Object Record containing field data. Allowable objects
are DbRec, FileManagerJava and ResultSet.

getProfileFromSource(source)
Returns the policy profile based on the values in the result set, null if no corresponding profile found. Fields
array is used to determine values to pull, so needs to be setup before this call, using the actual field names
present in the source data.
Parameter Description
Source: FileManagerJava Result set containing field data

evaluateMatch(mapping, value)
Evaluates provided mapping with provided field value to determine whether or not said value matches said
mapping. Returns true if value meets mapping criteria, false otherwise.
Parameter Description
Mapping: String Mapping value or wildcard.
Mappings can be a straight value, a wild card (*),
or use IN(string) to indicate that the value needs
to be contained within the string.
Value: String Field value for comparison.

getMappingParms(mapping)
Returns an array of entries for the specified mapping. Used internally to allow arrays to be specified and
processed correctly within the mapping.
Parameter Description
mapping: String Single mapping or multiple mappings of the form
"['val1','val2',...]" or "!['val1','val2',...]"

buildMapFromDBFields(connection, keyField, valueField, table)


Builds a multi-map structure (using the LookupTable) based on inputted key/values in the specified table.
Returns a multi-map of strings to string arrays.
Parameter Description
workforceConn: connection Local database connection to use for querying
the data

(optional) - if passed null or empty the method


will create the connection to the local database
and then in the end of the method the
connection will be closed

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 181


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
keyField: String The field in the table that houses the keys
valueField: String The field in the table that houses the values
table: String The table used to look up the keyfield and
valuefield

createAndInitJobQueueForImport(workforceConn, employeeImportId, asgnmtImportId)


Creates a job queue object and initializes jobs for Import Control policies. Pass in the policy IDs of the SQL
Employee Import Control policies corresponding to the employee and asgnmt imports. This should be done
from the scheduled script that loads the staging table with import data.
Returns a jobQueue object.
Parameter Description
workforceConn: connection Local database connection to use for querying
the data

(optional) - can be passed null or empty as the


method does not use it
employeeImportId: String The policy ID of the employee import policy to
run
asgnmtImportId: String The policy ID of the asgnmt import policy to run

clearEmployeeStageRecords(matchCondition)
Removes all records in employee_ stage table that match the specified condition.
Parameter Description
matchCondition: MatchConditionJava Condition to delete the records from
employee_stage table

clearAsgnmtStageRecords(matchCondition)
Removes all records in asgnmt_stage tables that match the specified condition.
Parameter Description
matchCondition: MatchConditionJava Condition to delete the records from
asgnmt_stage table

clearAllEmployeeStageRecords()
Removes all records in employee_ stage table.

clearAllAsgnmtStageRecords()
Removes all records in asgnmt_stage table.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 182


WT&A API Specifications 18.3 Employee Import Library

appendSplitAsgnmtMasterDescription()
Appends the split date to the description of the old half of a split assignment to ensure that the description
doesn't overlap with the new half's description, to preserve the uniqueness of assignment descriptions of
assignment_master table.
To be used in the post-policy profile change script of asgnmt import policy.

DecoderData(decoderPolicyId, sourceField, stdDateFormat, sourceType)


Wrapper class for containing all of the decoder information that needs to be passed throughout an employee
import.
Parameter Description
decoderPolicyId: String Name of the decoder policy to use for building
data maps
sourceField: String Field containing the source data for decoder
maps
stdDateFormat: String Standard format to use for parsing dates without
formats specified in the decoder
sourceType: Object The Import_source choice, choice constant, or
choice ID of the data source type (defaults to
CSV)

addDecoderMap (name, destField)


Defines a new DecoderMap from the source field defined in the constructor to the specified destination field.
Parameter Description
name: String Name reference name for this map, used to
retrieve the map in later calls
destField: String Destination field for the mapping

addReverseMap (name, destField)


Defines a new DecoderMap from the specified destination field to the source field defined in the constructor.
Parameter Description
name: String Reference name for this map, used to retrieve
the map in later calls
destField: String Destination field for the mapping

getMap(name)
Returns the DecoderMap that has been defined with the specified reference name. Requires that either
addDecoderMap or addReverseMap have been called previously in order to define the map that should be
retrieved.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 183


WT&A API Specifications 18.3 Employee Import Library

Parameter Description
name: String Previously-defined reference name for the map
to be looked up

decodeData (destRecord, sourceRecord, name)


Applies the specified mapping to decode values from the indicated source record to the target destination
record. If the indicated mapping is not defined, nothing will happen. Requires that either addDecoderMap or
addReverseMap have been called previously in order to define the mapping that should be applied.
Parameter Description
destRecord: DbRec Destination object for the decoded mappings
sourceRecord: ResultSet Source data to use for the mappings
name: String Name of the previously-defined mapping that
should be used for decoding the mappings

validateSourceData (sourceData)
Checks that the current record in the source data meets the necessary conditions (required fields populated,
data matches valid values, source data formats) as defined in the decoder.
Parameter Description
sourceData: ResultSet Source data result set cursor pointing to the
record to be evaluated

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 184


WT&A API Specifications 18.3 Export Stage API

Export Stage API


Overview and Capabilities
The Export Stage API provides a mechanism for clearing, fetching, and writing data to the export_stage
table. It is expected to be used mostly as part of a Generic export.
As part of its clearing, the Export Stage API allows you to clear all/processed records, whereas, you can also
clear the records based on criteria. The criteria used to clear the data can be a simple standalone condition:
(“(export_id = '" + EXPORT_ID_VALUE + "')”)
or it can be combined to form a much more complicated condition. This gives the script the flexibility to
define whichever conditions are necessary to identify the desired data to delete.
The Generic Export API also provides methods to fetch all/unprocessed records from the table. And finally,
you can also write the data to the table using the API.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• There are no Export Stage API components.

Setup
No setup is necessary for the Export Stage API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Clearing the data from the staging table
The Export Stage API allows to clear the data from the table.

Example 1: Clear all records from staging table


Following are the other API methods used in this example:

Method Name Description


commit() Commit the current state of the database transaction
rollback() Roll back the state of the database transaction to the last
commit
close() Closes the connection

includeDistributedPolicy(“EXPORT_STAGE_API”);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 185


WT&A API Specifications 18.3 Export Stage API

try{
//Create an Instance of API
Var exportStageAPI = new ExportStageApi();

//Clear out staging table


exportStageAPI.clearstaging();

exportStageAPI.commit();
}
Catch(e) {
exportStageAPI.rollback();
log.error(e);
}
Finally{
exportStageAPI.close();
}

Example 2: Clear processed records from staging table


includeDistributedPolicy(“EXPORT_STAGE_API”);

try{
//Create an Instance of API
Var exportStageAPI = new ExportStageApi();

//Clear out staging table


exportStageAPI.clearProcessed();

exportStageAPI.commit();
}
Finally{
exportStageAPI.close();
}

Example 3: Clear records from staging table based on the provided criteria
includeDistributedPolicy(“EXPORT_STAGE_API”);

//Create an Instance of API


Var exportStageAPI = new ExportStageApi();

Var EXPORT_ID_VALUE = exportSpecificationPolicyId.toString();

//criteria
Var clearCriteria = {};
clearCriteria.whereClause = (“(export_id = ‘” + EXPORT_ID_VALUE + “’)”);

try{
//Clear out staging table
exportStageAPI.clearByCriteria(clearCriteria);
}
Finally{
exportStageAPI.close();
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 186


WT&A API Specifications 18.3 Export Stage API

Fetching the records from staging table


This API lets you fetch the record from the stage table provided with criteria(optional).

Example 1: Get Records from staging table with criteria(optional)


includeDistributedPolicy(“EXPORT_STAGE_API”);

//Create an Instance of API


Var exportStageAPI = new ExportStageApi();

//criteria
Var criteria = {
whereClause: “EXPORT_ID = ‘SEMP_HOURS_EXPORT_TO_ARCOS’ “,
orderByClause: “employee, calc_string2”
};

//fetching the records


Var records = exportStageAPI.getRecords(criteria);

Example 2: Get Unprocessed Records from staging table with criteria(optional)


Following are the other API methods used in this example:
Method Name Description
writeList(list) Write a DBRecList to the database within the current
database transaction

includeDistributedPolicy(“EXPORT_STAGE_API”);

//Create an Instance of API


Var exportStageAPI = new ExportStageApi();

//criteria
Var criteria = {};
Criteria.orderByClause = “employee”;

Try{
//fetch the unprocessed records
Var records = exportStageAPI.getUnprocessedRecords(criteria);

Var unprocessedMaxDate = WDate.today().addDays(3);

For (var it = records.listIterator(); it.hasNext();) {


Record = it.next();
Var system_timestamp = record.getSystem_timestamp();
If (system_timestamp < unprocessedMaxDate) {
Record.setProcessed(true);
}
}
exportStageAPI.writeList(records);
exportStageAPI.commit();
}
Finally{
exportStageAPI.close();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 187


WT&A API Specifications 18.3 Export Stage API

Example 3: Get Aggregation Records from staging table with criteria(optional)


includeDistributedPolicy(“EXPORT_STAGE_API”);

//Create an Instance of API


Var exportStageAPI = new ExportStageApi();

//criteria
Var criteria = {};
Criteria.orderByClause = “employee”;

Var sumFields = ['AMOUNT'];


Var groupByFields = ['HOURS'];

Var aggregationRecords = exportStageAPI.getAggregationRecords(criteria, sumFields,


groupByFields);

Troubleshooting
The job log of the script using the Export Stage API will contain information messages. In the case of
problems, any error messages generated during processing are due to a connection or database issue;
therefore the exception thrown contains details of the error.

API Reference
ExportStageApi
The ExportStageApi has the following methods available:

clearStaging()
Clears all records from the staging table, i.e. export_stage.

ClearProcessed()
Clear processed records from the staging table, i.e. export_stage.

clearByCriteria(criteria)
Clear records from the staging table based on the provided criteria(optional). However, the criteria
object should have the following property:
whereClause: a string that will be used as the SQL where clause of a query that clears records.

getRecords(criteria)
Returns the staging table records based on the provided criteria(optional). However, the criteria object
can have the following properties:
whereClause: a string that will be used as the SQL where clause of the query that retrieves
records(optional).
orderByClause: a string that will be used as the SQL order by clause to order the results(optional).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 188


WT&A API Specifications 18.3 Export Stage API

getAggregationRecords(criteria, sumFields, groupByFields)


Returns the staging table records based on the provided criteria(optional), sumFields and groupByFields.
However, the criteria object can have the following properties:
whereClause: a string that will be used as the SQL where clause of the query that retrieves
records(optional).
orderByClause: a string that will be used as the SQL order by clause to order the results(optional).
sumFields: an Array of String containing the name of the fields that needs to be summed.
groupByFields: an Array of String containing the name of the groupByFields.

getUnprocessedRecords(criteria)
Returns the staging table records based on the provided criteria(optional). However, the criteria object
can have the following properties:
orderByClause: a string that will be used as the SQL order by clause to order the results(optional).

writeList(list)
Write a DBRecList to the database within the current database transaction.

commit()
Commit the current state of the database transaction.

rollback()
Roll back the state of the database transaction to the last commit.

close()
Close the database connection.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 189


WT&A API Specifications 18.3 File Manager API

File Manager API


Overview and Capabilities
The File Manager API provides a way to read data from structured data files, such as CSV or fixed width data.
It also provides basic file management tools such as file renaming, archiving, and moving.
The main use of the File Manager API is to read a data file with a defined structure; the most common
structure is a comma-separated values (CSV) structure. The API provides a way to read such a file by
specifying the field headers and processing the file line-by-line, reading field values. The API assumes certain
defaults, but allows the user to specify, if necessary, such settings as character set, delimiter, starting line,
and default date and time formats.
The File Manager API also provides a way to read data from fixed-width data files. In this mode, not all the
setting overrides are available. The file is read line-by-line, and data can be retrieved based on its position
within a line.
The File Manager API provides simple file management capabilities often used in conjunction with reading
data files. A file can have its header validated to make sure that the expected set of fields are present. The
file can be archived after processing for future investigation or backup, and files can be renamed or moved.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The Distributed JavaScript Library, FILE_MANAGER_API

Setup
No setup is necessary for the File Manager API. The distributed library is automatically available in
WorkForce Time and Attendance.

Use Cases
Reading data from a CSV file
This script excerpt demonstrates opening the file sample.csv and validating that it contains the header fields
EMPLOYEE, EFFECTIVE_DATE, PROJECT, and AMOUNT. It then reads values from the file and logs them out.
includeDistributedPolicy("FILE_MANAGER_API");

var fields = ['EMPLOYEE', 'EFFECTIVE_DATE', 'PROJECT', 'AMOUNT'];

var fm = new FileManager();


fm.setFile("sampleDirectory", "sample.csv");

// Indicate there is a header record


var fileParameters = {hasHeaderRecord: true};
// Set the default date format for all dates in the file
fm.setDateFormat("yyyy-MM-dd");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 190


WT&A API Specifications 18.3 File Manager API

fm.openFile(fileParameters);

// Confirm that the file has the expected headers


if (fm.validateFields(fields, false)) {
// Read the file line-by-line
while (fm.next()) {
// Extract a string value from the current line
var employee = fm.getStringValue("EMPLOYEE");
// Extract a date value from the current line
var effectiveDate = fm.getDateValue("EFFECTIVE_DATE");
// Extract a number value from the current line
var amount = fm.getNumericalValue("AMOUNT");
// Do something with the extracted data
log.info("Read data " + employee + " " + effectiveDate + " " + amount);
}
} else {
log.error("File validation failed.");
}
fm.closeFile()

Reading data from a fixed-width file


This script excerpt demonstrates reading data from a fixed-width file. In order to access a field, the starting
position of the field and its width in characters must be specified. Position ordering begins with 0 at the far
left of the line.
includeDistributedPolicy("FILE_MANAGER_API");
// Set and open the file. The filepath and filename are combined into a single parameter
var fwfr = new FixedWidthFileReader("fixed_width_sample.txt");
fwfr.open();
// Read the file line-by line
while (fwfr.next()) {
// Read the first field. It starts at position 0 (far left of the line) and is 10
characters wide
var first_field_width_10 = fwfr.getData(0, 10);
// Read the second field. It starts at position 10 and is 5 characters wide
var second_field_width_5 = fwfr.getData(10, 5);
// Read the third field. It stars at position 15 and is 20 characters wide
var third_field_width_20 = fwfr.getData(15, 20);
// Do something with the data
}
// Close the file
fwfr.close();

Reading data from a file line by line


This script excerpt demonstrates reading data from a file line by line.
includeDistributedPolicy("FILE_MANAGER_API");
// set the file
var fileName = "workforce/sample_data/datafiles/file_manager_api_read_file_test.txt";
var fileReader = new FileLineReader({ filename: fileName });
fileReader.open();
// read the file line by line
fileReader.next();
var firstLine = fileReader.getLine();
// move to the next line

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 191


WT&A API Specifications 18.3 File Manager API

fileReader.next();
var secondLine = fileReader.getLine();
// close the reader
fileReader.close();

Reading data from a CSV file while validating the character set of a file
This script excerpt demonstrates opening the file sample.csv, but before that it validates that the character
set provided in the file is correct compared to what was passed as a parameter. It then reads values from the
file and logs them.
includeDistributedPolicy("FILE_MANAGER_API");

var fields = ['EMPLOYEE', 'EFFECTIVE_DATE', 'PROJECT', 'AMOUNT'];

var fm = new FileManager();


fm.setFile("sampleDirectory", "sample.csv");

// Indicate there is a header record


var fileParameters = {hasHeaderRecord: true, charSet: “UTF-8”, enforceCharsetEncoding: true};
// Set the default date format for all dates in the file
fm.setDateFormat("yyyy-MM-dd");
fm.openFile(fileParameters);

// Confirm that the file has the expected headers


if (fm.validateFields(fields, false)) {
// Read the file line-by-line
while (fm.next()) {
// Extract a string value from the current line
var employee = fm.getStringValue("EMPLOYEE");
// Extract a date value from the current line
var effectiveDate = fm.getDateValue("EFFECTIVE_DATE");
// Extract a number value from the current line
var amount = fm.getNumericalValue("AMOUNT");
// Do something with the extracted data
log.info("Read data " + employee + " " + effectiveDate + " " + amount);
}
} else {
log.error("File validation failed.");
}
fm.closeFile()

Reading data from a fixed-width file while validating the character set
of a file
This script excerpt demonstrates reading data from a fixed-width file, but before that it validates that the
character set provided in the file is correct compared to what was passed as a parameter. To access a field,
the starting position of the field and its width in characters must be specified. Position ordering begins with 0
at the far left of the line.
includeDistributedPolicy("FILE_MANAGER_API");
// Set and open the file. The filepath and filename are combined into a single parameter,
// plus other parameters for validating the character set are also provided.
var charSet = “UTF-8”;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 192


WT&A API Specifications 18.3 File Manager API

var encrypted = false;


var enforceCharSetEncoding = false;
var fwfr = new FixedWidthFileReader("fixed_width_sample.txt", charSet, encrypted,
enforceCharSetEncoding);
fwfr.open();
// Read the file line-by line
while (fwfr.next()) {
// Read the first field. It starts at position 0 (far left of the line) and is 10
characters wide
var first_field_width_10 = fwfr.getData(0, 10);
// Read the second field. It starts at position 10 and is 5 characters wide
var second_field_width_5 = fwfr.getData(10, 5);
// Read the third field. It stars at position 15 and is 20 characters wide
var third_field_width_20 = fwfr.getData(15, 20);
// Do something with the data
}
// Close the file
fwfr.close();

Reading data from a file line by line while validating the character set of
a file
This script excerpt demonstrates reading data from a file line by line, but before that it validates that the
character set provided in the file is correct compared to what was passed as a parameter.
includeDistributedPolicy("FILE_MANAGER_API");
// set the file
var fileName = "workforce/sample_data/datafiles/file_manager_api_read_file_test.txt";
var fileReader = new FileLineReader({
filename: fileName,
charSet: 'UTF-16'
});
fileReader.open();
// read the file line by line
fileReader.next();
var firstLine = fileReader.getLine();
// move to the next line
fileReader.next();
var secondLine = fileReader.getLine();
// close the reader
fileReader.close();

Reading data from an Encrypted CSV file


This script excerpt demonstrates opening the encrypted file sample.csv and validating that it contains the
header fields EMPLOYEE, EFFECTIVE_DATE, PROJECT, and AMOUNT. It then reads values from the file and
logs them.
includeDistributedPolicy("FILE_MANAGER_API");

var fields = ['EMPLOYEE', 'EFFECTIVE_DATE', 'PROJECT', 'AMOUNT'];

var fm = new FileManager();


fm.setFile("sampleDirectory", "sample.csv");

// Indicate there is a header record


var fileParameters = {hasHeaderRecord: true, encrypted: true};
// Set the default date format for all dates in the file

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 193


WT&A API Specifications 18.3 File Manager API

fm.setDateFormat("yyyy-MM-dd");
fm.openFile(fileParameters);

// Confirm that the file has the expected headers


if (fm.validateFields(fields, false)) {
// Read the file line-by-line
while (fm.next()) {
// Extract a string value from the current line
var employee = fm.getStringValue("EMPLOYEE");
// Extract a date value from the current line
var effectiveDate = fm.getDateValue("EFFECTIVE_DATE");
// Extract a number value from the current line
var amount = fm.getNumericalValue("AMOUNT");
// Do something with the extracted data
log.info("Read data " + employee + " " + effectiveDate + " " + amount);
}
} else {
log.error("File validation failed.");
}
fm.closeFile()

Reading data from an encrypted fixed-width file


This script excerpt demonstrates reading data from an encrypted fixed-width file. In order to access a field,
the starting position of the field and its width in characters must be specified. Position ordering begins with 0
at the far left of the line.
includeDistributedPolicy("FILE_MANAGER_API");
// Set and open the file. The filepath and filename are combined into a single parameter
var fwfr = new FixedWidthFileReader("fixed_width_sample.txt", “UTF-8”, true);
fwfr.open();
// Read the file line-by line
while (fwfr.next()) {
// Read the first field. It starts at position 0 (far left of the line) and is 10
characters wide
var first_field_width_10 = fwfr.getData(0, 10);
// Read the second field. It starts at position 10 and is 5 characters wide
var second_field_width_5 = fwfr.getData(10, 5);
// Read the third field. It stars at position 15 and is 20 characters wide
var third_field_width_20 = fwfr.getData(15, 20);
// Do something with the data
}
// Close the file
fwfr.close();

Reading data from an encrypted file line by line


This script excerpt demonstrates reading data from an encrypted file line by line.
includeDistributedPolicy("FILE_MANAGER_API");
// set the file
var fileName = "workforce/sample_data/datafiles/file_manager_api_read_file_test.txt";
var fileReader = new FileLineReader({
filename: fileName,
encrypted: true
});

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 194


WT&A API Specifications 18.3 File Manager API

fileReader.open();
// read the file line by line
fileReader.next();
var firstLine = fileReader.getLine();
// move to the next line
fileReader.next();
var secondLine = fileReader.getLine();
// close the reader
fileReader.close();

Archiving a file
After processing a file, it may be advisable to move it to an archive directory and rename it, so its contents
can be reviewed if necessary. The following example demonstrates archiving a file, sample.csv.

Example: Archiving a file


includeDistributedPolicy("FILE_MANAGER_API");
var fm = new FileManager();
fm.setFile("sampleDirectory", "sample.csv");
// Any processing of the file would go here
fm.archiveFile("archive");

After this script is run, the file sample.csv will be moved to a directory named archive and a timestamp
prepended to the filename; for instance, 20180323135113_sample.csv.
The archiveFile option does not allow customization of the archived file name. If prepending a timestamp is
not the desired change, the new name can be fully specified using the file renaming operation, described
next.

Renaming or moving a file


Renaming a file or moving it between directories – or both at the same time – can be done with a single
method of the File Manager API. The following examples demonstrate these operations on a file named
sample.csv.

Example 1: Renaming a file


includeDistributedPolicy("FILE_MANAGER_API");
var fm = new FileManager();
fm.setFile("sampleDirectory", "sample.csv");
fm.renameFile(fm.getPath(), "sample.bak");

After this script is run, the file sample.csv should be renamed to sample.bak and remain in the same
directory as it was initially.

Example 2: Moving a file


includeDistributedPolicy("FILE_MANAGER_API");
var fm = new FileManager();
fm.setFile("sampleDirectory", "sample.csv");
fm.renameFile("newDir", fm.getName());

After this script is run, the file sample.csv will be moved to a directory named newDir, but with the file name
unchanged.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 195


WT&A API Specifications 18.3 File Manager API

Example 3: Renaming and moving a file simultaneously


includeDistributedPolicy("FILE_MANAGER_API");
var fm = new FileManager();
fm.setFile("sampleDirectory", "sample.csv");
fm.renameFile("newDir", "sample.bak");

After this script is run, the file sample.csv will be renamed to sample.bak and moved to a directory named
newDir.

Creating a new directory


The script excerpt below demonstrates creating a new directory. To create the directory, the path is
specified. The method returns true if the directory is created successfully. If it fails or the directory already
exists, it returns false.
includeDistributedPolicy("FILE_MANAGER_API");
importClass(Packages.com.workforcesoftware.Misc.ConfigData);

var fileManager = new FileManager();


// get the absolute path for the directory to be created
var dirPath = new WFSFile(ConfigData.getInstance().getDistributionRootDirectory());
// create the path where the directory is to be created
var newDirectoryPath = dirPath + "/workforce/sample_data/datafiles/" + "INT_1200";
// confirm the file is created successfully
test.assertTrue(fileManager.createDirectory(newDirectoryPath), "createDirectory method runs
successfully.");

// delete the new created directory


var newFile = new WFSFile(newDirectoryPath);
newFile.delete(newFile);

Troubleshooting
The job log of the script using the File Manager API will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
Some common error messages, their causes, and the solution:
Error Message Cause Solution
FileNotFoundException: Source The file as specified could not be Check that the file path and name
File 'nonexistentFile.txt' could not found are correct, and the file is in place
be found in folder
Invalid delimiter. Delimiter must A delimiter of more than one Use a single-character delimiter
be a single character. character has been specified
Header fields are not set, so File contains no headers, and Add headers to the file, or
nothing will ever actually be read none were specified provide the header list to the API
from file.
Fields cannot be validated, Header validation was attempted Call validateFields after opening
because file is not open. before the file was opened the file
Extra fields present in import file: Actual and expected headers do Make sure the correct file is being
EXTRA_FIELD not match when validateFields is read, and the correct headers are
used specified. If extra fields are

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 196


WT&A API Specifications 18.3 File Manager API

Fields missing in import file: allowed, indicate that in the call


MISSING_FIELD to validateFields
Error parsing line A line of data was unparseable Ensure the source data is not
corrupted or otherwise incorrect.
The error message may indicate
the specific problem
Table 42: File Manager API common error messages, causes, and solutions

API Reference
FileManager
The FileManager has the following methods available:

FileManager()
Create a new FileManager.

setFile(filePath, fileName)
Specify the path and name of the file to be processed.

getPath()
Returns the path of the file - as provided in the setFile call.

getName()
Returns the name of the file - as provided in the setFile call.

archiveFile(archivePath)
Prepend a current timestamp to the name of the file and move it to the specified path.

renameFile(newFilePath, newFileName)
Rename and/or move the file to the specified path and file name.

openFile(fileParameters)
Open the file specified by the call to setFile. The fileParameters are specified as a JavaScript object, which
can have the following properties:
• delimiter: The file delimiter. Defaults to a comma if not provided.
• hasHeaderRecord: specify true if there is a header record in the source file, with the field headers.
Defaults to false.
• useUppercaseHeaders: specify true if the headers in the source file should be converted to
uppercase. Defaults to false.
• discardBOM: specify true if the source file is in an encoding that uses Byte Order Marks (such as UTF-
8). Defaults to false.
• charSet: specify the character set encoding of the source file. If not specified, Java will attempt to
detect the character set based on the file contents.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 197


WT&A API Specifications 18.3 File Manager API

• startingLineNumber: specify the line number to start reading the file at. Useful if there are non-data
header lines. Defaults to 1.
• fileHeader: If the source file does not have a header row, specify the field names of the source file as
an array of strings.
• encrypted: whether or not the file is encrypted. Defaults to false.
• enforceCharSetEncoding: Whether to enforce character set encoding validation or not. Defaults to
false.

closeFile()
Close the file used by the reader. This should always be done, to ensure the file is released.

validateFields(fieldArray, areExtraFieldsAllowed)
Compare the field headers found in the source file against those provided in the fieldArray. Will return false
if either there are fields in the fieldArray that are not found in the file, or if there are fields in the source file
that are not in the fieldArray (unless areExtraFieldsAllowed is true). If the fields match, or there are extra
fields in the source file and areExtraFieldsAllowed is true, will return true.

setDateFormat(format)
Specify a date format that will automatically apply to all date fields, unless overridden within calls to
getDateValue. If all dates in the source file will be in the same format, it is recommended to use this method
to indicate the format, then it will not be necessary to specify a format in the individual getDateValue calls.

setDateTimeFormat(format)
Specify a datetime format that will automatically apply to all datetime fields, unless overridden within calls to
getDateTimeValue. If all datetimes in the source file will be in the same format, it is recommended to use
this method to indicate the format, then it will not be necessary to specify a format in the individual
getDateTimeValue calls.

next()
Advance the reader to the next line of the file. If there is a next line, this will return true, otherwise it will
return false.

getStringValue(field, defaultValue)
Extract string data from the current line. Field specifies the name of the field to extract, and defaultValue is
an optional parameter that indicates what to return if the field is empty.

getDateValue(field, format, defaultValue)


Extract data from the current line and automatically attempt to convert it to a date value. Field specifies the
name of the field to extract, format is an optional value that indicates the date format, and defaultValue is an
optional parameter that indicates what to return if the field is empty.

getDateTimeValue(field, format, defaultValue)


Extract data from the current line and automatically attempt to convert it to a datetime value. Field specifies
the name of the field to extract, format is an optional value that indicates the datetime format, and
defaultValue is an optional parameter that indicates what to return if the field is empty.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 198


WT&A API Specifications 18.3 File Manager API

getNumericalValue(field, defaultValue)
Extract data from the current line and automatically attempt to convert it to a number value. Field specifies
the name of the field to extract, and defaultValue is an optional value that indicates what to return if the field
is empty.

FixedWidthFileReader
The FixedWidthFileReader has the following methods available:

FixedWidthFileReader(filename, charSet, encrypted, enforceCharSetEncoding)


Create a FixedWidthFileReader for the specified file. The filename can include the path to the file. Specify the
desired character encoding with charSet (optional). The encrypted parameter tells the reader whether or not
the specified file has been encrypted (optional). The enforceCharSetEncoding parameter tells whether or not
to validate the character set of the file.

open()
Open the file specified when the reader was created.

close()
Close the file used by the reader. This should always be done, to ensure the file is released.

next()
Advance the reader to the next line of the file. If there is a next line, this will return true, otherwise it will
return false.

getData(startPosition, width)
Extract string data from the current line. The startPosition specifies the position in the line to begin from (0 is
the far left) and the width specifies the number of characters.

FileLineReader
The FileLineReader has the following methods available:

FileLineReader(params)
Create a FileLineReader for the specified file. The params object contains the following parameters to read
the file:
Parameter Optional Description
filename Yes Name of file to read the text from
charset No The character set the file is encoded with
encrypted No Whether the file is encrypted or not
enforceCharSetEncoding No Whether the character set should be enforced or not.
charset must be provided if this is true

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 199


WT&A API Specifications 18.3 File Manager API

open()
Open the file specified when the reader was created.

close()
Close the file used by the reader. This should always be done, to ensure the file is released.

next()
Advance the reader to the next line of the file. If there is a next line, this will return true, otherwise it will
return false.

getLine()
Extract string data from the current line.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 200


WT&A API Specifications 18.3 File Writer API

File Writer API


Overview and Capabilities
The File Writer API provides interfaces with the ability to write out data to arbitrary files from within a script.
The API includes support for writing both delimited data, with the delimiters being inserted automatically
into the output, and for writing non-delimited data.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• How policy sets function within WorkForce Time and Attendance

Components
This API consists of the following component(s):
• The Distributed JavaScript Library policy FILE_WRITER_API

Setup
No setup is necessary for the File Writer API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Writing Delimited Text to a File
The File Writer API allows for delimited text to be written to a file. When operating in this fashion, the API
expects each field in the file to be written using a separate call, and the API will automatically insert the
delimiters as needed:

Example 1: Writing delimited text to a file


includeDistributedPolicy("FILE_WRITER_API");

// Define the parameters for the file writer


var parms = {
// The name of the file the data should be written to
fileName: "export_data.csv",

// The character encoding to use in the file


charsetName: "UTF-8",

// The delimiter to use to separate fields in the file


delimiter: ","

// The character(s) to be used to end a line in the file


lineBreak: "\r\n"
};
var fileWriter = new FileWriter(parms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 201


WT&A API Specifications 18.3 File Writer API

// Assume there is something that returns us an array of objects to be exported


var data = getData();

// Iterate over each record and write it to the file


for (var i = 0; i < data.length; ++i) {
var record = data[i];

// Add each data attribute to be exported for the current record to the file
// buffer
fileWriter.append(record.field1);
fileWriter.append(record.field2);
fileWriter.append(record.field3);
fileWriter.append(record.field4);
fileWriter.append(record.field5);

// Print the contents of the buffer to the file


fileWriter.writeBuffer();
}

// Now that all of the data has been written, close the file writer
fileWriter.close();

Note: Calls to append() only add the data to a buffer. That buffer does not actually get written to the file until
writeBuffer() is called.

If no additional action is taken, each value written to a delimited file will be automatically enclosed within
double quotes. This behavior can be turned off globally if desired for a file, and then re-enabled on a field-
by-field basis as needed if some fields should have quotes and some should not:

Example 2: Controlling quoting of fields in a delimited file


includeDistributedPolicy("FILE_WRITER_API");

// Define the parameters for the file writer


var parms = {
// The name of the file the data should be written to
fileName: "export_data.csv",

// The character encoding to use in the file


charsetName: "UTF-8",

// The delimiter to use to separate fields in the file


delimiter: ","

// The character(s) to be used to end a line in the file


lineBreak: "\r\n",

// Setting this to false turns off the default behavior of always quoting values
// being appended
useQuotes: false
};
var fileWriter = new FileWriter(parms);

// Assume there is something that returns us an array of objects to be exported


var data = getData();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 202


WT&A API Specifications 18.3 File Writer API

// Iterate over each record and write it to the file


for (var i = 0; i < data.length; ++i) {
var record = data[i];

// Add each data attribute to be exported for the current record to the file
// buffer
fileWriter.append(record.field1); // Will not have quotes
fileWriter.append(record.field2, true); // Will have quotes
fileWriter.append(record.field3, false); // Will not have quotes
fileWriter.append(record.field4); // Will not have quotes
fileWriter.append(record.field5, true); // Will have quotes

// Print the contents of the buffer to the file


fileWriter.writeBuffer();
}

// Now that all of the data has been written, close the file writer
fileWriter.close();

Example 3: Writing the Output Using Encryption


The File Writer API allows the user to write encrypted data. To do this, specify the encryptionAlias property
in the parameters object sent to the FileWriter constructor. The encryptionAlias should match one of the
existing encryption aliases on the customer’s system. After specifying the parameter, use the FileWriter as
normal, and any contents it writes will be encrypted.
includeDistributedPolicy("FILE_WRITER_API");

// Define the parameters for the file writer


var parms = {
// The name of the file the data should be written to
fileName: "export_data.csv",

// The character encoding to use in the file


charsetName: "UTF-8",

// The delimiter to use to separate fields in the file


delimiter: ","

// The character(s) to be used to end a line in the file


lineBreak: "\r\n",

// Setting this to false turns off the default behavior of always quoting values
// being appended
useQuotes: false,

// The encryption alias to use for encrypting data


encryptionAlias: “fooEncryption”
};
var fileWriter = new FileWriter(parms);

// Assume there is something that returns us an array of objects to be exported


var data = getData();

// Iterate over each record and write it to the file


for (var i = 0; i < data.length; ++i) {
var record = data[i];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 203


WT&A API Specifications 18.3 File Writer API

// Add each data attribute to be exported for the current record to the file
// buffer
fileWriter.append(record.field1); // Will not have quotes
fileWriter.append(record.field2, true); // Will have quotes
fileWriter.append(record.field3, false); // Will not have quotes
fileWriter.append(record.field4); // Will not have quotes
fileWriter.append(record.field5, true); // Will have quotes

// Print the contents of the buffer to the file


fileWriter.writeBuffer();
}

// Now that all of the data has been written, close the file writer
fileWriter.close();

Writing Non-Delimited Text to a File


The File Writer API also allows for text that should not be delimited (such as for a fixed-width file) to be
written to a file. In this case, the expectation is that the script would compute each line exactly as it should
be written to the file before using the API to write that line:

Example: Writing delimited text to a file


includeDistributedPolicy("FILE_WRITER_API");

// Define the parameters for the file writer


var parms = {
// The name of the file the data should be written to
fileName: "export_data.csv",

// The character encoding to use in the file


charsetName: "UTF-8",

// The character(s) to be used to end a line in the file


lineBreak: "\r\n"
};
var fileWriter = new FileWriter(parms);

// Assume there is something that returns us an array of objects to be exported


var data = getData();

// Iterate over each record and write it to the file


for (var i = 0; i < data.length; ++i) {
var record = data[i];

// Construct the line that should be written to the file


var output = record.field1 + record.field2 + record.field3 + record.field4;

// Write the line to the file


fileWriter.writeLine(output);
}

// Now that all of the data has been written, close the file writer
fileWriter.close();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 204


WT&A API Specifications 18.3 File Writer API

Note: When using writeLine(), the data is written to the file immediately, as opposed to being buffered for
later writing.

Troubleshooting
The job log of the script using the File Writer API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No file parameters defined An attempt was made to create a Ensure that all new FileWriter objects
for the File Writer new FileWriter object without that are created have parameters
specifying any parameters for it. being specified when they are
created.
Unable to create FileWriter A FileWriter object was created Ensure that all new FileWriter objects
without a file name using parameters that did not that are created have a file name
specified define a file name to be written to. specified in their parameters.
Table 43: File Writer API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

FileWriter
FileWriter(parms)
Creates a new instance of the File Writer, using the settings specified in the provided parameters.
Parameter Name Description
fileName The full path and file name of the file that should be written to
charsetName Optional character encoding to use for the file. Valid options are:
US-ASCII
ISO-8859-1
UTF-8
UTF-16BE
UTF-16LE
UTF-16
Defaults to UTF-8 if not specified
delimiter Delimiter to use between fields when writing delimited data. Defaults to
comma (,) if not specified.
useQuotes True if all fields being written should be enclosed in quotes when writing
delimited data, false if quotes should be specified on a per-field basis.
Defaults to true if not specified.
lineBreak The character(s) to use between lines in the file. Defaults to a carriage return
plus a line break if not specified.
encryptionAlias The encryption alias to use if the file should be encrypted. Defaults to NONE if
not specified.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 205


WT&A API Specifications 18.3 File Writer API

Table 44: Parameters available to be specified when creating a new FileWriter

writeLine(text)
Writes the specified text to the file, followed by a line break. No special formatting, such as the addition of
quotes or delimiters, will be applied to the text.

append(text, forceQuotes)
Adds the specified text to the buffer for the file. If previous content has already been added to the buffer,
then a delimiter will be added to the buffer before the text content is appended. If the FileWriter has
quoting turned on globally, or if forceQuotes is true, then the text will be wrapped in double quotes before
being appended.

writeBuffer()
Writes the current contents of the buffer to the file, followed by a line break.

close()
Closes the file and stops any further writing from taking place.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 206


WT&A API Specifications 18.3 FTP API

FTP API
Definitions of Terms Used in This Section
FTP – File Transfer Protocol (FTP) is a standard network protocol used to transfer files between a client and a
server. This API provides FTP support for WorkForce Time and Attendance.
SFTP – SSH File Transfer Protocol (SFTP) is a standard network protocol used to transfer files between a client
and a server in a secure way using an extension of the Secure Shell (SSH) protocol.
FTPS – FTPS is an extension to the FTP protocol that adds support for the Transport Layer Security (TLS) and
Secure Socket Layer (SSL) cryptographic protocols to securely transfer files.

Overview
The FTP API provides support for transferring files to/from an FTP server from within an WorkForce Time and
Attendance script. It supports using the FTP, SFTP, or FTPS protocols for performing the files transfers.
Typically this would be used as part of a larger process, such as retrieving a file and then processing it to
import data or exporting data to a file and then transferring it to a remote server.
In addition to its abilities to move files between the WorkForce Time and Attendance server and the FTP
server, the FTP API can also be used for a number of different file-based operations against the files on either
the WorkForce Time and Attendance server or FTP server. This includes determining which files are located
on the server, determining if a specific file exists, creating directories, renaming files, deleting files, moving
files, and copying files.

Prerequisites
To use this API, you should be familiar with the following functionality:
• How to create policies within the Policy Editor
• Basic file transfer concepts, particularly those of getting files and putting files
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The FTP_SCRIPT_API distributed JavaScript library
• One or more FTP Connection Info policies in Policy Editor

Setup
Make sure the following two requirements are met before using the FTP API:

The FTP_SCRIPT_API Distributed JavaScript Library


The FTP_SCRIPT_API library is distributed by WorkForce Software, and should already be present in any
EmpCenter 15.1 or later instance. No action needs to be taken for this component.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 207


WT&A API Specifications 18.3 FTP API

FTP Connection Info Policy


Use of the FTP API requires one or more FTP Connection Info policies, which are located and set up in Policy
Editor. You must create these policies manually. See the Policy Configuration Guide for full details on the
FTP Connection Info policy; a short summary of the most important policy fields appears below.
Create the FTP Connection Info policy or policies based on the customer requirements. Typically, there will
be one FTP Connection Info policy per FTP server that files need to be transferred to/from.

Field Description
Connection Type Specifies what type of file transfer connection should be established.
Host Specifies the host name of the FTP server that should be connected to.
Port Specifies which port the communication should use.
User ID Specifies which user ID should be used to establish the connection.
Authentication Specifies whether a password or a private key file should be used as part of the
Method authentication credentials
Password Specifies which password should be used to establish the connection.
Private Key File Path Specifies the location of the file containing the private key file that should be used
to establish the connection. (The key contained in the file must be in OpenSSH
format.)
Table 45: Fields in FTP Connection Info policy

Example FTP Connection Info


Below is an example FTP Connection Info policy named SAMPLE_CONNECTION.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 208


WT&A API Specifications 18.3 FTP API

This guide will refer to this example in further sections.

Use Cases
Retrieving a File from a Remote Server
The FTP API can be used to copy a file from a remote file server to the local server, where it can be read by
the same or other interface processes. This is needed because WorkForce Time and Attendance is only able
to read from files that are present on the local server. The original file on the remote file server remains
unaltered by this process.

Example 1: Retrieving a single file


The following script example demonstrates copying a single file named “importData.csv” from the
“outbound/sourceFiles” directory on the remote file server to the “interface/incoming” directory on the local
server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 209


WT&A API Specifications 18.3 FTP API

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote file to be copied


var remoteDirectory = "outbound/sourceFiles";
var remoteFileName = "importData.csv";

// Define the location the file should be stored on the local server
var localDirectory = "interface/incoming";
var localFileName = "importData.csv";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the file from the remote server


ftpClient.getFile(remoteDirectory, remoteFileName, localDirectory, localFileName,
replaceExisting);

Example 2: Retrieving many files based on an array of file names


The following script example demonstrates how to copy several different files with specific names from the
“outbound/sourceFiles” directory on the remote file server to the “interface/incoming” directory on the local
server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote files to be copied


var remoteDirectory = "outbound/sourceFiles";
var remoteFileNames = ["file1.csv", "file2.csv", "file3.csv", "file4.csv"];

// Define the location the file should be stored on the local server
var localDirectory = "interface/incoming";

// Specify a suffix that should be added to the end of the file names
var suffix = "_unprocessed";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the files from the remote server


ftpClient.getFiles(remoteDirectory, remoteFileNames, localDirectory, suffix,
replaceExisting);

In this example, the local directory would end up with files named “file1_unprocessed.csv”,
“file2_unprocessed.csv”, “file3_unprocessed.csv”, and “file4_unprocessed.csv” after the operation is
complete.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 210


WT&A API Specifications 18.3 FTP API

Example 3: Retrieving many files based on a pattern match


The following script example demonstrates how to copy all files that match a specified regular expression in
the “outbound/sourceFiles” directory on the remote file server over to the “interface/incoming” directory on
the local server. In this example, all files that have names beginning with the word “file” followed by a
number and then terminated with the “.csv” suffix will be copied:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote files to be copied


var remoteDirectory = "outbound/sourceFiles";
var filePattern = "file(\\d+)\\.csv";

// Define the location the file should be stored on the local server
var localDirectory = "interface/incoming";

// Specify a suffix that should be added to the end of the file names
var suffix = "_unprocessed";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the files from the remote server


ftpClient.getFiles(remoteDirectory, filePattern, localDirectory, suffix,
replaceExisting);

Transferring a File to a Remote Server


The FTP API can be used to copy a file from the local server to a remote file server. This might be used as part
of an export process, in order to transfer the completed export file to a remote system for processing after it
is produced. The original file on the local server remains unaltered by this process.

Example 1: Transferring a single file


The following script example demonstrates copying a single file named “exportData.csv” from the
“interface/outgoing” directory on the local server to the “inbound/payrollFiles” directory on the remote file
server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local file to be copied


var localDirectory = "interface/outgoing";
var localFileName = "exportData.csv";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 211


WT&A API Specifications 18.3 FTP API

// Define the location the file should be stored on the remote file server
var remoteDirectory = "inbound/payrollFiles";
var remoteFileName = "exportData.csv";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the file to the remote server


ftpClient.putFile(localDirectory, localFileName, remoteDirectory, remoteFileName,
replaceExisting);

Example 2: Transferring many files based on an array of file names


The following script example demonstrates how to copy several different files with specific names from the
“interface/outgoing” directory on the local server to the “outbound/payrollFiles” directory on the remote file
server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local files to be copied


var localDirectory = "interface/outgoing";
var localFileNames = ["file1.csv", "file2.csv", "file3.csv", "file4.csv"];

// Define the location the file should be stored on the remote file server
var remoteDirectory = "inbound/payrollFiles";

// Specify a suffix that should be added to the end of the file names
var suffix = "_unprocessed";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the file to the remote server


ftpClient.putFiles(localDirectory, localFileNames, remoteDirectory, suffix,
replaceExisting);

In this example, the remote file directory would end up with files named “file1_unprocessed.csv”,
“file2_unprocessed.csv”, “file3_unprocessed.csv”, and “file4_unprocessed.csv” after the operation is
complete.

Example 3: Transferring many files based on a pattern match


The following script example demonstrates how to copy all files that match a specified regular expression in
the “interface/outgoing” directory on the local server over to the “inbound/payrollFiles” directory on the
remote file server. In this example, all files that have names beginning with the word “file” followed by a
number and then terminated with the “.csv” suffix will be copied:
includeDistributedPolicy("FTP_SCRIPT_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 212


WT&A API Specifications 18.3 FTP API

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local files to be copied


var localDirectory = "interface/outgoing";
var filePattern = "file(\\d+)\\.csv";

// Define the location the file should be stored on the remote file server
var remoteDirectory = "inbound/payrollFiles";

// Specify a suffix that should be added to the end of the file names
var suffix = "_unprocessed";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy the file to the remote server


ftpClient.putFiles(localDirectory, filePattern, remoteDirectory, suffix,
replaceExisting);

Identifying Which Files Are Present


The FTP API can be used to identify which files exist on either the local directory or a remote file directory, as
shown in the following examples:

Example 1: Listing local files that match a specified pattern


The following script example demonstrates looking up all files that have the name “file_” followed by 14
numbers (e.g. a timestamp in the form yyyyMMddHHmmss) and with the “.csv” suffix that are present in the
“interface/incoming” directory on the local server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming";

// Define the pattern indicating which files should be returned


var pattern = "file_(\\d{14})\\.csv";

// Specify whether any directories with names that match the pattern should be
// included in the results
var includeDirectories = false;

// Get the names of the matching files in the specified directory


var fileNames = ftpClient.listLocalDirectory(directory, pattern, includeDirectories);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 213


WT&A API Specifications 18.3 FTP API

// Iterate over the files and do something with them


for (var i = 0; i < fileNames.length; ++i) {
var fileName = fileNames[i];
log.info("Found the file " + fileName);
}

Example 2: Determining if a specific local file exists


The following script example demonstrates how to use the API to determine if a file with the name
“employeeImport.csv” exists in the “interface/incoming” directory on the local server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming";

// The name of the file to check for


var fileName = "employeeImport.csv";

// Determine if the file exists


var fileExists = ftpClient.localFileExists(directory, fileName);

// Perform whatever logic is needed based on the existence of the file


if (fileExists) {
// Do something
}
else {
// Do something else
}

Example 3: Listing remote files that match a specified pattern


The following script example demonstrates looking up all files that have the name “file_” followed by 14
numbers (e.g. a timestamp in the form yyyyMMddHHmmss) and with the “.csv” suffix that are present in the
“outbound/sourceFiles” directory on the remote file server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Define the pattern indicating which files should be returned


var pattern = "file_(\\d{14})\\.csv";

// Specify whether any directories with names that match the pattern should be
// included in the results

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 214


WT&A API Specifications 18.3 FTP API

var includeDirectories = false;

// Get the names of the matching files in the specified directory


var fileNames = ftpClient.listRemoteDirectory(directory, pattern,
includeDirectories);

// Iterate over the files and do something with them


for (var i = 0; i < fileNames.length; ++i) {
var fileName = fileNames[i];
log.info("Found the file " + fileName);
}

Example 4: Determining if a specific remote file exists


The following script example demonstrates how to use the API to determine if a file with the name
“targetFile.csv” exists in the “outbound/sourceFiles” directory on the remote file server:
includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// The name of the file to check for


var fileName = "targetFile.csv";

// Determine if the file exists


var fileExists = ftpClient.remoteFileExists(directory, fileName);

// Perform whatever logic is needed based on the existence of the file


if (fileExists) {
// Do something
}
else {
// Do something else
}

Renaming Files
The FTP API can be used to rename files on the local or remote file servers. The following script examples
demonstrate this functionality:

Example 1: Renaming a single local file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 215


WT&A API Specifications 18.3 FTP API

// Define the local directory to look for files in


var directory = "interface/incoming/";

// Specify the file in the directory to be renamed


var existingFileName = "employeeData.csv";

// Specify the new name the file should have


var newFileName = "employeeData_processed.csv";

// Rename the file


ftpClient.renameLocalFile(directory, existingFileName, newFileName);

Example 2: Appending a suffix to the file names of multiple local files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming";

// Specify the pattern to match all of the files in the directory that should be renamed
var pattern = "file_(\\d{14})\\.csv";

// Specify the suffix that should be added to all of the file names
var suffix = "_processed";

// Rename all of the matching files


ftpClient.renameLocalFiles(directory, pattern, suffix);

Example 3: Renaming a single remote file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the file in the directory to be renamed


var existingFileName = "targetFile.csv";

// Specify the new name the file should have


var newFileName = "targetFile_processed.csv";

// Rename the file


ftpClient.renameRemoteFile(directory, existingFileName, newFileName);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 216


WT&A API Specifications 18.3 FTP API

Example 4: Appending a suffix to the file names of multiple remote files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the pattern to match all of the files in the directory that should be renamed
var pattern = "file_(\\d{14})\\.csv";

// Specify the suffix that should be added to all of the file names
var suffix = "_processed";

// Rename all of the matching files


ftpClient.renameRemoteFiles(directory, pattern, suffix);

Moving Files
In addition to moving files to/from the local server and the remote file server, the FTP API can also be used to
move files between directories on the same server (either local or remote). In this case, the original file is
removed from the directory it was originally in and placed into a different directory on the same server. The
following script examples demonstrate this functionality:

Example 1: Moving a single local file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var sourceDirectory = "interface/incoming/";

// Specify the file in the directory to be moved


var existingFileName = "employeeData.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "interface/incoming/processed/";

// Specify the name the file should have in the new directory
var newFileName = "employeeData.csv";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 217


WT&A API Specifications 18.3 FTP API

// Move the file


ftpClient.moveLocalFile(sourceDirectory, existingFileName, targetDirectory,
newFileName, replaceExisting);

Example 2: Moving multiple local files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming";

// Specify the pattern to match all of the files in the directory that should be moved
var pattern = "file_(\\d{14})\\.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "interface/incoming/processed/";

// Specify the suffix that should be added to all of the file names
var suffix = "_processed";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Move all of the matching files


ftpClient.moveLocalFiles(directory, pattern, targetDirectory, suffix,
replaceExisting);

Example 3: Moving a single remote file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var sourceDirectory = "outbound/sourceFiles";

// Specify the file in the directory to be moved


var existingFileName = "targetFile.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "outbound/sourceFiles/processed/";

// Specify the name the file should have in the new directory
var newFileName = "targetFile.csv";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 218


WT&A API Specifications 18.3 FTP API

// Define whether an existing file with that name on the remote server should be
// overwritten or not
var replaceExisting = true;

// Move the file


ftpClient.moveRemoteFile(sourceDirectory, existingFileName, targetDirectory,
newFileName, replaceExisting);

Example 4: Moving multiple remote files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the pattern to match all of the files in the directory that should be moved
var pattern = "file_(\\d{14})\\.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "outbound/sourceFiles/processed/";

// Specify the suffix that should be added to all of the file names
var suffix = "_processed";

// Define whether an existing file with that name on the remote server should be
// overwritten or not
var replaceExisting = true;

// Move all of the matching files


ftpClient.moveRemoteFiles(directory, pattern, targetDirectory, suffix,
replaceExisting);

Copying Files
The FTP API includes functionality for creating copies of files on either the local or remote file servers. With
this behavior, the original file remains untouched in its original directory and a second copy of the file is
created in either the same or a different directory on the same server. The following script examples
demonstrate this behavior:

Example 1: Copying a single local file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 219


WT&A API Specifications 18.3 FTP API

// Define the local directory to look for files in


var directory = "interface/incoming/";

// Specify the name of the file in the directory to be copied


var existingFileName = "employeeData.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "interface/incoming/allFiles/";

// Specify the name that the file should have in the new directory
var newFileName = existingFileName;

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy all of the matching files


ftpClient.copyLocalFile(directory, existingFileName, targetDirectory, newFileName,
replaceExisting);

Example 2: Copying multiple local files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming/";

// Specify the pattern to match all of the files in the directory that should be copied
var pattern = "file_(\\d{14})\\.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "interface/incoming/allFiles/";

// Specify the suffix that should be added to all of the file names
var suffix = "";

// Define whether an existing file with that name on the local server should be
// overwritten or not
var replaceExisting = true;

// Copy all of the matching files


ftpClient.copyLocalFiles(directory, pattern, targetDirectory, suffix,
replaceExisting);

Example 3: Copying a single remote file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 220


WT&A API Specifications 18.3 FTP API

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the name of the file in the directory to be copied


var existingFileName = "targetFile.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "outbound/allFiles";

// Specify the name that the file should have in the new directory
var newFileName = existingFileName;

// Define whether an existing file with that name on the remote server should be
// overwritten or not
var replaceExisting = true;

// Copy all of the matching files


ftpClient.copyRemoteFile(directory, existingFileName, targetDirectory, newFileName,
replaceExisting);

Example 4: Copying multiple remote files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the pattern to match all of the files in the directory that should be copied
var pattern = "file_(\\d{14})\\.csv";

// Specify the directory that the file should be moved to


var targetDirectory = "outbound/allFiles/";

// Specify the suffix that should be added to all of the file names
var suffix = "";

// Define whether an existing file with that name on the remote server should be
// overwritten or not
var replaceExisting = true;

// Move all of the matching files


ftpClient.copyRemoteFiles(directory, pattern, targetDirectory, suffix,
replaceExisting);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 221


WT&A API Specifications 18.3 FTP API

Deleting Files
In addition to copying or moving files, the FTP API can also be used to delete files on either the local server or
the remote file server. The following script examples demonstrate this behavior:

Example 1: Deleting a single local file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming/";

// Specify the name of the file in the directory to be deleted


var fileName = "oldDataFile.csv";

// Delete the specified file from the indicated directory


ftpClient.deleteLocalFile(directory, fileName);

Example 2: Deleting multiple local files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to look for files in


var directory = "interface/incoming/";

// Specify the pattern that should be matched to find the files to be deleted
var pattern = "old(.+)\\.csv";

// Specify whether directories with names matching the specified pattern should
// be deleted as well
var deleteDirectories = false;

// Delete all of the files that match the pattern from the indicated directory
ftpClient.deleteLocalFiles(directory, pattern, deleteDirectories);

Note: If deleting directories, a directory with a matching name must be empty in order to be deleted by this
process.

Example 3: Deleting a single remote file


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 222


WT&A API Specifications 18.3 FTP API

var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the name of the file in the directory to be deleted


var fileName = "oldDataFile.csv";

// Delete the specified file from the indicated directory


ftpClient.deleteRemoteFile(directory, fileName);

Example 4: Deleting multiple remote files


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to look for files in


var directory = "outbound/sourceFiles";

// Specify the pattern that should be matched to find the files to be deleted
var pattern = "old(.+)\\.csv";

// Specify whether directories with names matching the specified pattern should
// be deleted as well
var deleteDirectories = false;

// Delete all of the files that match the pattern from the indicated directory
ftpClient.deleteRemoteFiles(directory, pattern, deleteDirectories);

Note: If deleting directories, a directory with a matching name must be empty in order to be deleted by this
process.

Working with Directories


The FTP API can also be used to create or remove a directory from either the local server or the remote file
server. When creating a directory, any necessary parent directories will be automatically created as
necessary to place the specified directory at the desired point. (For instance, if the directory to be created
was “interface/incoming/timeImportFiles/schedulingSystem/”, and the “interface/incoming” directory did
not already contain any other directories, then this process would automatically create both a
“timeImportFiles” directory under “interface/incoming” and then a “schedulingSystem” directory within
“timeImportFiles”.) When deleting a directory, the directory specified must be empty in order for the
deletion to complete successfully. The following script examples demonstrate this behavior:

Example 1: Creating a local directory


includeDistributedPolicy("FTP_SCRIPT_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 223


WT&A API Specifications 18.3 FTP API

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to be created


var directory = "interface/incoming/timeImportFiles/schedulingSystem/";

// Create the directory


ftpClient.createLocalDirectory(directory);

Example 2: Deleting a local directory


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the local directory to be deleted


var directory = "interface/incoming/timeImportFiles/schedulingSystem/";

// Delete the specified directory


ftpClient.deleteLocalDirectory(directory);

Example 3: Creating a remote directory


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

// Define the remote directory to be created


var directory = "outbound/sourceFiles/employeeImportData/";

// Create the directory


ftpClient.createRemoteDirectory(directory);

Example 4: Deleting a remote directory


includeDistributedPolicy("FTP_SCRIPT_API");

// Define which FTP Connection Info policy stores the connection information to use
var ftpConnectionInfoPolicy = "SAMPLE_CONNECTION";

// Create a new FTP Client using the specified FTP Connection Info policy
var ftpClient = new FTPClient(ftpConnectionInfoPolicy);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 224


WT&A API Specifications 18.3 FTP API

// Define the remote directory to be deleted


var directory = "outbound/sourceFiles/employeeImportData/";

// Delete the specified directory


ftpClient.deleteRemoteDirectory(directory);

Troubleshooting
The job log of the script using the FTP API will contain information messages and, in the case of problems, any
error messages generated during processing. This job log should be reviewed if there are any problems
encountered while using the API.

Error Message Problem Solution


An FTPClient can only be The datatype of the object Ensure that a string value is provided
instantiated by passing in provided to identify which FTP containing the name of the FTP
either an FTP Connection Connection Info policy should be Connection Info policy to use when
Info policy’s name as a used to establish the connection instantiating a new FTPClient object.
string or a PolicyID object. was not a string.
Actual type given: TYPE
Policy with ID POLICY_ID is No FTP Connection Info policy Ensure that all of the FTP Connection
not a valid FTP Connection exists with the name that was Info policies specified in the script are
Info policy provided when instantiating a new defined within the Policy Editor.
FTPClient object.
No FTP connection with The specified FTP Connection Info Ensure that the FTP Connection Info
environment profile policy does not provide a policy includes a definition for all of
ENVIRONMENT_PROFILE in definition for the WorkForce Time the environments in which the script
policy POLICY_ID and Attendance environment that will be getting executed.
the script is running in.
Local file FILE_NAME A file with the same name as the Ensure that the file being copied
already exists. Either file being copied from the remote doesn’t already exist in the target
specify a new name for the server to the local server already directory, or set replaceExisting to
file to be transferred, or set exists in the target directory. true to allow the API to overwrite the
replaceExisting to true existing file.
Remote file FILE_NAME A file with the same name as the Ensure that the file being copied
already exists. Either file being copied from the local doesn’t already exist in the target
specify a new name for the server to the remote server directory, or set replaceExisting to
file to be transferred, or set already exists in the target true to allow the API to overwrite the
replaceExisting to true directory. existing file.
DIRECTORY is not a valid The directory specified when Ensure that the directory whose files
local directory, returning listing files in a directory does not should be listed actually exists.
empty array exist.
Cannot rename FILE_NAME The script attempted to rename a Ensure that no files already exist with
to NEW_NAME as a file file to a new name when there was the target name in the directory
with that name already already an existing file with that containing the file when performing a
exists new name. rename operation.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 225


WT&A API Specifications 18.3 FTP API

Cannot rename local file The script attempted to rename a Ensure that all files being renamed
that does not exist file on the local server that does exist.
(FILE_NAME) not exist.
Cannot rename remote file The script attempted to rename a Ensure that all files being renamed
that does not exist file on the remote server that does exist.
(FILE_NAME) not exist.
Cannot move local file The script attempted to move a file Ensure that all files being moved exist.
FILE_NAME. File does not on the local server that does not
exist exist.
Error moving local file. File The script attempted to move a file Ensure that no files already exist with
FILE_NAME in DIRECTORY on the local server to a new the target name in the directory the
cannot be moved to location when a file with the target file is to be moved to, or set
NEW_DIRECTORY with name already existed in that new replaceExisting to true to allow the
name NEW_NAME as the location. API to overwrite the existing file.
file already exists. Either
set replaceExisting = true
or choose a new
destination file name
Cannot move remote file The script attempted to move a file Ensure that all files being moved exist.
FILE_NAME. File does not on the remote server that does not
exist exist.
Error moving remote file. The script attempted to move a file Ensure that no files already exist with
File FILE_NAME in on the remote server to a new the target name in the directory the
DIRECTORY cannot be location when a file with the target file is to be moved to, or set
moved to NEW_DIRECTORY name already existed in that new replaceExisting to true to allow the
with name NEW_NAME as location. API to overwrite the existing file.
the file already exists.
Either set replaceExisting =
true or choose a new
destination file name
Table 46: FTP API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

FTPClient
FTPClient(ftpConnInfoPolicy)
Creates a new FTPClient instance, pointing at the FTP server defined by the specified FTP Connection Info
policy.

getFile(remoteDir, remoteFileName, localDir, localFileName, replaceExisting)


Copies a single file from the specified directory on the remote file server to the local server, storing it in the
indicated local directory and with the specified file name. If an existing file already exists in the specified
local directory with the indicated file name, this can either overwrite that existing file or generate an error
depending on the value provided for replaceExisting.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 226


WT&A API Specifications 18.3 FTP API

getFiles(remoteDir, filePatternOrArray, localDir, suffixToAdd, replaceExisting)


Copies any number of files from the specified directory on the remote file server to the local server, storing
them in the indicated local directory. The files to be copied can be specified as either an array of fixed file
names or as a regular expression matching the names of the files that should be copied. If a suffix string is
specified, that string will be automatically added to the end of the file names of the files created on the local
server (before the file extension). If any of the files being copied already exist, this can either overwrite those
existing files or generate an error depending on the value provided for replaceExisting.

putFile(localDir, localFileName, remoteDir, remoteFileName, replaceExisting)


Copies a single file from the specified directory on the local server to the remote file server, storing it in the
indicated remote directory and with the specified file name. If an existing file already exists in the specified
remote directory with the indicated file name, this can either overwrite that existing file or generate an error
depending on the value provided for replaceExisting.

putFiles(localDir, filePatternOrArray,remoteDir, suffixToAdd, replaceExisting)


Copies any number of files from the specified directory on the local server to the remote file server, storing
them in the indicated remote directory. The files to be copied can be specified as either an array of fixed file
names or as a regular expression matching the names of the files that should be copied. If a suffix string is
specified, that string will be automatically added to the end of the file names of the files created on the
remote file server (before the file extension). If any of the files being copied already exist, this can either
overwrite those existing files or generate an error depending on the value provided for replaceExisting.

listRemoteDirectory(remoteDir, filePattern, includeDirectories)


Returns an array containing the names of all of the files in the specified directory on the remote file server
that match the indicated regular expression. In addition to files, subdirectories in that location can also be
returned in the array if desired.

listLocalDirectory(localDir, filePattern, includeDirectories)


Returns an array containing the names of all of the files in the specified directory on the local server that
match the indicated regular expression. In addition to files, subdirectories in that location can also be
returned in the array if desired.

remoteFileExists(remoteDir, remoteFileName)
Determines whether or not a file of the specified name exists in the indicated directory on the remote file
server.

localFileExists(localDir, localFileName)
Determines whether or not a file of the specified name exists in the indicated directory on the local server.

renameLocalFile(localDir, localFileName, newFileName)


Renames a file on the local server to a specified new file name. Cannot be used to change the directory that
file is located in.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 227


WT&A API Specifications 18.3 FTP API

renameLocalFiles(localDir, filePatternOrArray, suffixToAdd)


Renames multiple files in the specified directory on the local server by appending a suffix string to the end of
the file names (before the file extension). The files to be renamed can be specified either by an array of fixed
file names or by a regular expression that matches the names of the files that should be renamed.

renameRemoteFile(remoteDir, remoteFileName, newFileName)


Renames a file on the remote file server to a specified new file name. Cannot be used to change the
directory that file is located in.

renameRemoteFiles(remoteDir, filePatternOrArray, suffixToAdd)


Renames multiple files in the specified directory on the remote file server by appending a suffix string to the
end of the file names (before the file extension). The files to be renamed can be specified either by an array
of fixed file names or by a regular expression that matches the names of the files that should be renamed.

moveLocalFile(sourceDir, fileName, destDir, newFileName, replaceExisting)


Moves the specified file on the local server to a new directory on the local server, optionally renaming it at
the same time. If a file already exists in the new directory with the final name of the file being moved, this
can either overwrite that existing file or generate an error depending on the value of replaceExisting.

moveLocalFiles(sourceDir, filePatternOrArray, destDir, suffixToAdd, replaceExisting)


Moves multiple files on the local server from the specified directory to a new target directory on the local
server, optionally adding a suffix to the end of the file names (before the file extension) at the same time.
The files to be moved can be specified either by an array of fixed file names or by a regular expression that
matches the names of the files to be moved. If any of the files being moved end up with the same name as a
file that already exists in the target directory, then this can either overwrite those existing files or generate an
error depending on the value of replaceExisting.

moveRemoteFile(sourceDir, fileName, destDir, newFileName, replaceExisting)


Moves the specified file on the remote file server to a new directory on the remote file server, optionally
renaming it at the same time. If a file already exists in the new directory with the final name of the file being
moved, this can either overwrite that existing file or generate an error depending on the value of
replaceExisting.

moveRemoteFiles(sourceDir, filePatternOrArray, destDir, suffixToAdd, replaceExisting)


Moves multiple files on the remote file server from the specified directory to a new target directory on the
remote file server, optionally adding a suffix to the end of the file names (before the file extension) at the
same time. The files to be moved can be specified either by an array of fixed file names or by a regular
expression that matches the names of the files to moved. If any of the files being moved end up with the
same name as a file that already exists in the target directory, then this can either overwrite those existing
files or generate an error depending on the value of replaceExisting.

copyLocalFile(sourceDir, fileName, destDir, destFileName, replaceExisting)


Creates a copy of the specified file on the local server in either the same directory or a new directory on the
local server, optionally renaming the copy at the same time. If a file already exists in the target directory with

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 228


WT&A API Specifications 18.3 FTP API

the final name of the file being copied, this can either overwrite that existing file or generate an error
depending on the value of replaceExisting.

copyLocalFiles(sourceDir, filePatternOrArray, destDir, suffixToAdd, replaceExisting)


Creates a copy of multiple files in the specified directory on the local server in either the same directory or a
new directory on the local server, optionally adding a suffix to the end of the file names on the copies (before
the file extension). The files to be copied can be specified either by an array of fixed file names or by a
regular expression that matches the names of the files to be copied. If any of the files being copied end up
with the same name as a file that already exists in the target directory, then this can either overwrite those
existing files or generate an error depending on the value of replaceExisting.

copyRemoteFile(sourceDir, fileName, destDir, destFileName, replaceExisting)


Creates a copy of the specified file on the remote file server in either the same directory or a new directory
on the remote file server, optionally renaming the copy at the same time. If a file already exists in the target
directory with the final name of the file being copied, this can either overwrite that existing file or generate
an error depending on the value of replaceExisting.

copyRemoteFiles(sourceDir, filePatternOrArray, destDir, suffixToAdd, replaceExisting)


Creates a copy of multiple files in the specified directory on the remote file server in either the same
directory or a new directory on the remote file server, optionally adding a suffix to the end of the file names
on the copies (before the file extension). The files to be copied can be specified either by an array of fixed
file names or by a regular expression that matches the names of the files to be copied. If any of the files
being copied end up with the same name as a file that already exists in the target directory, then this can
either overwrite those existing files or generate an error depending on the value of replaceExisting.

deleteRemoteFile(remoteDir, remoteFileName)
Deletes the specified file from the remote file server.

deleteRemoteFiles(remoteDir, filePatternOrArray, includeDirectories)


Deletes multiple files from the specified directory on the remote file server. The files to be deleted can be
specified either by an array of fixed file names or by a regular expression that matches the names of the files
to be deleted.

deleteLocalFile(localDir, localFileName)
Deletes the specified file from the local server.

deleteLocalFiles(localDir, filePatternOrArray, includeDirectories)


Deletes multiple files the specified directory on the local server. The files to be deleted can be specified
either by an array of fixed file names or by a regular expression that matches the names of the files to be
deleted.

createLocalDirectory(directoryPath)
Creates a new directory on the local server with the indicated name.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 229


WT&A API Specifications 18.3 FTP API

deleteLocalDirectory(directoryPath)
Deletes the directory with the specified name from the local server.

createRemoteDirectory(directoryPath)
Creates a new directory on the remote file server with the indicated name.

deleteRemoteDirectory(directoryPath)
Deletes the directory with the specified name from the remote file server.

setDebug(enableDebugging)
Specifies whether debug output should be written to the job log for actions performed by the API.

getHost()
Returns the host name specified in the FTP Connection Info policy used to instantiate this object.

getPort()
Returns the port number specified in the FTP Connection Info policy used to instantiate this object.

getUserID()
Returns the user ID specified in the FTP Connection Info policy used to instantiate this object.

getProtocolType()
Returns the protocol type—either FTP, SFTP, FTPS (implicit), or FTPS(explicit)—specified in the FTP
Connection Info policy used to instantiate this object.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 230


WT&A API Specifications 18.3 Generic Export API

Generic Export API


Overview and Capabilities
The Generic Export API provides a mechanism for filtering, formatting and exporting time_sheet_output
and/or bank_output_summary data. It is expected to be used as part of a Generic Export policy or a
scheduled custom script that needs to extract information from WorkForce Time and Attendance for a range
of dates. It places that data into a file or a database table, or transfers specified files to a remote server using
SFTP.
In terms of filtering, the Generic Export API can filter the data being exported by setting fields to blank or
zero (examples are provided in the Use Cases). The Generic Export API can also format the date and number,
according to the requirements. The API also provides the functionality to clear all the staging tables used by
the Generic Export Specification policy or any specific table using the option of sqlCriteria. The sqlCriteria
used to look up the desired data can be a simple, standalone condition:
(system_timestamp < (current_timestamp -1))
or can be combined to form a much more complicated condition:

(calc_string10 =? and calc_Date1 =?).


This gives script the flexibility to define whatever conditions are necessary to identify the desired data.
The Generic Export API also provides some utility methods such as rounding the number to a specified
precision or the nearest quarter, or to set the field with the generated ID value.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Background knowledge of Generic Export Specification/Section policy works for some of the functions of
API.

Components
This API consists of the following component(s):
1. The GENERIC_EXPORT_LIBRARY Distributed JavaScript library
2. The library also includes the FTP_LIBRARY Distributed JavaScript library, to perform the transfer
of files to a remote server using SFTP.
3. This library also includes the FILE_MANAGER_API Distributed JavaScript library, so that the data
can be written to file.

Setup
No setup is necessary for the Generic Export Library. The distributed library is automatically available within
WorkForce Time and Attendance.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 231


WT&A API Specifications 18.3 Generic Export API

Use Cases
Exporting Data to a File
The Generic Export Library allows a script to transfer the data from a specific table or the table identified by
the first Generic Export Section in the Generic Export Specification. Before exporting the records, the API also
allows you to do some basic formatting.
Following are the settings for exporting the record:
Property Name Required Description
fileName Y Name of the file to export the data to.
tableName Y Name of the table to export data from.
sqlCriteria N Additional SQL selection criteria.
singleRecordFunction N Function identifying processing to perform for each record in
the table
postProcessFunction N Function identifying processing to perform once all records
have been processed
encryptionAlias N String identifying which encryption key to use from the
database

Example 1: Exporting data from the table identified by the first Generic Export Section in the
Generic Export Specification
Following are the other API methods used in this example:

Method Name Description


exportRecord(record) Writes a single record to the export file, followed by a line
break
formatNumber(number, formatString) Converts the provided number into a target format
roundNumber(number, precision) Rounds a number to the specified precision
formatDate(dateString, Converts the provided date string into a target format
sourceFormatString,targetFormatString)
roundNumberToNearestQuarter(number) Rounds the specified number to the nearest quarter (i.e. 4.30
rounds to 4.25)
useCalcChangeSetForSpecifiedRange(flag) For exports run using a specified date range, defines whether
the export will use the calc change sets for the periods that
overlap with the date range or not.

The following script example demonstrates what the implementation might look like:
includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Set to true to use calc changes for the specified date range
exportAPI.useCalcChangeSetForSpecifiedRange(true);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 232


WT&A API Specifications 18.3 Generic Export API

//File Name with path to be exported


Var fileName = EXPORT_PATH+“AH_MONTHLY_ACCRUAL.csv”;

//Single Record Function


function processCurrentRecord(record) {
if (PRINT_HEADER) {
exportAPI.exportRecord(headerFields);
PRINT_HEADER = false;
}
TOTALS.recordsRead++;

var formattedRecord = getFormattedRecord(record);


exportAPI.exportRecord(formattedRecord);

TOTALS.recordCount++;
}

//Formatting each record to be exported


function getFormattedRecord(record) {
if (record.other_date1 == null || record.other_date2 == null || record.other_date3 == null
|| record.other_date4 == null || record.other_date5 == null || record.other_date6 == null) {
log.info("Null date(s) found for Employee ID " + record.DESCRIPTION);
}

var PRIM_JOB_IND = record.OTHER_STRING5 == 'T' ? 'P' : 'S';


var EST_GROSS = exportAPI.formatNumber(exportAPI.roundNumber(record.OTHER_NUMBER1, ROUND),
NUM_FMT);
var TL_QUANTITY = exportAPI.formatNumber(exportAPI.roundNumber(record.OTHER_NUMBER2, ROUND),
NUM_FMT);

TOTALS["EST_GROSS"] += parseFloat(EST_GROSS);
TOTALS["TL_QUANTITY"] += parseFloat(TL_QUANTITY);

return (H + DELIMITER +
record.DESCRIPTION + DELIMITER +
record.OTHER_STRING1 + DELIMITER +
record.OTHER_STRING2 + DELIMITER +
record.OTHER_STRING3 + DELIMITER +
record.OTHER_STRING4 + DELIMITER +
PRIM_JOB_IND + DELIMITER +
record.LD1 + DELIMITER +
record.LD8 + DELIMITER +
record.LD2 + DELIMITER +
record.LD5 + DELIMITER +
record.LD6 + DELIMITER +
record.LD4 + DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE1, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE2, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE3, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE4, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
OFF_CYCLE + DELIMITER +
SEQ_NBR + DELIMITER +

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 233


WT&A API Specifications 18.3 Generic Export API

RT_SOURCE + DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE5, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
exportAPI.formatDate("" + record.OTHER_DATE6, STD_DATE_FORMAT, EXPORT_DATE_FORMAT) +
DELIMITER +
record.OTHER_STRING6 + DELIMITER +
record.OTHER_STRING7 + DELIMITER +
AH_AMENDED_SEQ_NBR + DELIMITER +
EST_GROSS + DELIMITER +
CURRENCY_CD + DELIMITER +
TL_QUANTITY);
}

//Post Process Function


function writeSummaryRecord() {
var result = "T";
result += DELIMITER + TOTALS.recordCount;
result += DELIMITER + exportAPI.formatDate("" + today, STD_DATE_FORMAT, EXPORT_DATE_FORMAT);
result += DELIMITER + exportAPI.formatNumber(exportAPI.roundNumber(TOTALS.EST_GROSS, ROUND),
NUM_FMT);
result += DELIMITER +
exportAPI.formatNumber(exportAPI.roundNumberToNearestQuarter(TOTALS.TL_QUANTITY), NUM_FMT);

exportAPI.exportRecord(result);
}

//Calling API function to export data from the table identified by the first Generic Export
//Section in the Generic Export Specification
exportAPI.exportDataForSingleSourceTable(fileName, null, processCurrentRecord,
writeSummaryRecord, null);

Example 2: Exporting data from a specific table


The following script example demonstrates what the implementation might look like:
includeDistributedPolicy("GENERIC_EXPORT_LIBRARY");

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//File Name with path to be exported


Var fileName = EXPORT_PATH+”payroll_export.csv”;

//Sql Criteria
Var sqlCriteria = "CALC_BOOLEAN1 = 'F'";

//Table Name for export


Var tableName = "EXPORT_STAGE";

//Connection Object
var connection = new Connection();

//Single Record Function


function exportFunction(record) {
exportApi.exportRecord(
record.EMPLOYEE + "," + // Employee ID
record.CALC_STRING3 + "," + // Week Start Date
record.CALC_STRING4 + "," + // Week End Date

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 234


WT&A API Specifications 18.3 Generic Export API

record.EARNINGS_CODE + "," + // Earnings Code


formatNumber(record.HOURS) + "," + // Hours
formatNumber(record.AMOUNT) + "," + // Amount
record.CALC_STRING1 + "," + // Pay Group
record.CALC_STRING2 // Work State
);
}

//formatNumber called within the script


function formatNumber(value) {
var roundedValue = exportApi.roundNumber(value, 2);
return (roundedValue === 0 ? "" : roundedValue);
}

//Calling API function to export data from the table specified above
exportApi.exportDataFromTable(connection, tableName, fileName, sqlCriteria, exportFunction,
null, null);

Changing directory of the exported files


Generic Export Library allows to change the directory of the specified files. The following script demonstrates
what the implementation might look like:
includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Credentials for accessing the SFTP


var toyotaSftpCredentials = {
"server":"63.87.74.38",
"port":"22",
"user":"wfstap",
"passphrase":"",
"remoteDirectory":"incoming/",
"privateKeyPath":"../custom_files/id_rsa"
};

//File Path for changing the directory


var filePath = "interface/outgoing/TMS/TMS/";

//Files to move
var fileName = assignmentDescription + "_PAY_EXPORT_" + today + ".csv";
var totalsFileName = assignmentDescription + "_SUMMARY_TOTALS_" + today + ".csv";

.
.
.

exportAPI.sftpFilesWithKey(toyotaSftpCredentials, filePath, [fileName, totalsFileName]);

Using the Export Parameters for export


The API allows you to get export parameters that can be exported or can be used for the calculation.
The following example illustrates its usage:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 235


WT&A API Specifications 18.3 Generic Export API

//POST SUMMARY SCRIPT

includeDistributePolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Fetching the export parameters


var exportParms = exportAPI.getExportParms();
var dateRange = exportParms.specifiedDateRange;
var endDate = dateRange.getEnd();
var quarter = getQuarter(endDate);

function getQuarter(date) {
var month = date.getMonth();
//Follows USA government fiscal calendar and is one quarter ahead of the physical calendar
var quarter = "2";

if (month > 9) {
quarter = "1"
} else if (month > 6) {
quarter = "4"
} else if (month > 3) {
quarter = "3"
}

return quarter;
}

.
.

columnMap.put("CALC_STRING8", quarter);

Getting Export Data from all the tables using API


The API allows to get Data from the export tables and check whether it is defined or not. And If it is then use
those records to write to a file and when completed you can either clear that table or clear all the source
tables. Following are the other API methods used in this example:
Function Name Description
getTables() Identifies all the tables that will be written to by this Generic Export
Specification
isObjectDefined(object) Returns false if the specified object is null or undefined, otherwise true

The following example illustrates the usage:


includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Array of tables that will be written by the Generic Export Specification


Var tableNames = exportAPI.getTables();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 236


WT&A API Specifications 18.3 Generic Export API

//Export Data stored


Var exportData;

//SQL Criteria
Var sqlCriteria = "CALC_BOOLEAN1 = 'F'";

//Connection for the function


Var connection = new Connection();

for(var singleTableName in tableNames) {

//Getting data from each table


exportData = exportAPI.getExportData(connection, singleTableName, sqlCriteria);

if(exportAPI.isObjectDefined(exportData)){
//DO SOMETHING THE DATA OF THE TABLE i.e. write it to a file
}
}

Removing existing data from the tables


The Generic Export Library allows to delete the existing data from specified/all table(s) being written to by
this export.

Example 1: Clear all existing data from the tables being written to by this export

includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Delete data from all the tables


exportAPI.clearAllSourceTables();

Example 2: Delete data from specific table

includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for specification


Var exportAPI = new GenericExportSpecAPI();

//Array of tables that will be written by the Generic Export Specification


Var tableNames = exportAPI.getTables();

//Connection for the function


Var connection = new Connection();

//SQL Criteria
Var sqlCriteria = “”;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 237


WT&A API Specifications 18.3 Generic Export API

//Delete from the first table


exportAPI.clearTable(connection, tableNames[0], sqlCriteria);

Filter and stop the record from export when specified Field is zero or blank
API stops the record form being exported automatically when the specified field is zero or blank.
includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for section


Var exportAPI = new GenericExportSectionAPI(this);

//Fields to look for


Var blankField = “WAGETYPE”;
Var zeroField = “NO_OF_HOURS”;

//stops the current record if specified field is blank


exportAPI.filterWhenFieldIsBlank(blankField);

//stops the current record if specified field constains a zero value


exportAPI.filterWhenFieldIsZero(zeroField);

Filter when specified Filed is zero or blank


API doesn’t stop the record from being exported if the specified field is zero or blank, it only returns a
Boolean.
includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for section


Var exportAPI = new GenericExportSectionAPI(this);

//Fields to look for


Var blankField = “WAGETYPE”;
Var zeroField = “NO_OF_HOURS”;

//Determine if the specified field is blank then put empty string in place of that
if(exportAPI.fieldIsBlank(blankField)) {
columnMap.put(“Reg Hours”,””);
}

//Determine if the specified field is zero then put empty string in place of that
if(exportAPI.fieldIsZero(zeroField)) {
columnMap.put(“Hours 3 Amount”,””);
}

Filter when All Fields are zero or blank


includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for section


Var exportAPI = new GenericExportSectionAPI(this);

//Fields to look for


Var blankField = ["EARNINGS_CODE", "CALC_STRING1"];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 238


WT&A API Specifications 18.3 Generic Export API

Var zeroField = ["AMOUNT", "CALC_VALUE1"];

exportAPI.filterWhenAllFieldsAreBlank(blankField);
exportAPI.filterWhenAllFieldsAreZero(zeroField);

Filter when Any Field is zero or blank


includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for section


Var exportAPI = new GenericExportSectionAPI(this);

//Fields to look for


Var blankField = ["EARNINGS_CODE", "CALC_STRING1"];
Var zeroField = ["AMOUNT", "CALC_VALUE1"];

exportAPI.filterWhenAnyFieldsAreBlank(blankField);
exportAPI.filterWhenAnyFieldsAreZero(zeroField);

Set a field value to a Generated Value


includeDistributedPolicy(“GENERIC_EXPORT_LIBRARY”);

//Create an Instance of API for section


Var exportAPI = new GenericExportSectionAPI(this);

//Using the setFieldGID method to set the generated id for the field
exportAPI.setFieldGID(“SYSTEM_RECORD_ID”);

Troubleshooting
The job log of the script using the Generic Export Library will contain information messages and, in the case
of problems, any error messages generated during processing. This job log should be reviewed if there are
any problems encountered while using the API.
Error Message Problem Solution
No destination tables defined There is no Destination table You need to define the destination
for Generic Export Sections. defined in Generic Export table if this export is going to write
Unable to export data Specification-> Sections, while to a DB table.
configuring the policy
No Writer is defined No writer object is defined You must call
before exporting the record exportDataFromTable(…) or
exportDataForSingleSourceTable(…)
before calling the
exportRecord(record) function,
because either of those two
function will eventually initialize
the writer object.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 239


WT&A API Specifications 18.3 Generic Export API

API Reference
GenericExportSpecAPI:
The GenericExportSpecAPI has the following methods available:

useCalcChangeSetForSpecifiedRange(useCCS)
For exports run using a specified date range, defines whether the export will use the calc change sets for the
periods that overlap with the date range or not, for which useCCS (Boolean) value is passed.

clearAllSourceTables()
Clears all existing data from the tables being written to by this export.

clearTable(connection, tableName, sqlCriteria)


Truncates the data from the specified table name using the connection (optional; if not provided, will create
its own connection to the local DB) to communicate with database, with provided SQL criteria(optional).

getTables()
Returns the name of tables that will be written to by this Generic Export Specification.

exportDataForSingleSourceTable(exportFileName, sqlCriteria, singleRecordFunction,


postProcessFunction, encryptionAlias)
Exports the data to the file name provided with the encryptionAlias(optional), from the table identified by
the first Generic Export section in the Generic Export Specification with some SQL criteria(optional), using the
singleRecordFunction(optional) for identifying the processing to perform for each record. You can also do
some processing once all the records have been processed using the postProcessFunction(optional).

exportDataFromTable(connection, tableName, exportFileName, sqlCriteria,


singleRecordFunction, postProcessFunction, encryptionAlias)
Exports the data to the file name provided with the encryptionAlias(optional), from the specified table name
with connection (optional; if not provided, will create its own connection to the local DB) and SQL
criteria(optional), using the singleRecordFunction(optional) for identifying the processing to perform for each
record. You can also do some processing once all the records have been processed using the
postProcessFunction(optional).

getExportData(connection, tableName, sqlCriteria)


Returns the records to be exported from the specified table name using the connection (optional; if not
provided, will create its own connection to the local DB) to communicate with database, with provided SQL
criteria(optional).

exportRecord(record)
Writes a single record to the export file, followed by the line break.

sftpFilesWithKey(credentials, filePath, fileNames)


Transfers all the specified files to the file path provided, using SFTP credentials.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 240


WT&A API Specifications 18.3 Generic Export API

formatDate(dateStr, sourceFormatStr, targetFormatStr)


Converts the provided date string from source format string to a targeted format string.

formatNumber(number, formatStr)
Converts the provided number into a target format.

roundNumberToNearestQuarter(number)
Rounds the specified number to the nearest quarter (i.e. 4.30 rounds to 4.25).

roundNumber(number, precision)
Rounds a number to specified precision.

getExportParms()
Returns the export parameters associated with this particular export job.

isObjectDefined(object)
Returns false if the specified object is null or undefined, true otherwise.

GenericExportSectionAPI:
The GenericExportSectionAPI has the following methods available:

setFieldGID(fieldName)
Used to set a field in the Generic Export Section to a new Generated ID value.

filterWhenFieldIsBlank(field)
Stops the current record from being exported if the specified field is blank.

filterWhenFieldIsZero(field)
Stops the current record from being exported if the specified field contains a zero value.

filterWhenAnyFieldsAreBlank(fields)
Stops the current record from being exported if any of the specified fields do not contain data.

filterWhenAnyFieldsAreZero(fields)
Stops the current record from being exported if any of the specified fields contains a zero value.

filterWhenAllFieldsAreBlank(fields)
Stops the current record from being exported if all the specified fields do not contain values.

filterWhenAllFieldsAreZero(fields)
Stops the current record from being exported if all the specified fields contain a zero value.

fieldIsBlank(field)
Determines if the specified field is empty.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 241


WT&A API Specifications 18.3 Generic Export API

fieldIsZero(field)
Determines if the specified field contains a zero value.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 242


WT&A API Specifications 18.3 Incremental Export API

Incremental Export API


Overview and Capabilities
The Incremental Export API is used in exporting incremental changes to TIME_SHEET_OUTPUT,
TIME_SHEET_DETAIL, and SCHEDULE_DETAIL data. This API enables detection of data changes since the
previous export, and exports new addition or deletion records to reflect those changes.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
1. The INCREMENTAL_EXPORT_API Distributed JavaScript library.
• This automatically includes the API_UTIL Distributed JavaScript Library.
2. The MatchCondition, which defines a condition to select assignments.
3. Parms, which is a JS object containing parameters used for initializing the API. Expected properties
include the following:
• exportTarget {String} Unique name for export process. Used to differentiate between
multiple incremental exports.
• enableDebugLogging {Boolean} Set to true if debug logging should be generated; otherwise
false. Defaults to false.
• exportType {String} Determines the type of the export. TIME_SHEET_DETAIL,
SCHEDULE_DETAIL, and TIME_SHEET_OUTPUT are valid values. Defaults to
TIME_SHEET_OUTPUT.

Setup
No setup is necessary for the Incremental Export API. The distributed library is automatically available within
WT&A.

Use Cases
Computing the Differences in TIME_SHEET_OUTPUT,
TIME_SHEET_DETAIL, and SCHEDULE_DETAIL Against an Assignment
Example 1: Computing differences in TIME_SHEET_OUPUT against an assignment
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 243


WT&A API Specifications 18.3 Incremental Export API

startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]

};
var api = new IncrementalExportAPI(apiParms);
api.computeDifferences(condition, differencesParms);

Example 2: Computing differences in TIME_SHEET_DETAIL against an assignment


includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999)
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]

};
var api = new IncrementalExportAPI(apiParms);
api.computeDifferences(condition, differencesParms);

Example 3: Computing differences in SCHEDULE_DETAIL against an assignment


includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999)
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 244


WT&A API Specifications 18.3 Incremental Export API

};
var api = new IncrementalExportAPI(apiParms);
api.computeDifferences(condition, differencesParms);

Example 4: Considering specific fields for computing differences in TIME_SHEET_OUPUT


against an assignment
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘HOURS’]

};
var api = new IncrementalExportAPI(apiParms);
api.computeDifferences(condition, differencesParms);

Example 5: Considering specific fields for computing differences in TIME_SHEET_DETAIL


against an assignment
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘HOURS’]

};
var api = new IncrementalExportAPI(apiParms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 245


WT&A API Specifications 18.3 Incremental Export API

api.computeDifferences(condition, differencesParms);

Example 6: Considering specific fields for computing differences in SCHEDULE_DETAIL


against an assignment
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘HOURS’]

};
var api = new IncrementalExportAPI(apiParms);
api.computeDifferences(condition, differencesParms);

Computing the Differences in TIME_SHEET_OUTPUT,


TIME_SHEET_DETAIL, and SCHEDULE_DETAIL Against All Assignments in
a Specific Assignment Group
Example 1: Computing differences in TIME_SHEET_OUPUT against all assignments in an
Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 246


WT&A API Specifications 18.3 Incremental Export API

api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Example 2: Computing differences in TIME_SHEET_DETAIL against all assignments in an


Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;
api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Example 3: Computing differences in SCHEDULE_DETAIL against all assignments in an


Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;
api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Example 4: Considering specific fields for computing differences in


TIME_SHEET_OUTPUT against all assignments in Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 247


WT&A API Specifications 18.3 Incremental Export API

};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘pay_code’]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;
api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Example 5: Considering specific fields for computing differences in TIME_SHEET_DETAIL


against all assignments in Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘pay_code’]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;
api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Example 6: Considering specific fields for computing differences in SCHEDULE_DETAIL


against all assignments in Assignment Group
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = { exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 248


WT&A API Specifications 18.3 Incremental Export API

startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"],
diffSpecificFields: true,
fieldNames: [‘pay_code’]
};
var api = new IncrementalExportAPI(apiParms);
var assignmentGroup = ‘1038645186’;
api.computeDifferencesForGroup(assignmentGroup, differencesParms);

Getting the Collection of Differences That Were Calculated by the


Specified Export Batch
Example 1: Getting the collection of differences in TIME_SHEET_OUTPUT that were
calculated by the specified export batch
batchincludeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportDetails = api.getExportDetails(batchId, parms);

Example 2: Getting the collection of differences in TIME_SHEET_DETAIL that were


calculated by the specified export batch
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 249


WT&A API Specifications 18.3 Incremental Export API

exportType: "TIME_SHEET_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportDetails = api.getExportDetails(batchId, parms);

Example 3: Getting the collection of differences in SCHEDULE_DETAIL that were


calculated by the specified export batch
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL"
};
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportDetails = api.getExportDetails(batchId, parms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 250


WT&A API Specifications 18.3 Incremental Export API

Getting the Details About the Specified Incremental Export Operation


Example 1: Getting the details about the specified TIME_SHEET_OUTPUT incremental
export operation
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.getExportProperties(batchId);

Example 2: Getting the details about the specified TIME_SHEET_DETAIL incremental


export operation
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.getExportProperties(batchId);

Example 3: Getting the details about the specified SCHEDULE_DETAIL incremental


export operation
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 251


WT&A API Specifications 18.3 Incremental Export API

exportType: "SCHEDULE_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.getExportProperties(batchId);

Rolling Back All the Differences Computed by Runs of This Export


Example 1: Rolling back all the differences in TIME_SHEET_OUTPUT computed by runs of
this export
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.rollbackExport(batchId);

Example 2: Rolling back all the differences in TIME_SHEET_DETAIL computed by runs of


this export
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 252


WT&A API Specifications 18.3 Incremental Export API

gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.rollbackExport(batchId);

Example 3: Rolling back all the differences in SCHEDULE_DETAIL computed by runs of


this export
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
api.rollbackExport(batchId);

Rolling Back a Single Record Computed by Runs of This Export


Example 1: Rolling back a single record computed by runs of this export for
TIME_SHEET_OUTPUT
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
negateNumericFields: true,
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 253


WT&A API Specifications 18.3 Incremental Export API

orderFields: ["ID", "TIME_OFF_DATE"]


};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportRecords = api.getExportDetails(batchId, parms);
for (var I in exportRecords){
record = exportRecords[i];
api.rollbackRecord(record);
}

Example 2: Rolling back a single record computed by runs of this export for
TIME_SHEET_DETAIL
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "TIME_SHEET_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,
logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportRecords = api.getExportDetails(batchId, parms);
for (var I in exportRecords){
record = exportRecords[i];
api.rollbackRecord(record);
}

Example 3: Rolling back a single record computed by runs of this export for
SCHEDULE_DETAIL
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var apiParms = {
exportTarget: "Clarity Incremental Export",
enableDebugLogging: false,
exportType: "SCHEDULE_DETAIL" };
var condition = new MatchCondition("ASGNMT", "OTHER_STRING14", MatchOperator.EQUALS, "DIV17");
var differencesParms = {
startDate: WFSDate.today().addDays(-30),
endDate: WFSDate.today().addDays(999),
retractOnTerm: true,
priorPeriodMode: "PRIOR_PERIOD_ON_CHANGE",
gracePeriod: 1440,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 254


WT&A API Specifications 18.3 Incremental Export API

logData: true,
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var parms = {
filter: function(record) { return (inArray(["REG","SICK"],record.pay_code)); },
orderFields: ["ID", "TIME_OFF_DATE"]
};
var api = new IncrementalExportAPI(apiParms);
var batchId = api.computeDifferences(condition, differencesParms);
var exportRecords = api.getExportDetails(batchId, parms);
for (var I in exportRecords){
record = exportRecords[i];
api.rollbackRecord(record);
}

Performing Aggregate Operations on computedDifferences


Example 1: Performing aggregate operations on computedDifferences for
TIME_SHEET_OUTPUT
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var condition = new MatchCondition("ASGNMT", "ASGNMT", MatchOperator.EQUALS, "528312");
condition.and(new MatchCondition("ASGNMT", "LD8", MatchOperator.EQUALS,
"INT_137_A1_NewHire"));

var parms = {
startDate: WFSDate.VERY_EARLY_DATE,
endDate: WFSDate.VERY_LATE_DATE,
personSelectionDateOption: Person_selection_date_option.BEGINNING_OF_CURRENT_PERIOD
};
var exportId = api.computeDifferences(condition, parms);

// aggregations will be an array of IncrementalExportAggregationScriptables


var aggregations = api.getExportAggregations(exportId, ['hours'], ['pay_code']);

Example 2: Performing aggregate operations on computedDifferences for


TIME_SHEET_DETAIL
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var condition = new MatchCondition("ASGNMT", "ASGNMT", MatchOperator.EQUALS, "528312");
condition.and(new MatchCondition("ASGNMT", "LD8", MatchOperator.EQUALS,
"INT_137_A1_NewHire"));

var parms = {
startDate: WFSDate.VERY_EARLY_DATE,
endDate: WFSDate.VERY_LATE_DATE,
personSelectionDateOption: Person_selection_date_option.BEGINNING_OF_CURRENT_PERIOD,
exportType: "TIME_SHEET_DETAIL"
};
var exportId = api.computeDifferences(condition, parms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 255


WT&A API Specifications 18.3 Incremental Export API

// aggregations will be an array of IncrementalExportAggregationScriptables


var aggregations = api.getExportAggregations(exportId, ['hours'], ['pay_code']);

Example 3: Performing aggregate operations on computedDifferences for


SCHEDULE_DETAIL
includeDistributedPolicy("INCREMENTAL_EXPORT_API");
var condition = new MatchCondition("ASGNMT", "ASGNMT", MatchOperator.EQUALS, "528312");
condition.and(new MatchCondition("ASGNMT", "LD8", MatchOperator.EQUALS,
"INT_137_A1_NewHire"));

var parms = {
startDate: WFSDate.VERY_EARLY_DATE,
endDate: WFSDate.VERY_LATE_DATE,
personSelectionDateOption: Person_selection_date_option.BEGINNING_OF_CURRENT_PERIOD,
exportType: "SCHEDULE_DETAIL"
};
var exportId = api.computeDifferences(condition, parms);

// aggregations will be an array of IncrementalExportAggregationScriptables


var aggregations = api.getExportAggregations(exportId, ['hours'], ['pay_code']);

Troubleshooting
The job log of the script using the File Manager API will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
Some common error messages, their causes, and the solution:
Error Message Problem Solution
No value specified for Not specifying any parameters Ensure that IncrementalExportAPI() is
export target should have failed the API called with the specified parms.
initialization due to a missing export
target.
Specifying parameters without an Ensure that parms being passed in the
export target should have failed the IncrementalExporAPI() must contain an
API initialization. export target.
Invalid export type Specifying parameters with an Valid values for export type are
BAD_CHOICE_VALUE invalid export type should have TIME_SHEET_OUTPUT,
specified failed the API initialization TIME_SHEET_DETAIL, and
SCHEDULE_DETAIL
No value specified for Not specifying any parameters computeDifferences should be called
export start date when computing difference should with two parameters.
have generated an error due to a 1) matchCondition
missing start date. 2) parms – JS object

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 256


WT&A API Specifications 18.3 Incremental Export API

Not specifying any parameters The Parms (JS object) must contain a
when computing difference should start date.
have generated an error due to a
missing start date.

No value specified for End date is a required field in the Ensure that Parms should contain a
export end date parameters and was not specified. specified end date.

Incremental Export start End date is not allowed to be before Ensure that start date is less than end
date yyyy-MM-dd is after start date. date.
end date yyyy-MM-dd

Value ‘X’ is not a valid value Invalid values are not allowed for The priorPeriodMode property must
for choice the prior period mode choice. contain a valid value.

Negative numbers not Negative values are not allowed for The gracePeriod property in parms
allowed for grace period the grace period. must not contain a negative value.

Incremental export filter Filter function does not return a The filter property in parms is a
function returned result null value that is not allowed. function which should return a value.

Incremental export filter Filter function that returns a non- Filter function should return a Boolean
function returned result 5, Boolean value is not allowed. value (True or False).
of type class

Invalid ordering field Order field array containing invalid Order field array should contain a valid
BAD_FIELD specified, Field field names is not allowed. field name.
does not exist in
INCR_EXP_HIST_DETAIL,
TIME_SHEET_DETAIL_HIST,
SCHEDULE_DETAIL_HIST

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 257


WT&A API Specifications 18.3 Incremental Export API

Invalid ordering field Order field array containing good Order field array should contain a valid
NONEXISTEND_FIELD and bad field names is not allowed. field name.
specified. Field does not
exist in
INCR_EXP_HIST_DETAIL,
TIME_SHEET_DETAIL_HIST,
SCHEDULE_DETAIL_HIST
Invalid ordering field Order field array containing data Order field array should contain a data
C_CALC_STRING2 specified element not linked to IEHD, TSDH, element linked to IEHD, TSDH, SDH.
Field does not exist in SDH is not allowed.
INCR_EXP_HIST_DETAIL,
TIME_SHEET_DETAIL_HIST,
SCHEDULE_DETAIL_HIST
Incorrect field name: The field name provided in the Provide the correct table name.
PAY_STRING specified for parameter doesn’t map to the
the difference. Field does actual column of
not exist in TIME_SHEET_OUTPUT,
TIME_SHEET_OUTPUT, TIME_SHEET_DETAIL,
TIME_SHEET_DETAIL, SCHEDULE_DETAIL table.
SCHEDULE_DETAIL

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Incremental Export API consists of the following component(s):
1. The MatchCondition, which defines a condition to select employee, assignment, or user records
a. This MatchCondition makes use of a MatchOperator which defines a comparison operation
to use in a condition for matching a specified value against the assignment.
2. The IncrementalExportAPI, which provides assorted methods to export incremental changes to
TIME_SHEET_OUTPUT, TIME_SHEET_DETAIL, and SCHEDULE_DETIAL data.

MatchOperator
EQUALS
Only data where the value in the specified field exactly matches the indicated value will be matched by the
condition.

NOT_EQUALS
Only data where the value in the specified field does not match the indicated value will be matched by the
condition.

GREATER_THAN
Only data where the value in the specified field is greater than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “3” is greater than “20”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 258


WT&A API Specifications 18.3 Incremental Export API

GREATER_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is greater than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “3” is greater than
“20”.

LESS_THAN
Only data where the value in the specified field is less than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “20” is less than “3”.

LESS_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is less than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “20” is less than
“3”.

IN
Only data where the value in the specified field exactly matches one of the values in the indicated array of
values will be matched by the condition.

NOT_IN
Only data where the value in the specified field does not match any of the values in the indicated array of
values will be matched by the condition.

LIKE
Only data where the value in the specified field matches the pattern defined by the indicated value will be
matched by the condition.

NOT_LIKE
Only data where the value in the specified field does not match the pattern defined by the indicated value
will be matched by the condition.

BETWEEN
Only data where the value in the specified falls between the two values defined by the indicated array of
values (inclusive of the two endpoints) will be matched by the condition. For string fields this is applied
lexicographically, meaning that “5” is between “37” and “62”.

MatchCondition
MatchCondition(table, field, operator, values, isNotOperator)
Creates a new MatchCondition for the indicated table/field combination that matches against the specified
value(s) using the indicated MatchOperator.
If the MatchOperator specified is IN or NOT_IN, then values is expected to be an array of all the different
values to be evaluated by the “in” operation. If the MatchOperator specified is BETWEEN, then values is
expected to be an array containing two values: the starting point and ending point of the range to be
evaluated by the “between” operation. For all other MatchOperators, values is expected to be a single
value.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 259


WT&A API Specifications 18.3 Incremental Export API

The isNotOperator controls whether the results of the MatchCondition should be negated. If this is set to
true, then a MatchCondition that normally evaluates to false will instead evaluate to true, and a
MatchCondition that normally evaluates to true will instead evaluate to false. This allows for conditions that
don’t have an explicit MatchOperator defined, such as “not between”, to be defined.

and(condition)
Modifies the MatchCondition to return only the intersection of its original condition and the specified
condition.

or(condition)
Modifies the MatchCondition to return the union of its original condition and the specified condition.

IncrementalExportAPI
IncrementalExportAPI(parms)
Creates a new instance of the Incremental Export API, using the provided settings. The available parameters
that can be defined are:
Parameter Description
exportTarget Unique name for the export process. Used to differentiate between multiple
incremental exports a customer may have so that changes calculated in one export
do not impact the changes calculated by a different export.
True if debug logging should be generated, false if not. Defaults to false.
enableDebugLogging

Determines type of the export. TIME_SHEET_DETAIL, SCHEDULE_DETAIL, and


exportType
TIME_SHEET_OUTPUT are valid values. Defaults to TIME_SHEET_OUTPUT.

computeDifferences(matchCondition, parms)
Computes the differences in TIME_SHEET_OUTPUT, TIME_SHEET_DETAIL and SCHEDULE_DETAIL since the
last time this export was run for all assignment that match the provided condition, returning the batch ID for
the process that computed the differences. The available parameters that can be defined are as follows:
Parameter Description
startDate Starting date of the range that should be evaluated by the export.

Ending date of the range that should be evaluated by the export.


endDate

Should output fields (hours, amounts, etc.) be negated on reversal. Defaults to


negativeNumericFields
false. This field applies only to TIME_SHEET_OUTPUT.
Should previously-exported time be retracted following a termination.
retractOntTerm
Defaults to true.
Defines when prior-period time should be included in the export. Defaults to
priorPeriodMode
PRIOR_PERIOD_ON_CHANGE.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 260


WT&A API Specifications 18.3 Incremental Export API

Time in minutes before the previous export run time to use when checking for
gracePeriod
timesheet modification. Defaults to 1440.
Indicates if information about the differences being computed should be
logData
written to the job log. Defaults to true.
Indicates what dates to filter the person on.
personSelectionDateOption

Indicates if the difference will be restricted to specific fields, defaults to false.


diffSpecificFields

Name of fields that should be only considered for the export.


fieldNames

computeDifferencesForGroup(groupId, parms)
Computes the differences in TIME_SHEET_OUTPUT, TIME_SHEET_DETAIL, and SCHEDULE_DETAIL since the
last time this export was run for all assignments present in the specified assignment group, returning the
batch ID for the process that computed the differences. The available parameters that can be defined are as
follows:
Parameter Description
startDate Starting date of the range that should be evaluated by the export.

Ending date of the range that should be evaluated by the export.


endDate

Should output fields (hours, amounts, etc.) be negated on reversal. Defaults to


negativeNumericFields
false. This field applies only to TIME_SHEET_OUTPUT.
Should previously-exported time be retracted following a termination.
retractOntTerm
Defaults to true.
Defines when prior-period time should be included in the export. Defaults to
priorPeriodMode
PRIOR_PERIOD_ON_CHANGE.
Time in minutes before the previous export run time to use when checking for
gracePeriod
timesheet modification. Defaults to 1440.
Indicates if information about the differences being computed should be
logData
written to the job log. Defaults to true.
Indicates what dates to filter the person on.
personSelectionDateOption

Indicates if the difference will be restricted to specific fields, defaults to false.


diffSpecificFields

Name of fields that should be only considered for the export.


fieldNames

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 261


WT&A API Specifications 18.3 Incremental Export API

getExportProperties(batchId)
Returns the details about the incremental export operation specified by batch ID.

getExportDetails(batchId, parms)
Returns the collection of differences that were calculated by the specified export batch. The available
parameters that can be defined are as follows:
Parameter Description
filter Function that accepts a single argument (of type
IncrExportHistoryDetailScriptable) and returns a Boolean value; true if the
record should be kept, false if it should be filtered out.
Array of fields on the INCR_EXP_HIST_DETAIL, TIME_SHEET_DETAIL_HIST, and
SCHEDULE_DETIAL_HIST (for TIME_SHEET_OUTPUT, TIME_SHEET_DETAIL, and
orderFields
SCHEDULE_DETAIL, respectively) records that should be used for ordering the
results.

rollbackExport(batchId)
Undoes all the differences computed by runs of this export after and including the specified batch ID,
allowing these records to be exported again as though they had never been exported previously.

rollbackRecord(record)
Removes the differences associated with a single record, so that its source record can be exported again in a
future export. This would be used if a single record has an error that should stop it from being exported, so
that the next run of the export picks up that same change again (presumably after the issue that caused the
error has been fixed).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 262


WT&A API Specifications 18.3 Instance Info API

Instance Info API


Overview and Capabilities
The Instance Info API provides a set of utility functions that can be used to determine information about the
specific instance of WorkForce Time and Attendance that is executing a script. This includes determining
information about the database the instance is using, the files and file directories that are available to the
instance, and reading values from the config.xml and custom_config.xml files.
None of the methods exposed by the Instance Info API will modify the instance in any way, but they can be
used as part of larger script logic to conditionally change the way the script behaves depending on the
environment it’s running in.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The distributed JavaScript library policy INSTANCE_INFO_API

Setup
No setup is necessary for the Instance Info API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Reading Configuration Properties
The Instance Info API can be used to read settings from the config.xml file from within a script. These
settings correspond to the configuration properties that were defined for the instance in the build.properties
file, plus any defaults for properties that weren’t set explicitly. Some examples of uses for this information
would be for determining which environment (Prod, Test, Dev, etc.) the script is running in, or for checking
whether the script is running on an instance with the Scheduler enabled or not.
The following script example demonstrates reading configuration properties using the Instance Info API:

Example 1: Reading standard configuration properties


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Determine which environment the script is running in


var environment = api.getBuildProperty("ENVIRONMENT");

if (environment == "PROD") {
log.info("Script is running in the Production environment");
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 263


WT&A API Specifications 18.3 Instance Info API

else {
log.info("Script is not running in the Production environment");
}

// Determine if the scheduler is enabled


var schedulerEnabled = (api.getBuildProperty("SCHEDULER_RUN") == "true");

if (schedulerEnabled) {
log.info("Scheduler is enabled for this instance");
}
else {
log.info("Scheduler is not enabled for this instance");
}

Note: Only select standard configuration properties can be looked up using the Instance Info API. This is
because the rest of the information contained in those properties should not be used by scripts, and
could potentially lead to dangerous behavior or security risks.

In addition to reading the standard configuration properties, which will exist for every instance, the Instance
Info API can also be used to read custom configuration properties. These properties, defined in
custom_config.xml, allow additional customer-specific information to be associated with the instance. Some
examples of uses for this might include storing database connection information, web service end points, or
file transfer credentials.

Note: Custom configuration properties should not be used in place of environment-specific policy settings or
where the environment-specific script in the Environment policy can be used. Those options will be
much less prone to breaking when switching between environments or when upgrading.

The following script example demonstrates using the Instance Info API to read custom configuration
properties. It assumes that custom_config.xml defines a property called “EXTERNAL_CONNECTION_INFO”,
with sub-properties “USERNAME”, “PASSWORD”, “URL”, and “DRIVER”:

Example 2: Reading custom configuration properties


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Read the custom connection information from custom_config.xml


var userName = api.getBuildProperty("EXTERNAL_CONNECTION_INFO.USERNAME");
var password = api.getBuildProperty("EXTERNAL_CONNECTION_INFO.PASSWORD");
var url = api.getBuildProperty("EXTERNAL_CONNECTION_INFO.URL");
var driver = api.getBuildProperty("EXTERNAL_CONNECTION_INFO.DRIVER");

// Use the information to create a connection and process data


var connection = createConnection(userName, password, url, driver);

// Additional script logic to process data goes here

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 264


WT&A API Specifications 18.3 Instance Info API

Determining the Current Version of WorkForce Time and Attendance


The Instance Info API has the ability to identify which version of WorkForce Time and Attendance the script is
being executed on. This can be useful when building a script that needs to behave differently in different
versions (such as a library script that needs to populate an additional field in more recent versions but where
that field doesn’t exist in older versions). This helps facilitate custom scripts that work seamlessly across
upgrades.
The following script example demonstrates getting the current version and conditionally executing one of
two different code paths based on whether the version is v16.1.0.2 or later:

Example: Determining the Current Version of WorkForce Time and Attendance


includeDistributedPolicy("INSTANCE_INFO_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Read the current version of WorkForce Time and Attendance


var version = api.getVersion();

if (versionIsSameOrLaterThan(version, "16.1.0.2") ) {
// Execute code that applies to v16.1.0.2 and later
}
else {
// Execute code that applies to v16.1.0.1 and earlier
}

// Function that correctly evaluates two version strings to determine if the


// specified version is the same or later than a target version
function versionIsSameOrLaterThan(version, targetVersion) {
// Turn the versions into arrays by splitting on the separators
var versionArray = version.split(".");
var targetVersionArray = targetVersion.split(".");

// Iterate over the components in the arrays.


var numberOfComponents = max(versionArray.length, targetVersionArray.length);
for (var i = 0; i < numberOfComponents; ++i) {
// If one of the arrays doesn't have a component at this level, assume the
// component at this level is 0
var versionComponent = parseInt(versionArray[i], 10) || 0;
var targetComponent = parseInt(targetVersionArray[i], 10) || 0;

// If the component is greater than the target component, we know that the
// version as a whole is later than the target version
if (versionComponent > targetComponent) {
return true;
}
// If the component is less than the target component, we know that the
// version as a whole is earlier than the target version
if (versionComponent < targetComponent) {
return false;
}

// Both components are equal, so we need to move on to evaluating the next

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 265


WT&A API Specifications 18.3 Instance Info API

// component
}

// All components were the same, so the version is the same as the target version
return true;
}

Note: Never compare version strings directly, as strings. String comparisons compare values lexicographically,
meaning that “16.1.0.2” would be less than “7.8.0.5”.

Finding Files in a Directory


Often times a script may need to access information about all files in a given directory, rather than just a
specific file. One common scenario where this comes up is when the customer is writing time-stamped files
to a directory, and the script needs to process either all of those files or just the most recent file to have been
written. The Instance Info API includes a couple of methods to help facilitate this sort of operation.
The simplest case to deal with is when there is a dedicated directory for the files, and the script just needs to
grab every file that exists in that directory. The following script example demonstrates how the Instance Info
API can be used to retrieve every file in a specified directory:

Example 1: Finding all files in a directory


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Define the directory containing the files to be processed


var directory = "interface/incoming/dataFiles/";

// Get all of the files in the directory


var files = api.getFilesInDirectory(directory);

// Iterate over the files and process them as desired


for (var i = 0; i < files.length; ++i) {
var file = files[i];

// Process the file as needed


log.info("Processing file " + file.getName() );
}

Sometimes the files to be processed are not stored in a dedicated directory, and may be intermingled with
other files in the same directory which should not be processed. In these cases, there is usually a naming
convention defined to allow the script to determine which files should be processed and which should be
ignored. The Instance Info API supports specifying a regular expression when looking up files, returning only
those files whose filenames match the specified pattern.
The following script example demonstrates using the Instance Info API to retrieve all files with names
matching the pattern “importData_MMDDYYYYHHMMSS.csv” in the indicated directory:

Example 2: Finding all files matching a pattern in a directory


includeDistributedPolicy("INSTANCE_INFO_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 266


WT&A API Specifications 18.3 Instance Info API

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Define the directory containing the files to be processed


var directory = "interface/incoming/dataFiles/";

// Define the pattern the files need to match. This pattern will match all
// files with a filename of the form "importData_MMDDYYYYHHMMSS.csv", where
// "MMDDYYYYYHHMMSS" represents the timestamp of when the file was created
var pattern = "importData_(\\d{14})\\.csv";

// Get all of the files in the directory


var files = api.getMatchingFilesInDirectory(directory, pattern);

// Iterate over the files that match the pattern and process them as desired
for (var i = 0; i < files.length; ++i) {
var file = files[i];

// Process the file as needed


log.info("Processing file " + file.getName() );
}

Note: The pattern needs to be specified as a string, not as a JavaScript RegExp object. This means that care
needs to be taken with escape characters in the pattern: all backlashes to appear in the regular
expression need to be doubled in order to function correctly.

In addition to these methods to retrieve the files in a directory, the Instance Info API also includes
functionality for printing out information about the files in a directory to the job log. This information cannot
be consumed by the script, since it just consists of information messages in the log, but can be useful for
troubleshooting if a script does not appear to be accessing the expected files.
The following script example demonstrates using the Instance Info API to print out the contents of a directory
in the log:

Example 3: Listing all of the available files in a directory


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Define the directory containing the files to be processed


var directory = "interface/incoming/dataFiles/";

// Write the contents of the directory to the job log


api.printDirectoryContents(directory);

An example of the output from this method in the job log is:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 267


WT&A API Specifications 18.3 Instance Info API

Determining if an Instance has Access to the Expected Directories


For SaaS environments, it is assumed that interfaces will be reading from a directory named
“interface/incoming/” and will be writing to a directory named “interface/outgoing/”. The Instance Info API
includes a utility method that can be called to verify that both of these expected directories exist for an
instance.
An example of a script calling this method is as follows:

Example: Determining if an instance has access to the expected directories


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Perform conditional logic based on whether the expected SaaS directories are
// present or not
if (api.hasExpectedSaaSDirectories() ) {
log.info("The expected SaaS directories are present!");
}
else {
log.error("Unable to find the expected SaaS interface directories");
}

Determining File Permissions


The Instance Info API can be used to determine what permissions WorkForce Time and Attendance has for a
particular file. This can be used to verify that WorkForce Time and Attendance is allowed to read a file before
attempting to read data from it, or to verify that WorkForce Time and Attendance is allowed to update a file
before attempting to write to it.
The following script example demonstrates using the Instance Info API to look up the permissions for a file:

Example: Determining permissions for a file


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Define the directory containing the file to be evaluated


var directory = "interface/incoming/";

// Define the name of the file in the directory to be evaluated


var fileName = "importData.csv";

// Determine the permissions for the file


var filePermissions = api.getFilePermissions(directory, fileName);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 268


WT&A API Specifications 18.3 Instance Info API

if (filePermissions.canRead) {
log.info("Able to read data from the file");

// Do any file reading that is needed...


}
else {
log.error("Unable to read data from the file");
}

if (filePermissions.canWrite) {
log.info("Able to write data to the file");

// Do any file writing that is needed...


}
else {
log.error("Unable to write data to the file");
}

Identifying the Current Database Type


The Instance Info API provides the ability to determine which type of database the WorkForce Time and
Attendance instance is using as a backend. The can be used when writing custom queries, where the query
needs to reflect the correct syntax for the database. (Oracle and SQL Server have many areas where they
differ in terms of the allowed syntax.)
The following script example demonstrates how the Instance Info API can be used in order to detect the
database type in order to build a query that selects all records from the LD3 table where OTHER_STRING1 is
more than five characters long:

Example: Identifying the current database type


includeDistributedPolicy("INSTANCE_INFO_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Detect the database type


var databaseType = api.getDatabaseType();

// Select the right version of the query to use based on the database type
var query = "";
if (databaseType == "ORACLE") {
query = "select ld1 from ld3 where length(other_string1) >= 5";
}
else if (databaseType == "SQL_SERVER") {
query = "select ld1 from ld3 where len(other_string1) >= 5";
}

Retrieve Distribution Root Directory Path


The Instance Info API provides the ability to retrieve distribution root directory path.
The following script example demonstrates how the Instance Info API can be used to get root directory path.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 269


WT&A API Specifications 18.3 Instance Info API

Example: Get root directory path


includeDistributedPolicy("INSTANCE_INFO_API");

// Create a new instance of the API


var api = new InstanceInfoAPI();

// Get root directory path


var rootPath = api. getDistributionRootDirectory ();
log.info(rootPath);

Troubleshooting
The job log of the script using the Instance Info API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


Unable to lookup property A call was made to Ensure that all calls to
without a property name getBuildProperty() without a getBuildProperty() specify a property
specified property name specified. name and that the property name is
not null/blank.
Property PROPERTY_NAME The property name specified in Ensure that the property names being
is not authorized to be getBuildProperty() was not a accessed are correct and valid
queried through the custom property from property names to access.
Instance Info API custom_config.xml and is not one
of the valid whitelisted properties
to access from config.xml
Specified directory The file path specified when Ensure that a valid file path is
DIRECTORY does not looking up the files in a directory specified when looking up files in a
represent a valid directory. was either not a valid file path or it directory.
Either it does not exist, or it corresponded to a file in a
is not a directory. directory, not the directory itself.
Specified file FILE_NAME The indicated file does not exist in Ensure that the file path and file
does not exist in directory the directory that was specified. name are correct, and that the
DIRECTORY expected file exists in that location.
Table 47: Instance Info API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

InstanceInfoAPI
InstanceInfoAPI
Creates a new instance of the Instance Info API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 270


WT&A API Specifications 18.3 Instance Info API

getBuildProperty(property)
Returns the value of the specified build property from either the config.xml or custom_config.xml files. While
all properties in custom_config.xml are accessible through this method, only the following properties in
config.xml are available to be read:
Whitelisted config.xml Properties
BASE_PORT
BO.INSTALLATION.VERSION
CLIENT.APPLICATION.NAME
ENVIRONMENT
HOST_NAME
INSTANCE_NAME_OPTIONS.INSTANCE_ID
JDBC.PRODUCT
JVM.XMS
JVM.XMX
PRIMARY_INSTANCE
SCHEDULER_RUN
BATCH_JOB_THREADS
Table 48: Properties that are allowed to be read from config.xml

getVersion()
Returns the current version of WorkForce Time and Attendance that the script is running on.

getFilesInDirectory(filePath)
Returns an array of all files in the specified directory. Does not recursively scan subdirectories for files.

getMatchingFilesInDirectory(filePath, pattern)
Returns an array of all files in the specified directory where the filename matches the indicated regular
expression. Does not recursively scan subdirectories for files.

printDirectoryContents(filePath)
Writes information about the contents of the specified directory to the job log. Messages are of the form:
TYPE FILENAME (SIZE bytes). Last modified on LAST_MODIFICATION_DTTM

getFilePermissions(filePath, fileName)
Returns the file permissions for the specified file. Returned object is a JS object with the following
properties:
Property Name Description
canRead Indicates if the file is able to be read by WorkForce
Time and Attendance
Indicates if the files is able to be written to by
canWrite
WorkForce Time and Attendance
canExecute Indicates if the file can be executed by WorkForce
Time and Attendance
Table 49: Properties available on the result returned by getFilePermissions

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 271


WT&A API Specifications 18.3 Instance Info API

hasExpectedSaaSDirectories()
Returns true if both the interface/incoming/ and interface/outgoing/ directories exist and are accessible
by the instance, or false if one or both of them is not accessible.

getDatabaseType()
Identifies whether WorkForce Time and Attendance is using a SQL Server or an Oracle back end to store the
data. Return value will be either SQL_SERVER or ORACLE.

getDistributionRootDirectory ()
Returns distribution root directory path.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 272


WT&A API Specifications 18.3 Job Queue API

Job Queue API


Overview and Capabilities
The Job Queue API provides a mechanism for scripts to use in order to launch other jobs. This allows for a
process that requires multiple different interface policies to be run by the user selecting a single job.
Additionally, this API allows a sequence of jobs to be defined so that one job starts as soon as a preceding job
finishes. One example of this would be an employee import job, where a Scheduled Script is used to process
the source CSV file and then SQL Employee Import Control policies are used to actually update the employee
and assignment tables. The Job Queue API allows the scheduled script to automatically trigger the SQL
Employee Import Control policies once it has finished its portion of the processing, allowing them to pick up
the processing without requiring the user to manually trigger them.
The Job Queue API also includes functionality for working with jobs that are already running. This includes
identifying if a job is already running or not, which allows a job to stop any further processing if another
instance of that job is already running. This helps avoid issues due to the same job running multiple times
concurrently. It also includes determining when the last time a given job was run, which can be helpful in
determining what data a job should process.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• What sorts of WorkForce Time and Attendance jobs are available and what kinds of parameters they use

Components
This API consists of the following component(s):
• The JOB_QUEUE_API Distributed JavaScript library
• The COMMON_JOB_CREATION_LIBRARY Distributed JavaScript library (automatically included as part of
the JOB_QUEUE_API library)
• The JobBuilder framework (automatically included as part of the JOB_QUEUE_API library)

Setup
No setup is necessary for the Job Queue API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Running a Single Job
The simplest use case for the Job Queue API is to run a single job from within another script. If the job to be
run conforms to the typical default settings for running that type of job, then the helper methods defined by
the Common Job Creator Library can be used to define the job. A job defined in this manner will always
cause the parent script to pause execution until the child job has completed finished.
The following example demonstrates how a simple Scheduled Script job can be defined and run from within a
script. The script will run the Scheduled Script with the policy ID “STAGE_TWO_JOB”. This job will appear on

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 273


WT&A API Specifications 18.3 Job Queue API

the job status screen with a description of “Stage Two Processing Job”. The script that initiated the
Scheduled Script job will wait until the Scheduled Script completely finishes before continuing on with any
remaining code execution.

Example 1: Defining a simple job


includeDistributedPolicy("JOB_QUEUE_API");

// Initial code to be run before starting the job would go here

// Create a new job queue to hold the jobs to be run


var jobQueue = new JobQueue();

// Define the job to be run. In this case, the job being defined is a Scheduled
// Script policy named "STAGE_TWO_JOB".
var policyId = "STAGE_TWO_JOB";
var description = "Stage Two Processing Job";
var parameters = null;
var job = createScheduledScriptJob(description, policyId, parameters);

// Add the job definition into the queue


jobQueue.addJob(job);

// Start the job. This script will pause execution until the job completes
jobQueue.executeJobs();

// Additional code to be executed in this script after the job completes would
// go here

Sometimes the default settings for a job are not sufficient for the needs of the script. For example, perhaps
the parent job should not wait for the child job to complete before continuing on but instead it should
immediately continue with further processing. The following example shows how a job can be defined with
custom settings applied:

Example 2: Defining a job with custom settings


includeDistributedPolicy("JOB_QUEUE_API");

// Initial code to be run before starting the job would go here

// Create a new job queue to hold the jobs to be run


var jobQueue = new JobQueue();

// Define the job to be run. In this case, the job being defined is a Scheduled
Script policy named "STAGE_TWO_JOB".
var policyId = "STAGE_TWO_JOB";
var description = "Stage Two Processing Job";
var jobType = "SCRIPT_RUNNER";
var job = new JobBuilder(jobType, description)
.buildPolicyId(policyId)
.buildWaitUntilCompleteBoolean(false)
.buildParamMap(null)
.build();

// Add the job definition into the queue


jobQueue.addJob(job);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 274


WT&A API Specifications 18.3 Job Queue API

// Start the job. This script will continue with execution immediately
jobQueue.executeJobs();

// Additional code to be executed in this script after the job completes would
// go here

With this approach, the JobBuilder is used to construct the job. The different settings for the job are chained
together through a series of calls, and then the job is finalized by the call to build().

Note: Once a job has been built, no changes can be made to its settings. If different settings are needed a
second job must be built.

Running Multiple Jobs in Sequence


The Job Queue API can be used to define a sequence consisting of multiple jobs. When the jobs in the queue
are executed, the jobs will be run in the order in which they were added. The following example
demonstrates constructing a queue containing a Scheduled Script, a SQL Employee Import Control, and a
Time Entry Import.

Example 1: Running a series of jobs in order


includeDistributedPolicy("JOB_QUEUE_API");

// Initial code to be run before starting the jobs would go here

// Create a new job queue to hold the jobs to be run


var jobQueue = new JobQueue();

// Define the first job that should be run. This will be a Scheduled Script job
var policyId1 = "IMPORT_STEP_2";
var description1 = "Import Step #2: Scheduled Script";
var parameters1 = null;
var job1 = createScheduledScriptJob(description1, policyId1, parameters1);

// Define the second job that should be run. This will be a SQL Employe Import
// Control job.
var policyId2 = "IMPORT_STEP_3";
var description2 = "Import Step #3: SQL Employee Import Control";
var job2 = createSQLEmployeeImportJob(description2, policyId2);

// Define the third job that should be run. This will be a Time Entry Import job.
// Both the first and second phases of the Time Entry Import will be run.
var policyId3 = "IMPORT_STEP_4";
var description3 = "Import Step #4: Time Entry Import";
var filePath = "interface/incoming/";
var fileName = "timeEntryImport.csv";
var job3 = createTimeEntryImportJob(description3, policyId3, filePath, fileName);

// Add the three job definitions into the queue, in the order in which they should
// be executed
jobQueue.addJob(job1);
jobQueue.addJob(job2);
jobQueue.addJob(job3);

// Start the first job. One the first job completes, the second job will

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 275


WT&A API Specifications 18.3 Job Queue API

// automatically begin. Once the second job completes, the third job will
// automatically begin.
jobQueue.executeJobs();

// Additional code to be executed in this script after all three of the jobs have
// completed would go here

In addition to running a sequence of jobs in order, the Job Queue can also be used to run several jobs that all
process at the same time. This can be accomplished by defining custom settings for the jobs that tell the
Queue not to wait until they are completed before continuing on, as shown in this example:

Example 2: Running multiple jobs concurrently


includeDistributedPolicy("JOB_QUEUE_API");

// Initial code to be run before starting the jobs would go here

// Create a new job queue to hold the jobs to be run


var jobQueue = new JobQueue();

// Define the first job that should be run. This will be a Scheduled Script job
var policyId1 = "IMPORT_STEP_2";
var description1 = "Import Step #2: Scheduled Script";
var parameters1 = null;
var jobType1 = "SCRIPT_RUNNER";
var job1 = new JobBuilder(jobType1, description1)
.buildPolicyId(policyId1)
.buildParamMap(null)
.buildWaitUntilCompleteBoolean(false)
.build();

// Define the second job that should be run. This will be a SQL Employe Import
// Control job.
var policyId2 = "IMPORT_STEP_3";
var description2 = "Import Step #3: SQL Employee Import Control";
var jobType2 = "PC_PAYROLL_EMPLOYEE_IMPORT";
var job2 = new JobBuilder(jobType2, description2)
.buildPolicyId(policyId2)
.buildWaitUntilCompleteBoolean(false)
.build();

// Define the third job that should be run. This will be a Time Entry Import job.
// Both the first and second phases of the Time Entry Import will be run.
var policyId3 = "IMPORT_STEP_4";
var description3 = "Import Step #4: Time Entry Import";
var filePath = "interface/incoming/";
var fileName = "timeEntryImport.csv";
var job3 = createTimeEntryImportJob(description3, policyId3, filePath, fileName);

// Add the three job definitions into the queue, in the order in which they should
// be executed
jobQueue.addJob(job1);
jobQueue.addJob(job2);
jobQueue.addJob(job3);

// This will start the first job and then immediately start the second job, since
// the first job is defined as not waiting until completion before continuing.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 276


WT&A API Specifications 18.3 Job Queue API

// The same will happen with the second job, with the third job being started
// immediately upon beginning execution of the second job. This script will wait
// until the third job has completed before continuing on.
jobQueue.executeJobs();

// Additional code to be executed in this script after all three of the jobs have
// completed would go here

Specifying the User to Execute a Job


Normally when a job is executed through the Job Queue, it will be run as the WORKFORCE user. For most
applications this is probably the best user to show as running the job, and no further action is necessary.
However, in some cases it may be necessary to have jobs show up as having been run by a different user (e.g.
the user that ran the parent job). The following example shows how to define a Job Queue that executes
jobs as a particular user:

Example: Specifying the user to execute a job


includeDistributedPolicy("JOB_QUEUE_API");

// Initial code to be run before starting the job would go here

// Create a new job queue to hold the jobs to be run, specifying that the jobs should be
// run by the user that launched this job
var jobQueue = new JobQueue(loggedInUserId);

// Define the job that should be run. In this case, the job being defined is a Scheduled
// Script policy named "STAGE_TWO_JOB"
var policyId = "STAGE_TWO_JOB";
var description = "Stage Two Processing Job";
var parameters = null;
var job = createScheduledScriptJob(description, policyId, parameters);

// Add the job definition into the queue


jobQueue.addJob(job);

// Start the job, running it as though it was launched by the indicated user.
jobQueue.executeJobs();

// Additional code to be executed in this script after the job completes would
// go here

Note: If the user specified is not a valid login ID for an APP_USER record, an exception will be generated. This
is especially important when using the ID of the user that launched the parent script, since if that
parent job is scheduled that user ID will be SYSTEM_SCHEDULER, which is unlikely to be a valid user ID.

Determining the Number of Jobs Already Running


The Job Queue API can be used to determine the number of jobs matching a given description that are
currently running. This information can then be used to drive further logic within the script. One common
scenario where this information would be used would be to count the number of other versions of a given
job are already running when that job starts, and aborting the job if there is already another version running.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 277


WT&A API Specifications 18.3 Job Queue API

This helps prevent the two jobs from conflicting with each other if they would both be processing the same
data.
The following example demonstrates counting the number of instances of a job that are running and only
executing code if that count is an expected number. This script in this example is assumed to be running
from a policy named THIS_JOB with a description of “This Job that is currently running”:

Example: Determining the number of jobs already running


includeDistributedPolicy("JOB_QUEUE_API");

// Create a new job queue


var jobQueue = new JobQueue();

// Define the descriptions that we are interested in


var descriptions = ["THIS_JOB", "This Job that is currently running"];

// Count the number of jobs currently running that match the provided description.
var jobCount = jobQueue.getRunningJobCount(descriptions, true);

if (jobCount > 1) {
log.info("Multiple copies of this job are already running. No action will be
taken here.");
}
else {
log.info("This is the only instance of the job that is running. Performing
actions...");

// The rest of the script logic that should happen now that we know only one
// instance of the job is running would go here
}

Note: The same job can end up with multiple different descriptions, depending on how it’s run. A job run
manually will have a description reflecting its policy ID. A job run by the scheduler will use the
description defined in the policy, or a description reflecting the policy ID if no description is defined in
the policy. And a job run by a Job Queue will use whatever description is defined in the script that is
running the Job Queue. It is often necessary to check against multiple descriptions in order to
determine how many instances of a particular job are actually running.

Troubleshooting
The job log of the script using the Job Queue API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 278


WT&A API Specifications 18.3 Job Queue API

Error Message Problem Solution


Error executing job: The definition provided for a job Check the job log for the indicated job
DESCRIPTION. Exiting indicated that the queue should to see which errors were reported
queue stop further processing when a job and what action is necessary in order
encountered errors, and that job to resolve them.
had errors reported when it was
run
Warnings running job: A job run by the Job Queue Check the job log for the indicated job
DESCRIPTION. Check the generated warning messages to see which warnings were
batch job log for details. during its processing. generated and if any corrective
actions are necessary.
Errors running job: A job run by the Job Queue Check the job log for the indicated job
DESCRIPTION. Check the generated error messages during to see which errors were generated
batch job log for details. its processing. and determine what corrective action
is necessary.
No user found for ID: The user specified for running jobs Ensure that a user record exists with a
USER_ID in the Job Queue did not match login ID that matches the ID being
the login ID of a user record. specified when creating the Job
Queue.

When archive is set to true, The definition for a job in the Job Ensure that the definition for the job
archivePath, filepath, and Queue specified that files should where archiving is to occur specifies a
filename attributes must be archived after they are file path, file name, and an archive
be initialized. processed, but either the file path, path.
file name, and/or archive path
attributes were not specified in
that definition.
Unable to archive file. File The definition for a job in the Job Ensure that the file referenced by the
doesn’t exist. Queue specified that files should file path and file name specified in the
be archived after they are job definition exists.
processed, but no file was found to
be processed.
Closing timesheets via an An attempt was made to define a Closing timesheets is not supported
automated script is not job to execute the Close by the Job Queue, and must be run as
supported by WorkForce Timesheets operation. a manual operation.
Software
Advancing Policy Profiles An attempt was made to define a Advancing policy profiles is not
via an automated script is job to execute the Advance Policy supported by the Job Queue, and
not supported by Profiles operation. must be run as a manual operation.
WorkForce Software
Must supply a reference A job definition was being defined Ensure that the timesheet parameters
date for a pay period for a Calculate job using either the being used by the Calculate job
option of: PAY PERIOD “period as of” or “specified period” specify a valid period reference date.
OPTION options, but no period reference
date was provided
Table 50: Job Queue API typical error messages, root problems, and solutions

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 279


WT&A API Specifications 18.3 Job Queue API

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Job Queue API consists of the following component(s):
1. The JobQueue, which defines an ordered series of jobs that should be run
2. The Common Job Creator, which provides convenience methods for creating many common types of
jobs with default settings
3. The JobBuilder, which allows for custom job definitions to be defined with custom settings when the
Common Job Creator doesn’t provide the necessary functionality
The following is a summary of the available methods and common uses:

JobQueue
JobQueue(userId)
Creates a new Job Queue. If a userId is specified, all jobs executed by this Job Queue will appear to have
been run by the indicated user.

addJob(job)
Adds a new job, using the supplied definition, to the end of the Job Queue.

executeJobs()
Executes all jobs in the Job Queue, in the order in which they were added.

clearQueue()
Removes all jobs from the Job Queue.

countJobsCurrentlyRunning(description)
Returns the number of jobs currently running that include the specified value in their description.

getRunningJobCount(descriptionArray, includeThisJob)
Returns the number of jobs currently running that match any of the descriptions specified in the provided
description array. Descriptions are evaluated as regular expressions, allowing for pattern-based matching if
desired. Whichever description is associated with the job currently running will be automatically included in
the evaluation as well if includeThisJob is specified as true.

abortJob(description)
Aborts every job currently running where the specified value is included in the job description.

getLastRunTime(description)
Returns the most recent execution start time for any job matching the specified description. The description
is evaluated using SQL’s “LIKE” syntax, so wildcard values are supported.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 280


WT&A API Specifications 18.3 Job Queue API

executeSingleJobWithoutWaiting(job)
Executes the specified job immediately and resumes script execution without waiting for the job to complete.
Returns the Job ID of the job that was started to allow for later polling of the job status.

executeJobQueuePolicy(description, policyName)
Takes a job queue policy name and executes it by using an internal job queue. Description is also taken to
help identify the job more easily.

Common Job Creator


createCSVEmployeeImportJob(description, policyId, filePath, fileName)
Defines a new job to execute a CSV Employee Import Control job with the specified policy ID and description
that will process the specified file. The file will not be archived after processing, and when executed the Job
Queue will wait until the job is complete before continuing to the next job. Errors in this job will not cause
the Job Queue to abort without processing remaining jobs.

createSQLEmployeeImportJob(description, policyId)
Defines a new job to execute a SQL Employee Import Control job with the specified policy ID and description.
When executed, the Job Queue will wait until the job is complete before continuing to the next job. Errors in
this job will not cause the Job Queue to abort without processing remaining jobs.

createUserImportJob(description)
Defines a new job to execute the User Import job with the specified description. When executed, the Job
Queue will wait until the job is complete before continuing to the next job. Errors in this job will not cause
the Job Queue to abort without processing remaining jobs.

createTimeEntryImportJob(description, policyId, filePath, fileName)


Defines a new job to execute a Time Entry Import job with the specified policy ID and description. This job
will only execute both phases of the Time Entry Import process, reading data from the specified file and
loading it into the TIME_ENTRY_DETAIL_TABLE and then transferring the data from that table to the
timesheet or schedule. The file will not be archived after processing, and when executed the Job Queue will
wait until the job is complete before continuing to the next job. Errors in this job will not cause the Job
Queue to abort without processing remaining jobs.

createTimeEntryImportFromHoldingJob(description, policyId)
Defines a new job to execute a Time Entry Import job with the specified policy ID and description. This job
will only execute the second phase of the Time Entry Import process, moving data that already exists in the
TIME_ENTRY_DETAIL_IMPORT table to the timesheet or schedule. No new data will be created in
TIME_ENTRY_DETAIL_IMPORT by this job. When executed, the Job Queue will wait until the job is complete
before continuing to the next job. Errors in this job will not cause the Job Queue to abort without processing
remaining jobs.

createTimeEntryImportToHoldingJob(description, policyId, filePath, fileName)


Defines a new job to execute a Time Entry Import job with the specified policy ID and description. This job
will only execute the first phase of the Time Entry Import process, reading data from the specified file and

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 281


WT&A API Specifications 18.3 Job Queue API

loading it into the TIME_ENTRY_DETAIL_IMPORT table. Data will not actually be written to the timesheets or
schedules by this job. The file will not be archived after processing, and when executed the Job Queue will
wait until the job is complete before continuing to the next job. Errors in this job will not cause the Job
Queue to abort without processing remaining jobs.

createScheduledScriptJob(description, policyId, scriptParmsHashMap)


Defines a new job to execute a Scheduled Script job with the specified policy ID and description. Optional
parameter values can be specified in a HashMap, which will then be available within the Scheduled Script as
it is running. When executed, the Job Queue will wait until the job is complete before continuing to the next
job. Errors in this job will not cause the Job Queue to abort without processing remaining jobs.

createLockTimeSheetsJob(description, fastLock, singleTimeSheetEnv, groupId)


Defines a new job to execute a Lock and Calculate job with the specified description that will process the
indicated group. When executed, the Job Queue will wait until the job is complete before continuing to the
next job. Errors in this job will not cause the Job Queue to abort without processing remaining jobs.

createUnlockTimesheetsJob(description, singleTimeSheetEnv, groupId)


Defines a new job to execute an Unlock job with the specified description that will process the indicated
group. When executed, the Job Queue will wait until the job is complete before continuing to the next job.
Errors in this job will not cause the Job Queue to abort without processing remaining jobs.

createCalcTimesheetsJob(description, singleTimeSheetEnv, groupId, ppOption,


referenceDate, calcAmended, calcLocked)
Defines a new job to execute a Calculate job with the specified description and settings that will process the
indicated group. When executed, the Job Queue will wait until the job is complete before continuing to the
next job. Errors in this job will not cause the Job Queue to abort without processing remaining jobs.

createCloseTimesheetsJob(description, singleTimeSheetEnv, groupId)


Generates an error message. Because it is an irreversible operation, the Close Timesheets job should never
be run in an automated fashion. It should always be run manually, after verification that all timesheets to be
processed are in a final and correct state.

createGenericExportJob(description, exportId, ppOption, asOfDate, policyProfileGrpId,


asgnmtGrpId, asgnmtGrpDescription, isMultipleAssignment, dateRange)
Defines a new job to execute a Generic Export job with the specified description and settings. When
executed, the Job Queue will wait until the job is complete before continuing to the next job. Errors in this
job will not cause the Job Queue to abort without processing remaining jobs.

createAdvancePolicyProfileJob(description, listOfPolicyProfiles)
Generates an error message. Because it is an irreversible operation, the Advance Policy Profiles job should
never be run in an automated fashion. It should always be run manually, after verification that all timesheets
to be processed are in a final and correct state.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 282


WT&A API Specifications 18.3 Job Queue API

createCsvLdImportJob(description, policyId, filePath, fileName)


Defines a new job to execute a CSV-based LD Import job with the specified policy ID and description that will
process the specified file. The file will not be archived after processing, and when executed the Job Queue
will wait until the job is complete before continuing to the next job. Errors in this job will not cause the Job
Queue to abort without processing remaining jobs.

createSqlLdImportJob(description, policyId, dbConnectionInfo, query)


Defines a new job to execute a SQL-based LD Import job with the specified policy ID and description and
executing the indicated query against the specified database. When executed, the Job Queue will wait until
the job is complete before continuing to the next job. Errors in this job will not cause the Job Queue to abort
without processing remaining jobs.

createJobQueueJob(description, policyName)
Defines a new job to run a Job Queue policy.

createAbsenceExportJobForAssignments(parms)
Defines a new job to execute an Absence Export job using the specified parameters. The parameters
object should be specified as a JavaScript object with properties corresponding to the parameter to be
set and a value for each property corresponding to the value that should be used for that parameter.
The following parameters are supported:

Parameter Description
Description The description that should appear on the Job Status screen
for the export job
policyId The name of the Absence Export policy that should be
executed
filePath (Optional) The directory that the absence export file should
be written to. If not specified, the directory specified in the
Absence Export policy being executed will be used
fileName (Optional) The name of the absence export file that should
be written. If not specified, the file name specified in the
Absence Export policy being executed will be used
asgnmtIds (Optional) Array of assignment IDs specifying the
assignments that should be exported. If not specified, all
assignments defined in the instance will be included in the
export data.
Table 51: Valid batch job types and their description

createAbsenceExportJobForAssignmentGroup(parms)
Defines a new job to execute an Absence Export job using the specified parameters, exporting data for
only the assignments belonging to the specified assignment group. The parameters object should be
specified as a JavaScript object with properties corresponding to the parameter to be set and a value for
each property corresponding to the value that should be used for that parameter. The following
parameters are supported:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 283


WT&A API Specifications 18.3 Job Queue API

Parameter Description
Description The description that should appear on the Job Status screen
for the export job
policyId The name of the Absence Export policy that should be
executed
asgnmtGroupId The display ID of the assignment group whose assignments
should be exported
filePath (Optional) The directory that the absence export file should
be written to. If not specified, the directory specified in the
Absence Export policy being executed will be used.
fileName (Optional) The name of the absence export file that should
be written. If not specified, the file name specified in the
Absence Export policy being executed will be used
Table 52: Valid batch job types and their description

JobBuilder
JobBuilder(type, description)
Creates a new JobBuilder with the specified job type and description. Valid job types are as follows:
Job Type Description
ACT Generates notifications and evaluating document eligibility
for ACT cases.
LD_IMPORT Executes a specific LD Import policy
AUTO_SCHEDULER Runs an auto-scheduling process
RECALC_ASGNMT_GROUPS Recalculates membership of automatic assignment groups
APPROVAL_DEADLINE Sends emails based on approval deadlines
SCRIPT_RUNNER Executes a specific Scheduled Script policy
APPROVAL Approves a timesheet.
ADP_DATA_EXCHANGE Executes a specific ADP Export Map policy
GENERIC_EXPORT Executes a specific Generic Export policy
ORACLE_PAYROLL Executes a specific Oracle Payroll Export policy
CSV_EMPLOYEE_IMPORT Executes a specific CSV Employee Import Control policy
PC_PAYROLL_EMPLOYEE_IMPORT Executes a specific SQL Employee Import Control policy
OFF_CYCLE_CANCEL Cancels an existing off-cycle batch that is already in process
OFF_CYCLE_RE_EXPORT Re-exports off-cycle data associated with a particular off-
cycle batch
OFF_CYCLE_CLOSE Closes an existing off-cycle batch that is already in process
OFF_CYCLE_ADP_EXPORT Exports off-cycle data using the ADP Export process
OFF_CYCLE_GENERIC_EXPORT Exports off-cycle data using the Generic Export process
OFF_CYCLE_ORACLE_PAYROLL_EXPORT Exports off-cycle data using the Oracle Payroll Export
process
TIME_ENTRY_COMMIT Executes the stage-to-actual step of a specific Time Entry
Import policy

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 284


WT&A API Specifications 18.3 Job Queue API

Job Type Description


TIME_ENTRY_IMPORT Executes the source-to-stage step of a specific Time Entry
Import policy
TIME_ENTRY_IMPORT_COMMIT Executes both steps of a specific Time Entry Import policy
CROSS_PERIOD_CALC Executes a cross-period timesheet calculation job
SCHEDULE_ASSIGNMENT Assigns schedule templates or cycles to assignments
GROUP_MESSAGING Sends an email or SMS message to a list of assignments
TRANSLATIONS Imports or exports translation files
CALC_TIME_SHEETS Calculates timesheets
CREATE_RETRO_TRIGGER_EVENTS Creates retro trigger events
LOCK_AND_CALC_TIME_SHEETS Locks and calculates timesheets
ORALCE_PA Executes a specific Oracle Project Accounting export
UNLOCK_TIME_SHEETS Unlocks timesheets
USER_IMPORT Executes the User Import policy
REMOVE_BIOMETRIC_TEMPLATES Removes biometric templates assigned to terminated
employees
BADGE_IMPORT Imports badges from one or more data sources
ABSENCE_EXPORT Exports absence data to a file. (Predominantly used for
integrating with the Forecasting and Scheduling module.)
Table 53: Valid batch job types and their description

build()
Returns an immutable representation of the job definition that can be added into a Job Queue.

buildPolicyId(policyID)
Defines which policy should be executed for jobs that run a single policy.

buildFileName(fileName)
Defines the name of the file that should be processed for jobs that read data from a file.

buildFilePath(filePath)
Defines the directory containing the file that should be processed for jobs that read data from a file.

buildProcessingParm(processingParm)
Defines the processing parameters that are needed for a particular type of job. The following table defines
which job types require processing parameters as well as which parameter class they are expecting:
Job Type Processing Parameter Class
LD_IMPORT LdImportParams
APPROVAL_DEADLINE ApprovalDeadlineParams
APPROVAL ApprovalBatchJobParams
ADP_DATA_EXCHANGE ExportPolicyParms
GENERIC_EXPORT ExportPolicyParms
ORACLE_PAYROLL ExportPolicyParms
OFF_CYCLE_CANCEL OffCycleCancelBatchParms
OFF_CYCLE_RE_EXPORT OffCycleReExportBatchParms

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 285


WT&A API Specifications 18.3 Job Queue API

Job Type Processing Parameter Class


OFF_CYCLE_CLOSE OffCycleCloseBatchParms
OFF_CYCLE_ADP_EXPORT OffCycleExtractBatchParms
OFF_CYCLE_GENERIC_EXPORT OffCycleExtractBatchParms
OFF_CYCLE_ORACLE_PAYROLL_EXPORT OffCycleExtractBatchParms
TIME_ENTRY_COMMIT TimeEntryImportParms
TIME_ENTRY_IMPORT TimeEntryImportParms
TIME_ENTRY_IMPORT_COMMIT TimeEntryImportParms
GROUP_MESSAGING GroupMessagingBatchJobParms
TRANSLATIONS TranslationsJobParms
CALC_TIME_SHEETS CalcTimeSheetParms
CREATE_RETRO_TRIGGER_EVENTS ProcessingParms
LOCK_AND_CALC_TIME_SHEETS ProcessingParms
ORALCE_PA ExportPolicyParms
UNLOCK_TIME_SHEETS ProcessingParms
ABSENCE_EXPORT AbsenceExportParams
Table 54: Batch job types and their corresponding processing parameter classes

buildArchiveBoolean(archive)
Specifies whether the file should be archived after processing for jobs that read data from a file. When
archived, the source file for the job is renamed to include the timestamp of the archiving at the beginning of
the file name.

buildArchivePath(archivePath)
Specifies which directory the source file should be moved to when it is archived for jobs that read data from a
file. This setting only matters if file archiving is enabled using buildArchiveBoolean().

buildParamMap(paramMap)
Specifies the runtime parameters that should be passed into the job when it begins execution. Only used
when executing Scheduled Script jobs (the SCRIPT_RUNNER job type).

buildDelayTimer(delay)
Specifies the number of seconds the Job Queue should wait once it reaches this job before beginning actual
execution of the job.

buildContinueOnErrorBoolean(continueOnError)
Specifies whether the Job Queue should continue to execute later jobs in the queue if errors are reported in
the log for this job.

buildWaitUntilCompleteBoolean(waitUntilCompleteBoolean)
Specifies whether the Job Queue should wait until this job completes before starting the next job or whether
it should continue on immediately after starting this job.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 286


WT&A API Specifications 18.3 Job Queue API

buildSystemFeature(systemFeature)
Specifies the system feature needed in order to execute certain jobs. The following jobs require a system
feature to be specified:
Job Type
ADP_DATA_EXCHANGE
GENERIC_EXPORT
ORACLE_PAYROLL
CALC_TIME_SHEETS
CREATE_RETRO_TRIGGER_EVENTS
LOCK_AND_CALC_TIME_SHEETS
ORALCE_PA
UNLOCK_TIME_SHEETS
Table 55: Batch job types that require system features to be specified

buildJobTypeInt(jobTypeInt)
Specifies what type of batch job is being executed. This is used by the RECALC_ASGNMT_GROUPS,
CROSS_PERIOD_CALC, SCHEDULE_ASSIGNMENT, SCHEMA_MODIFIER, and REMOVE_BIOMETRIC_TEMPLATES
job types. The valid values here are:
Job Type Description
1 Interactive
2 User Batch
3 System Batch
4 Swipe Processing
Table 56: Valid job types

buildSuperUserId(superUserId)
Specifies which superuser should be marked as having executed the job.

buildParamList(paramList)
Specifies the list of assignment parameters to be processed by the job. This should be a list of the following
types of parameter-class objects depending on job type:
Job Type Parameter Class
CROSS_PERIOD_CALC CrossPeriodCalcBatchJob.CrossPeriodCalcParameter
SCHEDULE_ASSIGNMENT ScheduleAssignmentBatchJob.ScheduleAssignmentParameter
Table 57: Job types that use parameter lists and their expected parameter classes

buildPriority(priority)
Specifies the job priority for a CROSS_PERIOD_CALC, SCHEDULE_ASSIGNMENT, or SCHEMA_MODIFIER job.
This controls which jobs take precedence in terms of execution by the Batch Job Processor.

buildWildcardBoolean(wildcardBoolean)
Specifies whether the translations should be imported or exported by a TRANSLATIONS job. A value of true
here means that the job should export the translations, a value of false means that the job should import the
translations.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 287


WT&A API Specifications 18.3 KPI Chart Library

KPI Chart Library


Overview and Capabilities
The KPI Chart Library provides the methods needed to configure a Key Performance Indicator (KPI) policy.
Each KPI policy includes several scripts used for the configuration and processing of the KPI. For additional
information on KPI policy configuration, see the WT&A Policy Configuration Guide.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The KPI_CHART_LIBRARY Distributed JavaScript Library
• The KPIUtil, KPIDbUtil, KPIChartHelper Java classes

Setup
No setup is necessary for the KPI Chart Library. The distributed library is automatically available in WT&A.

Use Cases
The best way to see the KPI Chart Library in use is to browse the standard KPIs that can be imported via the
KEY_PERFORMANCE_INDICATORS Standard Product template. The use cases in this section are mostly drawn
from these KPIs. To learn how to access template instructions or how to import templates, see the WT&A
Templates Framework Guide.

KPI Chart Configuration JavaScript


The scripts in following examples are used to define the appearance, structure, and configuration of the
corresponding KPI chart.

Example 1: From the STD_BANK_BALANCE_EMPLOYEE_AGGREGATE_ASSIGNMENT Key


Performance Indicator policy
includeDistributedPolicy("KPI_CHART_LIBRARY");

/** Additional chart configuration should be defined here **/

config.setSubtitle(getStandardDateRange(getStart(), getEnd()));

turnOffLinePoints(config);

Example 2: From the STD_SCHEDULE_VS_ACTUAL Key Performance Indicator policy


includeDistributedPolicy("KPI_CHART_LIBRARY");

/** Additional chart configuration should be defined here **/

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 288


WT&A API Specifications 18.3 KPI Chart Library

config.setSubtitle(getStandardDateRange(getStart(), getEnd()));
config.getPlotOptions().getColumn()
.setColor("#ff0000")
.setNegativeColor("#008000");

KPI Chart Data JavaScript


The scripts in following examples demonstrate processing the retrieved data.

Example 1: From the STD_ABSENCE_HOURS Key Performance Indicator policy


includeDistributedPolicy("KPI_CHART_LIBRARY");

/*
Define the logic to process the records retrieved by the query here.
The buildDataPoints(resultSet) method must be defined and must return
an array of data points created using the methods in KPI_CHART_LIBRARY
*/
function buildDataPoints(resultSet) {
var data = [];
while(resultSet.next()) {
data.push(createBasicAssignmentGroupDataPoint(resultSet.payCodeSet, resultSet.dateField,
resultSet.sumField, resultSet.asgnmt_grp));
}
return data;
}

Example 2: From the TEST_AGGREGATION_AVERAGE Key Performance Indicator policy


includeDistributedPolicy("KPI_CHART_LIBRARY");

function buildDataPoints(resultSet) {
var asgnmts = retrieveAsgnmtDataFromResultSet(resultSet);
return createDataPointForEachAsgnmtGrp(asgnmts);
}

/**
* Takes the results of the query defined in the KPI query script, and retrieves the necessary
information
* in order to calculate the average other_number1 value over all asgnmts being processed.
* @param {ResultSetScriptable} Result set containing results of the KPI query
* @returns {Object} Map of asgnmt group ID to array of the other_number1 values for each
asgnmt in the group
*/
function retrieveAsgnmtDataFromResultSet(resultSet) {
var asgnmts = {};
while(resultSet.next()) {
if (!asgnmts[resultSet.asgnmt_grp]) {
asgnmts[resultSet.asgnmt_grp] = [];
}
asgnmts[resultSet.asgnmt_grp].push(resultSet.asgnmt_field_to_average);
}
return asgnmts;
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 289


WT&A API Specifications 18.3 KPI Chart Library

/**
* Processes through the arrays of values created by retrieveAsgnmtDataFromResultSet,
calculates the average value
* for each asgnmt group, and create a data point for the asgnmt group
* @param {Object} Map of asgnmt group ID to array of the other_number1 values for each asgnmt
in the group
* @returns {Array} Array of data points, one for each asgnmt grp
*/
function createDataPointForEachAsgnmtGrp(asgnmts) {
var data = [];
for(var asgnmtGrp in asgnmts) {
var sum = 0;
for(var i = 0; i < asgnmts[asgnmtGrp].length; i++) {
sum += asgnmts[asgnmtGrp][i];
}

data.push(createAssignmentGroupDataPoint(getDataElementParameter("ASGNMT_FIELD_TO_AVERAGE") +
" Average", getDataElementParameter("ASGNMT_FIELD_TO_AVERAGE") + " Average", null, null,
sum/asgnmts[asgnmtGrp].length, null, asgnmtGrp));
}
return data;
}

KPI Chart Data Query JavaScript


The scripts in following examples define the query used to determine what data is retrieved from the
database.

Example 1: From the STD_ABSENCE_HOURS Key Performance Indicator policy


includeDistributedPolicy("KPI_CHART_LIBRARY");

/*
Define the query used to retrieve the records here.
The defineQuery() method must be defined and must return
a query object created using the methods in KPI_CHART_LIBRARY
*/
function defineQuery() {
//Define the query text here. Variables can be referenced inside the <query> tags by
wrapping the variable name with {} brackets
var query = <query>
select agd.asgnmt_grp, vpcsd.rule_set as payCodeSet,
{getDateSqlForTimeUnit("tso.work_dt")} as dateField,
sum({getDataElementParameter("SUM_FIELD")}) as sumField
from asgnmt_grp_detail agd, asgnmt a, asgnmt_master am, employee_periods ep,
time_sheet_output tso, (select distinct record_key, rule_set from v_pay_code_set_detail) vpcsd
where a.asgnmt = agd.asgnmt
and tso.work_dt between a.eff_dt and a.end_eff_dt
and a.assignment_status = 'A'
and a.soft_terminated ='F'
and ? &lt;= ep.pp_end and ? >= ep.pp_begin
and am.asgnmt = a.asgnmt
and am.asgnmt_type in (1, 2, 3)
and am.employee = ep.employee
and ep.asgnmt = a.asgnmt
and tso.employee_period_version = ep.calc_emp_period_version
and tso.transaction_type in (30, 40)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 290


WT&A API Specifications 18.3 KPI Chart Library

and tso.work_dt between agd.eff_dttm and agd.end_eff_dttm


</query>.toString();

//The 'group by', 'having', and 'order by' clauses must be defined separately in the below
variables
var groupByClause = "group by asgnmt_grp, rule_set, " +
getDateSqlForTimeUnit("tso.work_dt");
var havingClause = "";
var orderByClause = "";

//Define the parameters used in the query here. For String values, use the
formatNativeStringForServer method
var queryParams = [];
queryParams.push(getStart());
queryParams.push(getEnd());

//Only modify the below line if you have changed the data scope to something other that
User's Assignment Groups
return createAssignmentGroupBasedKpiDataQueryWithDataSeries(query, groupByClause,
havingClause, orderByClause,
"agd.asgnmt_grp", "tso.work_dt", "tso.pay_code", "vpcsd", queryParams);
}

Example 2: From the STD_LABOR_COST_BY_MOST_COMMON_LD Key Performance


Indicator policy
includeDistributedPolicy("KPI_CHART_LIBRARY");

/*
Define the query used to retrieve the records here.
The defineQuery() method must be defined and must return
a query object created using the methods in KPI_CHART_LIBRARY
*/
function defineQuery() {
//Change fields here to config:
var sumField = "tso." + getDataElementParameter("SUM_FIELD"); //field to use for summing
var ldField = getStringParameter("LD_FIELD"); //field containing LD value
var dateField = "tso.work_dt"; //field containing date value
var laborCostPayCodeSet = getPayCodeSetParameter("LABOR_COST_PAY_CODE_SET"); //Pay code set
contain pay codes to use for this KPI
var asgnmtGrpField = "agd.asgnmt_grp"; //field containing asgnmt_grp value

//Define the query text here. Variables can be referenced inside the <query> tags by
wrapping the variable name with {} brackets
var query = <query>
select {ldField} as ldField, {getDateSqlForTimeUnit(dateField)} as dateField,
sum({sumField}) as sumField, {asgnmtGrpField} as asgnmt_grp
from time_sheet_output tso, asgnmt_grp_detail agd, asgnmt a, asgnmt_master am,
employee_periods ep, (select distinct record_key, rule_set from v_pay_code_set_detail) vpcsd
where tso.pay_code = vpcsd.record_key
and a.asgnmt = agd.asgnmt
and tso.work_dt between a.eff_dt and a.end_eff_dt
and a.assignment_status = 'A'
and a.soft_terminated = 'F'
and ? &lt;= ep.pp_end and ? >= ep.pp_begin
and am.asgnmt = a.asgnmt
and am.asgnmt_type in (1, 2, 3)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 291


WT&A API Specifications 18.3 KPI Chart Library

and am.employee = ep.employee


and ep.asgnmt = a.asgnmt
and tso.employee_period_version = ep.calc_emp_period_version
and tso.transaction_type in (30, 40)
and tso.work_dt between agd.eff_dttm and agd.end_eff_dttm
and {buildInClause(formatArrayForInClause([laborCostPayCodeSet]), "vpcsd.rule_set")}
</query>.toString();

//The 'group by', 'having', and 'order by' clauses must be defined separately in the below
variables
var groupByClause = "group by " + ldField + ", " + getDateSqlForTimeUnit(dateField) + ", " +
asgnmtGrpField;
var havingClause = "";
var orderByClause = "order by sumField desc";

var appUserField = ""; //The field which contains the app user value (required for user data
scope)

//Define the parameters used in the query here. For String values, use the
formatNativeStringForServer method
var queryParams = [];
queryParams.push(getStart());
queryParams.push(getEnd());

//Only modify the below line if you have changed the data scope to something other that
User's Assignment Groups
return createAssignmentGroupBasedKpiDataQuery(query, groupByClause, havingClause,
orderByClause, asgnmtGrpField, dateField, queryParams);
}

KPI Aggregation Custom JavaScript


The scripts in following examples demonstrate how to specify the data used to aggregate an assignment
group.

Example 1: From the STD_LABOR_HOURS_BY_MOST_COMMON_LD Key Performance


Indicator policy
includeDistributedPolicy("KPI_CHART_LIBRARY");

function aggregateDataPoints(dataPoints) {
//Show the top X most common LD values (set value of 'X' here)
numberOfMostCommonLdValues = getIntegerParameter("NUMBER_OF_MOST_COMMON_LD_VALUES");

data = [];

//Create map from LD value name to array of records for that value
var ldValueMap = createLdMap(dataPoints);

//Create map from 'LD value' --> 'sum of cost for LD value across entire time frame'
var sumMap = createSumMap(ldValueMap);

//Create array of LD value-sum pairs, ordered from largest sum to lowest sum
var sortedLdValues = sortLdValuesBySum(ldValueMap, sumMap);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 292


WT&A API Specifications 18.3 KPI Chart Library

//For each of the first X most common LD values (i.e. LD values with the largest hours sum),
create the data series for the LD value
for(var i = 0; i < numberOfMostCommonLdValues && i < sortedLdValues.length; i++) {
createDataSeriesForLdValue(sortedLdValues[i].ldValue, ldValueMap);
}

//Create "Other" series (all other data not part of the X most common LD values get grouped
into a single 'Other' series)
createOtherDataSeries(ldValueMap, sortedLdValues);

return data;
}

//Create map from name of LD value to an array of records for that value. Each record is a
pair of values (date, hours)
function createLdMap(dataPoints) {
var ldValueMap = {};
for(var i = 0; i < dataPoints.length; i++) {
addRecordToLdValueMap(dataPoints[i], ldValueMap);
}
return ldValueMap;
}

//Add the current record of the result set to the LD Map


function addRecordToLdValueMap(dataPoint, ldValueMap) {
//Each LD value can have many records, so all of the records for the value are stored in an
array
var dataSeries = dataPoint.series;
var ldFieldValue = com.workforcesoftware.Util.Util.emptyString(dataSeries) ?
getLabelText("KPI_STD_LABELS", "NO_VALUE") : dataSeries;
var ldValueArray = ldValueMap[ldFieldValue];
if(!ldValueArray) {
//If array for this LD does not yet exist, create it
ldValueMap[ldFieldValue] = [];
ldValueArray = ldValueMap[ldFieldValue];
}
//Create the record with date and hours values and add to the array for this LD value
ldValueArray.push({"dateField" : dataPoint.x_value, "sumField" : dataPoint.y_value});
}

//Create map from 'LD value' --> 'sum of hours for LD value across entire time frame'
function createSumMap(ldValueMap) {
var sumMap = {};
for(var ldValue in ldValueMap) {
createSumRecordForLdValue(ldValue, ldValueMap, sumMap);
}
return sumMap
}

//Retrieves the array of records for specified LD value, sums up the hours, and creates a
single record with LD value and sum (and adds record to LD sum map
function createSumRecordForLdValue(ldValue, ldValueMap, sumMap) {
sumMap[ldValue] = 0;
var ldArray = ldValueMap[ldValue];
//Iterate through all of the values for that LD value, and sum up the hours
for(var i = 0; i < ldArray.length; i++) {
//The new sum value is equal to the old sum value plus the hours amount for this record
sumMap[ldValue] = sumMap[ldValue] + ldArray[i].sumField;

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 293


WT&A API Specifications 18.3 KPI Chart Library

}
}

//Uses the data in the ldValueMap and sumMap to create an array of LD value-sum pairs, ordered
from largest sum to lowest sum
function sortLdValuesBySum(ldValueMap, sumMap) {
var sortedLdValues = [];
for(var ldValue in ldValueMap) {
sortedLdValues.push({"ldValue" : ldValue, "sumField" : sumMap[ldValue]});
}

//Sort the array based on the largest sum (i.e. the most common values by hours)
//Highest sum should be first in array (thus use b - a rather than other way around)
sortedLdValues.sort(function (a, b) {
var diff = b.sumField - a.sumField ;
if(diff != 0) {
return diff;
} else {
//If same cost value, sort by LD value name (so we have a consistent ordering, in the
case of tie)
if(b.ldValue == a.ldValue) {
return 0;
} else if (b.ldValue > a.ldValue) {
return 1;
} else {
return -1;
}
}
});

return sortedLdValues;
}

//Take all of the records for a given LD value, and create all of the data points for the
chart
function createDataSeriesForLdValue(ldValue, ldValueMap) {
//Create a data point for each date that this LD value has records
var sumValuesByDateMap = {};
sumRecordsForLdValueByDate(ldValue, ldValueMap, sumValuesByDateMap);
createDataSeriesPoints(ldValue, sumValuesByDateMap);
}

function sumRecordsForLdValueByDate(ldValue, ldValueMap, sumValuesByDateMap) {


//Get array of all records for this LD value
var ldValueArray = ldValueMap[ldValue];
//Iterate through the records and add them to the sum (there is sum for each day, so add sum
to proper day's sum)
for(var j = 0; j < ldValueArray.length; j++) {
var sumForDate = sumValuesByDateMap[ldValueArray[j].dateField];
//If no sum record exists yet for the given date, create sum record
if(typeof sumForDate === "undefined" || sumForDate == null) {
sumValuesByDateMap[ldValueArray[j].dateField] = {"date": ldValueArray[j].dateField,
"sum" : ldValueArray[j].sumField};
} else {
//The new sum value is equal to the old sum value plus the hours amount for this record
sumForDate.sum = sumForDate.sum + ldValueArray[j].sumField;
}
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 294


WT&A API Specifications 18.3 KPI Chart Library

return sumValuesByDateMap;
}

//The rest of the LD values that aren't in the X most common, get summed together into a
single "Other" series.
//So here we take the remaining values not processed by createDataSeriesForLdValue and combine
into one series.
function createOtherDataSeries(ldValueMap, sortedLdValues) {
var otherLdValuesMap = {};
//Start with i = numberOfMostCommonLdValues, as we have already processed through
'numberOfMostCommonLdValues - 1' in
//createDataSeriesForLdValue. If the number of series (# of LD values) is <=
numberOfMostCommonLdValues, then this
//loop gets skipped as i = numberOfMostCommonLdValues will already be >=
sortedLdValues.length
for(var i = numberOfMostCommonLdValues; i < sortedLdValues.length; i++) {
var ldValue = sortedLdValues[i].ldValue;
sumRecordsForLdValueByDate(ldValue, ldValueMap, otherLdValuesMap);
}

createDataSeriesPoints(getLabelText("KPI_STD_LABELS", "OTHER"), otherLdValuesMap);


}

//Take all of the records for the "Other" series, and create all of the data points for the
chart
function createDataSeriesPoints(ldValue, sumValuesByDateMap) {
for(var key in sumValuesByDateMap) {
//Create a data point for each date that has values
data.push(createAssignmentGroupDataPoint(ldValue, null, null,
sumValuesByDateMap[key].date, sumValuesByDateMap[key].sum, null, null));
}
}

KPI Report URL Wildcards JavaScript


The following example script defines the report URL placeholder and wildcards to use in the report URL.
includeDistributedPolicy ("KPI_CHART_LIBRARY");
var rollingMonthHelper = new RollingMonthHelper();
var payCodes = [];
payCodes.push("ALL");
var asgnmtGrpArray = asgnmtGrps.toArray();
definePlaceholder("startDate", rollingMonthHelper.getStart());
definePlaceholder("endDate", rollingMonthHelper.getEnd());
definePlaceholder("payCodes", payCodes, "STD_ABSENCE_PAY_CODE");
definePlaceholder("asgnmtGrps", asgnmtGrpArray, "STD_ASSIGNMENT_GROUP_LIST");

Troubleshooting
The job log of the script using the KPI Chart Library will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 295


WT&A API Specifications 18.3 KPI Chart Library

Error Message Cause Solution


Neither buildDataPoints() nor An error is thrown if Pass a valid buildDataPoints().
defineQuery() methods are buildDataPoints() and defineQuery() is optional.
defined. buildDataPoints() is defineQuery() are not defined
required, defineQuery() is
optional
Required method An error is thrown if Pass a valid
aggregateDataPoints is not aggregateDataPoints() is not aggregateDataPoints()
defined defined
The methodName method cannot An error is thrown if a time frame
be called here since this KPI is not helper object is not available (i.e.,
time-based. the KPI is not time-based)
No category defined for this point An error is thrown if an invalid Pass a valid category
category is passed when creating
a data point
Object for x-value has invalid An error is thrown if value for x- The x-value should have a proper
date format value does not have a valid date date format
format
Object of class class is not valid An error is thrown if the x-value Pass a valid x-value type. The
for the x-value. has an invalid type valid types are null, Double, Date,
WDate, WDateTime, and String
No data series defined for this An error is thrown if there is no
point: data series is provided for the
[Category: category X-value: x- data point
value Y-value: y-value Asgnmt
grp: asgnmt grp App user: app
user]
Incorrect parameter getter used. An error is thrown if incorrect Pass a valid parameter type to
Parameter with ID parameterId is parameter type is passed to getParameter()
of type parameterType getParameter() method
Null is not a valid An error is thrown if no Pass a valid parameter type to
Kpi_parameter_type parameter type is passed to getParameter()
getParameter() method
Invalid Parameter ID An error is thrown when no Pass a valid parameter ID
'parameterId'. No parameter with parameter exists for the provided
this ID exists parameterId

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

getRandomColor()
Gets a random hex color. The length can be from 3 to 6 characters.

turnOffLinePoints()
Turns off actual points on a line chart.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 296


WT&A API Specifications 18.3 KPI Chart Library

Parameter Description
Config: Object The configuration data of the chart

defineReportUrlPlaceholder()
Defines placeholder/values to be used in report URL.
Parameter Description
placeHolderName: String The placeholder to be used in report URL
value: String or Array The value(s) to be used in report URL. If Array, reportParameterId must be
defined.
reportParameterId Only required if value is Array. Name of the report parameter that the values
are for.

formatNativeStringForServer()
Formats a NativeString to a JavaScript String.
Parameter Description
string: NativeString The string to be formatted

getPay_codeSet()
Returns the pay codes for the specified pay code set.
Parameter Description
id: String The name of the pay code set.

buildInClause()
Creates a SQL ‘IN’ clause given a list of items and a specified column name.
Parameter Description
items: Array The list of items for the ‘IN’ clause
columnName: String Name of the queried column

formatListForInClause()
Formats a list to be used in DBUtils.buildInClause() method by adding single quote (‘) around each item in the
list.
Parameter Description
list: List The list to be formatted

getDateFormatBasedOnTimeUnitConfig()
Returns date format applicable to current time unit config.

formatArrayForInClause()
Formats an array to be used in DBUtils.buildInClause() method by adding single quote (‘) around each item in
the array.
Parameter Description
array: Array The array to be formatted

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 297


WT&A API Specifications 18.3 KPI Chart Library

getPayCodeSetDescription()
Returns short description value for the specified pay code set.
Parameter Description
payCodeSetId: String The name of the pay code set

getEmployee()
Returns current employee from runtime context.

getEmployeeId()
Returns current employee ID from runtime context.

getAppUser()
Returns current app user from runtime context.

getAppUserId()
Returns current app user ID from runtime context.

createGlobalKpiDataQuery()
Create a KpiQuery javascript object to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query
groupByClause: String Text of group by clause of query
havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
dateTimeField: String Name of field with dttm value
queryParams: Array Parameters for query

createAppUserBasedKpiDataQuery()
Create a KpiQuery javascript object, based on app user, to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query
groupByClause: String Text of group by clause of query
havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
appUserField: String Name of field with app_user value
dateTimeField: String Name of field with dttm value
queryParams: Array Parameters for query

createAssignmentGroupBasedKpiDataQuery()
Create a KpiQuery javascript object, based on assignment group, to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 298


WT&A API Specifications 18.3 KPI Chart Library

groupByClause: String Text of group by clause of query


havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
asgnmtGrpField: String Name of field with asgnt_grp value
dateTimeField: String Name of field with dttm value
queryParams: Array Parameters for query

createGlobalKpiDataQueryWithDataSeries()
Create a KpiQuery javascript object, based on app user, to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query
groupByClause: String Text of group by clause of query
havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
dateTimeField: String Name of field with dttm value
dataSeriesField: String Name of field with data series value
dataSeriesTableAlias: String The table alias used in the query to reference the source table of the data
series
queryParams: Array Parameters for query

createAppUserBasedKpiDataQueryWithDataSeries()
Create a KpiQuery javascript object with data series, based on app user, to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query
groupByClause: String Text of group by clause of query
havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
appUserField: String Name of field with app_user value
dateTimeField: String Name of field with dttm value
dataSeriesField: String Name of field with data series value
dataSeriesTableAlias: String The table alias used in the query to reference the source table of the data
series
queryParams: Array Parameters for query

createAssignmentBasedBasedKpiDataQueryWithDataSeries()
Create a KpiQuery javascript object with data series, based on assignment group, to be used to run query.
Parameter Description
query: String Text of select/from/where clauses of query
groupByClause: String Text of group by clause of query
havingClause: String Text of having clause of query
orderByClause: String Text of order by clause of query
asgnmtGrpField: String Name of field with asgnt_grp value
dateTimeField: String Name of field with dttm value
dataSeriesField: String Name of field with data series value

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 299


WT&A API Specifications 18.3 KPI Chart Library

dataSeriesTableAlias: String The table alias used in the query to reference the source table of the data
series
queryParams: Array Parameters for query

createBasicGlobalCategoryDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object, for use with category points.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
y: Double Y-value of point

createBasicAssignmentGroupCategoryDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object, for use with category points for assignment
group.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
y: Double Y-value of point
asgnmtGroup: String Assignment group value of point

createBasicAppUserCategoryDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object, for use with category points for app user.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
y: Double Y-value of point
appUser: String App user value of point

createBasicCategoryDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object, for use with category points.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
y: Double Y-value of point
asgnmtGroup: String Assignment group value of point
appUser: String App user value of point

createBasicGlobalDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object.
Parameter Description
series: String Name of data series
x: Double or WFSDate or X- value of point
WFSDateTime

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 300


WT&A API Specifications 18.3 KPI Chart Library

y: Double Y-value of point

createBasicAssignmentGroupDataPoint()
A more basic version of createAppUserDataPoint for assignment group.
Parameter Description
series: String Name of data series
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
asgnmtGroup: String Assignment group value of point

createBasicAppUserDataPoint()
A more basic version of createAppUserDataPoint for app user.
Parameter Description
series: String Name of data series
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
appUser: String App user value of point

createBasicDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object.
Parameter Description
series: String Name of data series
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
asgnmtGroup: String Assignment group value of point
appUser: String App user value of point

createGlobalDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
color: String Color of point
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
z: Double Z-value of point

createAssignmentGroupDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object for assignment group.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 301


WT&A API Specifications 18.3 KPI Chart Library

Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
color: String Color of point
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
z: Double Z-value of point
asgnmtGroup: String Assignment group value of point

createAppUserDataPoint()
Create a Kpi_data_set_point to add to the KPIChartData object for app user.
Parameter Description
series: String Name of data series
category: String Category of point (for category-based axes)
color: String Color of point
x: Double or WFSDate or X- value of point
WFSDateTime
y: Double Y-value of point
z: Double Z-value of point
appUser: String App user value of point

copyDataPoint()
Creates a copy of the specified data point.
Parameter Description
point: Kpi_data_set_point The data set point to be copied

getPayCodeSetParameter()
Retrieves the pay code set with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for pay code set

getBankSetParameter()
Retrieves the bank set with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for bank set

getDataElementParameter()
Retrieves the data element with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for data element

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 302


WT&A API Specifications 18.3 KPI Chart Library

getStringParameter()
Retrieves the string with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for string

getBooleanParameter()
Retrieves the boolean with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for boolean

getDateParameter()
Retrieves the date with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for date

getDateTimeParameter()
Retrieves the date time with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for date time

getDoubleParameter()
Retrieves the double with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for double

getIntegerParameter()
Retrieves the integer with the specified ID.
Parameter Description
parameter_id: String Unique parameter identifier for integer

getStandardDateRange()
Returns a localized date range.
Parameter Description
start: WFSDate Start date of the date range
end: WFSDate End date of the date range

getStart()
Returns the start date-time of the timeframe.

getEnd()
Returns the end date-time of the timeframe.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 303


WT&A API Specifications 18.3 KPI Chart Library

getLastPoint()
Returns the last data point in the timeframe.

addTimeIntervalToDateTime()
Given a date-time, adds the defined interval of time and returns the result.
Parameter Description
dateTime: WFSDateTime Date-time to add interval

getDateSqlForTimeUnit()
Given the name of a date or date-time filed, creates the proper SQL required around the date field to group
all the records for an hour, day, week, or month together.
Parameter Description
dateField: String The field to get the date or date-time from

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 304


WT&A API Specifications 18.3 LD Data API

LD Data API
Overview and capabilities
The LD Data API lets you access Labor Distribution (LD) data from tables using LdMatchCondition defined
in API_UTIL library.

Prerequisites
To use this API, you should know the following:

• Basic JavaScript coding

Components
The components of the LD Data API are as follows:

• The LD_DATA_API Distributed JavaScript library


• The API_UTIL Distributed JavaScript library
o This will allow you to create LdMatchCondtion

Setup
No setup is necessary for the LD Data API. The distributed library is automatically available within
WT&A.

Use cases
Get an LD Record from a table using simple LdMatchCondition
// include the required libraries
includeDistributedPolicy("LD_DATA_API");

// creating ld match condition object with required parameters


var condition = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job3");
// creating a new instance of the LD Store Api
var api = new LDStoreAPI();
var result = api.lookupByMatchCondition(condition, WFSDate.today());
log.info("logging ld fields");
var logArray = [];
for (var i = 0; i < result.length; i++) {
logArray.push(result[i].ld2);
}
log.info(logArray.toString());

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 305


WT&A API Specifications 18.3 LD Data API

Get an LD Record from a table using simple LdMatchCondition but no


asOfDate, this will return all records
// include the required libraries
includeDistributedPolicy("LD_DATA_API");

// creating ld match condition object with required parameters


var condition = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job3");
// creating a new instance of the LD Store Api
var api = new LDStoreAPI();
var result = api.lookupByMatchCondition(condition);
log.info("logging ld fields");
var logArray = [];
for (var i = 0; i < result.length; i++) {
logArray.push(result[i].ld2);
}
log.info(logArray.toString());

Get data using OR based match condition


includeDistributedPolicy("LD_DATA_API");

var condition = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job3");


var condition2 = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job1");
condition.or(condition2);
var api = new LDStoreAPI();
var result = api.lookupByMatchCondition(condition, WFSDate.today());
log.info("logging ld fields");
var logArray = [];
for (var i = 0; i < result.length; i++) {
logArray.push(result[i].ld2);
}
log.info(logArray.toString());

Get data using AND based match condition


includeDistributedPolicy("LD_DATA_API");

var condition = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job1");


var condition2 = new LdMatchCondition(8, "LD1", MatchOperator.EQUALS, "1");
condition.and(condition2);
var api = new LDStoreAPI();
var result = api.lookupByMatchCondition(condition, WFSDate.today());
log.info("logging ld fields");
var logArray = [];
for (var i = 0; i < result.length; i++) {
logArray.push(result[i].ld2);
}
log.info(logArray.toString());

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 306


WT&A API Specifications 18.3 LD Data API

Get data from multiple LD tables using LdMatchCondition


includeDistributedPolicy("LD_DATA_API");

var condition = new LdMatchCondition(8, "LD2", MatchOperator.EQUALS, "job1");


var condition2 = new LdMatchCondition(9, "LD10", MatchOperator.EQUALS, "ABC10");
condition.and(condition2);

//this will create inner join for table LD8 and LD9 on LD8.LD2 = LD9.LD1
condition.addJoinCriteria(8, "LD2", 9, "LD1");
var api = new LDStoreAPI();
var result = api.lookupByMatchCondition(condition, WFSDate.today());
log.info("logging ld fields");
var logArray = [];
for (var i = 0; i < result.length; i++) {
logArray.push(result[i].ld2);
}
log.info(logArray.toString());

Troubleshooting
The job log of the script using the LD Store API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.
Some common error messages, their causes, and the solution:
Error Message Problem Solution
NaN received in summation The API will not throw an error if Make sure the field is a data type that
the field is not supposed to be supports the sum aggregate.
summed, but may return invalid
values.

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The LD Store API consists of one public initializer component:
o LDStoreAPI. It contains the following public method:
▪ lookupByMatchCondition

LDStoreAPI
Creates a new instance of the LD Store API.

lookupByMatchCondition (matchCondition: LdMatchCondition, asOfDate: WFSDate)


Performs a lookup of the LD tables using the provided LdMatchCondition and returns matching rows as
DbRec scriptables.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 307


WT&A API Specifications 18.3 LD Import API

LD Import API
Overview and Capabilities
The LD Import API provides a mechanism for performing common LD imports.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding knowledge
• Understanding of policies and their settings
• Understanding of how and what LD Import should work
• Knowledge of which methods must be called first before the import can be initiated. This
documentation will detail these methods.

Components
This API consists of the following component(s):
• The distributed JavaScript library LD_IMPORT_LIBRARY_API

Setup
No setup is necessary for the LD Import API. The distributed library is automatically available within WT&A.

Use Cases
Importing Records from Using LD Import
Example 1: Importing records from a CSV file while validating the character set of a file
includeDistributedPolicy("LD_IMPORT_LIBRARY");

// set values to be passed in the API for readability


var DESTINATION_TABLE_NUMBER = 43;
var KEY_FIELD_COUNT = 1;
var FILE_NAME = "INT_1714_LD_import_Test_data1.csv";
var IMPORT_PATH = "workforce/RegTests/ImportTests/";
var ARCHIVE_FILE = false;
var FIELD_NAMES = ['LD1’,
’SHORT_DESCRIPTION’,
’EFF_DT’,
’END_EFF_DT’,
’OTHER_STRING1’,
’OTHER_STRING2’,
’OTHER_STRING3’,
’OTHER_STRING4'];
// set delimiter value according to csv file
var DELIMITER = ",";
// set date format according to csv file. This is optional and default value is ‘yyyy-MM-dd’
already
var STANDARD_DATE_FORMAT = "yyyy-MM-dd";
// define a mapping function between csv and sql table
// record is a keyword and enables us to access ‘current row’ of csv data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 308


WT&A API Specifications 18.3 LD Import API

// record.getStringValue(“column_name”) will return value of “column_name” of the current row


from csv file, as string
// mapping function is required
function mappingFunction(record) {
var obj = {
"ld1": record.getStringValue("LD1"),
"other_string2": record.getStringValue("OTHER_STRING2"),
"other_string3": record.getStringValue("OTHER_STRING3"),
"other_string4": record.getStringValue("OTHER_STRING4"),
"short_description": record.getStringValue("SHORT_DESCRIPTION"),
"eff_dt": record.getDateValue("EFF_DT", null, WFSDate.VERY_EARLY_DATE),
"end_eff_dt": record.getDateValue("END_EFF_DT", null, WFSDate.VERY_LATE_DATE),
"other_string1": record.getStringValue("OTHER_STRING1")
};
return obj;
}
// define a validation function to sort out any invalid data
// this is optional
function validationFunction(record, validationErrors) {
if (isBlank(record.getStringValue("LD1"))) {
validationErrors.push("No LD1 specified");
}
}
// now include the distributed ld import library to enable API in scope
includeDistributedPolicy("LD_IMPORT_LIBRARY");
// creating a new instance of the API
var ldImportApi = new LdImportAPI(mappingFunction, validationFunction);
// setinteger number of the LD table that is the destination of the import
// a value of 1 will make the destination LD1, and so on.
ldImportApi.setDestinationTable(DESTINATION_TABLE_NUMBER);
// set key field count. What?
ldImportApi.setKeyFieldCount(KEY_FIELD_COUNT);
// set standard dafe format, if needed
ldImportApi.setStandardDateFormat(STANDARD_DATE_FORMAT);
// specifying the character set
ldImportApi.useCharacterSet(“UTF-8”);
// set enforce character set validation
ldImportApi.setEnforceCharsetEncoding(true);
// start the import
ldImportApi.importDataFromFile(IMPORT_PATH, FILE_NAME, FIELD_NAMES, ARCHIVE_FILE,
DELIMITER);

Example 2: IMPORTING RECORDS FROM SQL TABLE


includeDistributedPolicy("LD_IMPORT_LIBRARY");

includeDistributedPolicy("LD_IMPORT_LIBRARY");
// mapping function is required
function mappingFunction(record) {
var obj = {
"ld1": record.getStringValue("LD1"),
"other_string2": record.getStringValue("OTHER_STRING2"),
"other_string3": record.getStringValue("OTHER_STRING3"),
"other_string4": record.getStringValue("OTHER_STRING4"),
"short_description": record.getStringValue("SHORT_DESCRIPTION"),
"eff_dt": record.getDateValue("EFF_DT", null, WFSDate.VERY_EARLY_DATE),
"end_eff_dt": record.getDateValue("END_EFF_DT", null, WFSDate.VERY_LATE_DATE),
"other_string1": record.getStringValue("OTHER_STRING1")
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 309


WT&A API Specifications 18.3 LD Import API

return obj;
}

// create a new instance of the API


var ldImportApi = new LdImportAPI(mappingFunction, null);
// setting parameters
ldImportApi.setDestinationTable(target);
ldImportApi.setKeyFieldCount(keyCount);
ldImportApi.wipeDataBeforeLoading(wipe);
ldImportApi.setStandardDateFormat(dateFmt);
ldImportApi.createRetroTriggers(createTriggers);
ldImportApi.setEmployeeMatchField(eMatch);
ldImportApi.setAssignmentMatchField(aMatch);

var query = "select LD1,OTHER_STRING1,OTHER_STRING2,OTHER_NUMBER1,EFF_DT,END_EFF_DT from LD18


where OTHER_STRING3 = ? order by LD1,EFF_DT";
var params = ['TT26764'];
// start the import
ldImportApi.importDataFromSQL("TT26764", query, params);

Importing Records Using a Decoder-Based LD Import


Example 1: Importing records from a CSV file while validating the character set of a file
var filePath = "workforce/sample_data/mtsdata/external_data/importcsv/";
var fileName = "INT_362_InternalOrderUpload.txt";
var fieldNames =
"INTERNAL_ORDER_ID,DEPARTMENT_ID,DESCRIPTION,SHIP_DATE,PRIMARY_ORDER,LOCKED_UNLOCKED".split(",
");

var parms = {
decoderPolicy: "INT_362_LD_DECODER",
autoTrimValues: true,
sourceType: Import_source.CSV
};
var ldImportApi = new DecoderLdImportAPI(parms);
ldImportApi.setDestinationTable(42);
ldImportApi.setKeyFieldCount(2);
ldImportApi.wipeDataBeforeLoading(true);
ldImportApi.useCharacterSet(“UTF-8”);
ldImportApi.setEnforceCharsetEncoding(true);
ldImportApi.importDataFromFile(filePath, fileName, fieldNames);

Troubleshooting
The job log of the script using the LD Import API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.
Error Message Problem Solution
Destination table must be a The number supplied to Supply a valid number
number between 1 and setDestinationTable function is out
<somenumber> bounds
OR

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 310


WT&A API Specifications 18.3 LD Import API

Destination LD Table must be


specified
Key field count must be a Number supplied to Supply a valid number
non-zero number setKeyFieldCount is invalid
Retro trigger function The parameter supplied to Supply a valid function
specified must be a function. setRetroTriggerFunction is either not
Instead it was… a function, or a function with
OR incorrect argument length
Retro trigger function
specified must accept two
arguments: the LD record and
a database connection…
File <filename> is missing The field list supplied does not match Correct any discrepancy and retry
expected fields - unable to with the fields present in the
import data provided filename
Unable to import record due Self-explanatory Correct any error in file and retry
to validation errors
Unable to identify employee
<employeeMatch>,
assignment <asgnmtMatch>;
retro triggers cannot be
created
ID was not specified in a valid
format. Valid formats are
string, integer, or
GeneratedId
No employee match field
specified for retro-trigger
creation
OR
No assignment match field
specified for retro-trigger
creation
Required key field LD <key> The mentioned fields are not Make sure source data is valid
not populated populated in source data
OR
Required field eff_dt not
populated
OR
Required field end_eff_dt not
populated
Archive file path has not been doArchiveFile parameter was passed Either set doArchiveFile to false or
defined as true, but archive file path and/or supply valid file path and name
OR name were not supplied
Archive file path has not been
defined

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 311


WT&A API Specifications 18.3 LD Import API

No decoder policy specified DecoderLdImportAPI was used but Supply a decoder policy id
decoder policy was not provided
Invalid source type Source type can either be CSV or Supply a valid source type
<sourceType> specified for FIXED_WIDTH
Decoder. Valid options are
[options]
XX method on YY called There are three types of LD Import N/A. only relevant/valid methods can be
APIs that can be initialized. called

• WebServiceLdImportAPI
• DecoderLdImportAPI
• LdImportAPI

Some functions are not applicable to


all LD Import API types. Such as
‘importDataFromSQL’ cannot be
called when the LdImportAPI type is
WebService
Table 58 LD Import API typical error messages, root problems, and solution

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The following is a summary of the available methods and common uses:

LDImportAPI
LdImportAPI(mappingFunction: function, validationFunction: function)
Creates a new instance of the LD Import API, capable of running imports from a SQL source, CSV file, or Fixed-
Width file. Takes two functions as parameters, mappingFunction and validationFunction, where
validationFunction is optional.

DecoderLdImportAPI(params: Object)
Creates a new instance of the LD Import API, capable of running imports from a SQL source, CSV file, or Fixed-
Width file. Since it is decoder based, a mappingFunction is not supplied. Instead, takes a JS Object as the
parameter with the following properties:
{
decoderPolicy: String
autoTrimValues: Boolean <optional, default = false>,
sourceColumnOverride: String <optional, default = “SOURCE”>,
sourceType: String <optional, default = “CSV”, possible values = CSV|FIXED_WIDTH>
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 312


WT&A API Specifications 18.3 LD Import API

WebServiceLdImportAPI(decoderPolicy: String)
Creates a new instance of the LD Import API, capable of running imports from a ResultSet using web services.
This type of LdImport is made use of by E2G and would not be needed directly in normal circumstances.

setMappingFunction(mappingFunction: function)
Only needed with DecoderLdImportAPI if there are fields that need to be mapped which the decoder does
not handle.

setValidationFunction(validationFunction: function)
Only needed with DecoderLdImportAPI if a validationFunction must be specified.

getNumFailedRecords() -> int


Returns number of records that failed to process.

getTotalRecords() -> int


Returns total number of records processed.

setDestinationTable(table: int)
Sets the destination LD table for the import. Must be set before the LD import can be run.

setKeyFieldCount(keyFieldCount: int)
The number of LD fields that form the key of the LD data. Defaults to 1.

setStandardDateFormat(format: String)
Sets the standard date format for all dates processed by the LD import. Default is "yyyy-MM-dd".

setLocale(locale: Locale)
Sets the locale for the date format for all dates processed by the LD import.

wipeDataBeforeLoading(doWipe: Boolean)
Sets the option that determines if the LD import will first wipe all data in the destination table before
importing. Defaults to false.

createRetroTriggers(createRetroTriggers: Boolean)
Indicates whether the LD import will create retro triggers or not. Defaults to false.

setRetroTriggerFunction(retroTriggerFunction: function)
Sets the function to use to determine which assignments should have retro triggers created when a change is
detected to an LD record. This function should accept two arguments, the LD record that caused the retro
trigger to be created and a connection to the local database, and should return an array of the assignment
IDs for the assignments that should have the retro triggers applied to them.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 313


WT&A API Specifications 18.3 LD Import API

setEmployeeMatchField(employeeMatchField: String)
Sets the employee match field (required for retro triggers).

setAssignmentMatchField(assignmentMatchField: String)
Sets the assignment match field (required for retro triggers).

useJoinImport(useJoinImport: Boolean)
Indicates whether to use the ld_join or ld table for import.

setArchivePathAndName(path: String, name: String)


Sets the archive path and file name (required if file archiving is enabled).

setAllowExtraColumns(doAllow: Boolean)
Indicates if extra columns in the source data should be tolerated. Default is true.

useCharacterSet(charSet: String)
Defines the character set to use for the input file.

setEncrypted(encrypted: Boolean)
Indicates if the source file is encrypted.

setEnforceCharsetEncoding(enforceCharsetEncoding: Boolean)
Indicates if the character set in the file should be same as mentioned. Defaults to false.

importSingleRecord(sourceData: JSObject)
Loads data from a JavaScript object into an LD table.

importDataFromFile: function (filePath: String, fileName: String, fields: [String],


doArchiveFile: Boolean <default=false>, delimiter: String <default=",">)
Loads data from a file into an LD table. Called by outside process to initiate processing of LD data.

importDataFromSQL: function (dbConnectionInfo: String, query: String <can be


parameterized>, params: [any] <only if the query was parameterized>)
Loads data from a source Table into an LD table.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 314


WT&A API Specifications 18.3 Line Approval API

Line Approval API


Overview and Capabilities
The Line Approval API provides a mechanism for scripts to use in order to load and maintain routing
information for Line Approvals. This information is used to determine which users are allowed to perform
Line Approvals on a given slice of time, and at what point in the approval process those users will see that
time slice. The API includes support for adding additional routing information to the existing routings that
are already loaded, replacing the existing routing information with new data that is being processed, and for
clearing out the existing routing information.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• How Line Approvals function in WorkForce Time and Attendance

Components
This API consists of the following component(s):
1. The distributed JavaScript library LINE_APPROVAL_API.
2. The RoutingApproval Java class.

Setup
No setup is necessary for the Line Approval API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Adding New Routings to the Existing Routing Data
The simplest use case for the Line Approval API is to just add additional routings to the existing routing data,
without changing any of those existing records. This would be used if your source data is only defining new
routings that need to be created, or if the routing data is being cleared out ahead of time through some other
means.
The following example demonstrates how new routing data can be added to the existing routing data. It
iterates through the records in a file, constructs a new RoutingApproval for each record, and then adds that
RoutingApproval into the routing data.

Example: Adding a new routing to the existing routing data


includeDistributedPolicy("LINE_APPROVAL_API");

// Get the file data to be processed. This method is assumed to return an


// object representing file data as a FileManager object
var file = getFileData();

// Create a new instance of the line approval API. This is done in a try-finally

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 315


WT&A API Specifications 18.3 Line Approval API

// block in order to ensure that the API is cleaned up correctly when it is no


// longer needed
var api;

try {
api = new LineApprovalAPI();

// Iterate over the records in the file


while (file.next() ) {
// Load the routing data from the current record in the file
var routingParms = {
userLoginId: file.getStringValue("LOGIN_ID"),
matchPolicy: "LINE_APPROVAL_MATCH",
matchValue: file.getStringValue("MATCH_VALUE"),
lineRole: "LINE_APPROVER_ROLE",
minApproval: 0,
maxApproval: file.getNumericalValue("MAX_APPROVAL_LEVEL"),
nextApproval: file.getNumericalValue("NEXT_APPROVAL_LEVEL"),
rejectApproval: 0,
rightType: "PRIMARY"
};

// Create the routing approval for the data being processed


var routingApproval = new RoutingApproval(routingParms);

// Add the routing approval to the database


api.importSingleRoutingApproval(routingApproval);
}
}
finally {
// Clean up the API now that it is done being used
api.close();
}

Replacing the Existing Routing Information


One of the most common ways routing data is provided is in a file that contains all of the routing data that
should currently exist. In this case, all routing data except for the data being imported should be removed
during the import process. The Line Approval API includes two different methods of supporting this sort of
behavior.
The first approach is to replace all of the existing routing data with the new data being imported. This
assumes that the file includes data for every user that should be able to approve line items, and that nothing
that is not included in the file should be kept. The following script example demonstrates using the Line
Approval API to replace all of the existing routing data with new data from a source file:

Example 1: Replacing routing information for all users


includeDistributedPolicy("LINE_APPROVAL_API");

// Get the file data to be processed. This method is assumed to return an


// object representing file data as a FileManager object
var file = getFileData();

// Define an array to hold the routing approval data that should exist after
// the import is complete
var routingApprovals = [];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 316


WT&A API Specifications 18.3 Line Approval API

// Iterate over the records in the file


while (file.next() ) {
// Load the routing data from the current record in the file
var routingParms = {
userLoginId: file.getStringValue("LOGIN_ID"),
matchPolicy: "LINE_APPROVAL_MATCH",
matchValue: file.getStringValue("MATCH_VALUE"),
lineRole: "LINE_APPROVER_ROLE",
minApproval: 0,
maxApproval: file.getNumericalValue("MAX_APPROVAL_LEVEL"),
nextApproval: file.getNumericalValue("NEXT_APPROVAL_LEVEL"),
rejectApproval: 0,
rightType: "PRIMARY"
};

// Create the routing approval for the data being processed


var routingApproval = new RoutingApproval(routingParms);

// Add the new routing approval to the array of data being tracked
routingApprovals.push(routingApproval);
}

// Create a new instance of the line approval API. This is done in a try-finally
// block in order to ensure that the API is cleaned up correctly when it is no
// longer needed
var api;

try {
api = new LineApprovalAPI();

// Use the API to replace the routing approvals. Any existing routing approval
// not defined in the provided array will be removed.
api.replaceAllRoutingApprovals(routingApprovals);
}
finally {
// Clean up the API now that it is done being used
api.close();
}

The second approach is to replace all of the existing routing data for the users with the new data being
imported, but to leave the routing data for users that aren’t in the import data set unchanged. This assumes
that the file includes data for only the users that have updates to their routing data. The following script
example demonstrates using the Line Approval API to replace the existing routing data for users that have
new data from a source file:

Example 2: Replacing routing information for just the users with new data
includeDistributedPolicy("LINE_APPROVAL_API");

// Get the file data to be processed. This method is assumed to return an


// object representing file data as a FileManager object
var file = getFileData();

// Define an array to hold the routing approval data that should exist after
// the import is complete

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 317


WT&A API Specifications 18.3 Line Approval API

var routingApprovals = [];

// Iterate over the records in the file


while (file.next() ) {
// Load the routing data from the current record in the file
var routingParms = {
userLoginId: file.getStringValue("LOGIN_ID"),
matchPolicy: "LINE_APPROVAL_MATCH",
matchValue: file.getStringValue("MATCH_VALUE"),
lineRole: "LINE_APPROVER_ROLE",
minApproval: 0,
maxApproval: file.getNumericalValue("MAX_APPROVAL_LEVEL"),
nextApproval: file.getNumericalValue("NEXT_APPROVAL_LEVEL"),
rejectApproval: 0,
rightType: "PRIMARY"
};

// Create the routing approval for the data being processed


var routingApproval = new RoutingApproval(routingParms);

// Add the new routing approval to the array of data being tracked
routingApprovals.push(routingApproval);
}

// Create a new instance of the line approval API. This is done in a try-finally
// block in order to ensure that the API is cleaned up correctly when it is no
// longer needed
var api;

try {
api = new LineApprovalAPI();

// Use the API to replace the routing approvals. Any existing routing approval
// not defined in the provided array will be removed for the users associated
// with the new routing approvals. Existing routing data for users not specified
// in the new data will not be modified.
api.replaceRoutingApprovalsForUsers(routingApprovals);
}
finally {
// Clean up the API now that it is done being used
api.close();
}

Clearing Routing Information


The Line Approval API can also be used to clear out information associated with a particular Match Policy.
This removes all of the existing routing information for that Match Policy, allowing new data to be loaded in
its place.
The following script example demonstrates removing all of the existing routing information for the Match
Policy “LINE_APPROVAL”:

Example: Clearing routing information


includeDistributedPolicy("LINE_APPROVAL_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 318


WT&A API Specifications 18.3 Line Approval API

// Create a new instance of the line approval API. This is done in a try-finally
// block in order to ensure that the API is cleaned up correctly when it is no
// longer needed
var api;

try {
api = new LineApprovalAPI();

// Define the name of the match policy whose routing data should be cleared
var matchPolicy = "LINE_APPROVAL";

// Clear all of the routing data associated with that match policy
api.clearAllRoutingApprovals(matchPolicy);
}
finally {
// Clean up the API now that it is done being used
api.close();
}

Troubleshooting
The job log of the script using the Line Approval API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


Unknown object type The array of routing details Ensure that all of the elements being
specified in routing provided when replacing the added to the array provided as an
approval array. Object was existing routing details included an argument when replacing the existing
expected to be of type object of a data type other than routing approvals are
RoutingApproval RoutingApproval RoutingApproval objects.
No user found with login ID The user login ID specified on a Ensure that the user login ID matches
LOGIN_ID RoutingApproval record did not a valid login ID value for the
match the login ID value for any of WorkForce Time and Attendance user
the user records in WorkForce that should receive the routing
Time and Attendance. approval.
Role ROLE_NAME is not a The line role specified on a Ensure that the line role specified
valid Line Approver role. RoutingApproval record did not matches a role defined in WorkForce
Instead it is a ROLE_TYPE match a Line Role policy defined in Time and Attendance that is of the
role WorkForce Time and Attendance. Line type (as opposed to General or
Group)
Invalid value The value provided on a Ensure that all of the supplied
APPROVAL_LEVEL for field RoutingApproval for one of the approval levels fall within the allowed
FIELD. Valid values are approval levels (min, max, next, or bounds for that type of approval
between MIN_VALUE and reject) was outside of the allowed level.
MAX_VALUE bounds for that type of approval
level.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 319


WT&A API Specifications 18.3 Line Approval API

This instance of the Line Additional calls were made to the Ensure that close() is not called until
Approval API is disabled API after close() had already been no further operations remain to be
and no further action can called. performed by the API.
be taken with it. Please
create a new instance of
the API in order to continue
with any further actions.
Table 59: Line Approval API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Line Approval API consists of the following component(s):
1. The RoutingApproval, which defines the information for a single routing of line items for a user
2. The LineApprovalAPI, which defines operations for updating the routing approvals within WorkForce
Time and Attendance
See the contents of the LINE_APPROVAL_API policy in the Distributed JavaScript Library category for full
documentation on these methods. The following is a summary of the available methods and common uses:

RoutingApproval
RoutingApproval(parms)
Defines a new routing approval with the indicated settings. Once created, a RoutingApproval can no longer
be modified. These RoutingApprovals can then be used by the LineApprovalAPI for updating the routing
information for line items within WorkForce Time and Attendance.
The available parameter values are as follows:
Parameter Name Description
userLoginId The login ID of the user who should receive the routing approval
matchPolicy The policy ID of the match policy associated with this approval
matchValue The value that needs to match the TIME_SHEET_DETAIL_MATCH_VAL
result in order for a line to be eligible for approval
lineRole The Line Role associated with the approval rights
minApproval The minimum approval level a line item can have to be visible to the
approver. Defaults to 0 if not specified.
maxApproval The maximum approval level a line item can have to be visible to the
approver. Defaults to 99 if not specified.
nextApproval The approval level that will be assigned to the line item after it’s
approved by this user. Defaults to 100 if not specified.
rejectApproval The approval level that will be assigned to the line item if this user
rejects it. Defaults to 0 if not specified.
rightType Indicates the type of line right represented by this record. One of either
PRIMARY or BACKUP. Defaults to PRIMARY if not specified.
description A description of the rights
Table 60: Available parameters when instantiating a RoutingApproval object

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 320


WT&A API Specifications 18.3 Line Approval API

LineApprovalAPI
LineApprovalAPI(parms)
Creates a new instance of the Line Approval API, using the specified parameters. The available parameters
that can be set are:
Parameter Name Description
connection A connection to the local WorkForce Time and Attendance database to
use for writing changes. If no connection is specified in the parameters,
the API will create its own connection to use and changes will be
automatically committed as soon as they are applied.
debug Determines if additional debug output should be written to the job log
Table 61: Available parameters when instantiating a LineApprovalAPI object

importSingleRoutingApproval(routingApproval)
Appends a new routing approval record to the existing routing approval data, using the provided settings.
Existing routing approval data remains unmodified.

replaceAllRoutingApprovals(routingApprovals)
Removes all of the existing routing approval data and replaces it with the data defined by the provided array
of RoutingApproval records. Even if the new data does not contain information for a particular user, the
existing routing approvals for that user will be removed.

replaceRoutingApprovalsForUsers(routingApprovals)
Removes all of the existing routing approval data and replaces it with the data defined by the provided array
of RoutingApproval records for the users with routing approvals defined in the provided array. If the new
data does not contain information for a particular user, the existing routing approvals for that user will
remain unchanged.

clearAllRoutingApprovals(matchPolicy)
Removes all of the existing routing approval information for the specified match policy.

close()
Cleans up all connections used by the API. This needs to be called, regardless of whether a connection was
supplied when instantiating the API, in order to prevent connection leaks by the script.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 321


WT&A API Specifications 18.3 Person Data API

Person Data API


Overview and Capabilities
The Person Data API provides a way to access employee, assignment, and user information from within a
script.
The Person Data API allows a script to access information for the employee, assignment, or user records
based on match conditions. The data returned is read only, allowing a script to look up the information to
drive later calculations but not to add or modify any of the values in that data directly. (To actually change
the employee, assignment, or user data, an Employee Import should be used.)
The match conditions used to look up the desired data can be a simple, standalone condition
(“employee.hr_status = 'A'”) or can be combined together to form much more complicated
structures (“asgnmt.policy_profile = "PROFILE_A" and (asgnmt.schedule_template
= "TEMPLATE_A" or asgnmt.schedule_template = "TEMPLATE_B")”). This gives the script
the flexibility to define whatever conditions are necessary in order to pull the desired information.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
1. The PERSON_DATA_API Distributed JavaScript library
a. This automatically includes the API_UTIL Distributed JavaScript library
2. The MatchCondition, which defines a condition to select employee, assignment, or user records.

Setup
No setup is necessary for the Person Data API. The distributed library is automatically available in WorkForce
Time and Attendance.

Use Cases
Looking up a single effective-dated employee record
This script excerpt demonstrates how the Person Data API can be used to find a single effective-dated
employee record. A match condition is defined that matches any employee with a display ID of “E156784”,
and then the API retrieves the data for the matching employee that is effective on the current system date.
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 322


WT&A API Specifications 18.3 Person Data API

// will match any employee with the display ID of E156784


var condition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E156784");

// Define the effective date that we are interested in


var effDt = WFSDate.today();

// Retrieve the employee data for that date


var employee = personDataAPI.getEmployeeRecord(condition, effDt);

if (employee === null) {


log.info("No employee data was found on " + effDt + " for employee E156784");
}
else {
// Do something with the data, based on the needs of the script
// As an example, log out the employee's HR status on that date
log.info("HR status for employee E156784 on " + effDt + " is " +
employee.hr_status);
}

Note: The condition used here must match exactly zero or one employees. If more than one employee
matches the condition, an exception will be generated.

Looking up the entire effective-dated history for an employee


This script demonstrates how the Person Data API can be used to look up the entire effective-dated history
for an employee. A match condition is defined that matches any employee with a display ID of “E284224”,
and then the API retrieves all of the effective-dated information for the matching employee.
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition


// will match any employee with the display ID of E284224
var condition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E284224");

// Retrieve all of the effective-dated data for the employee


var data = personDataAPI.getEmployeeHistory(condition);

if (data.length === 0) {
log.info("No employee data was found for employee E284224");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < data.length; ++i) {
var effDatedRecord = data[i];
log.info("Employee E284224 has a record effective from " +
effDatedRecord.eff_dt + " through " + effDatedRecord.end_eff_dt);
}
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 323


WT&A API Specifications 18.3 Person Data API

If the specified match condition doesn’t match any employees, then the array of records returned will have a
zero length. If more than one employee matches the condition specified, then an exception will be
generated.

Looking up all matching employees


The previous examples have shown various ways of accessing data for a single employee. However,
sometimes a script may have a need to access data for a whole set of employees. For instance, it may need
to evaluate all employees in a given location. The following script example shows how the Person Data API
can be used to find all employees matching a given condition:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition


// will match any employee with a home country code of "USA"
var condition = new MatchCondition("employee", "home_country_code",
MatchOperator.EQUALS, "USA");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the employees that match the condition on that date
var employees = personDataAPI.getAllEmployees(condition, effDt);

if (employees.length === 0) {
log.info("No employee data was found for country code USA");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < employees.length; ++i) {
var employee = employees[i];
log.info("Employee " + employee.display_employee +
" has a country code of USA on " + effDt);
}
}

If the specified condition doesn’t match any employees, then the array of records returned will be empty.

Looking up an employee master record


The following script example shows how to access the employee master record for an employee meeting a
particular condition. Typically, this would be used when you already have a specific employee you are
working with, and you need to determine which email address would be associated with that employee. In
this example, we are looking up the employee master record for the employee with display ID “E837645”:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition


// will match the employee with display ID "E837645"
var condition = new MatchCondition("employee", "display_employee",

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 324


WT&A API Specifications 18.3 Person Data API

MatchOperator.EQUALS, "E837645");

// Retrieve the employee master record for the matching employee


var employeeMaster = personDataAPI.getEmployeeMaster(condition);

if (employeeMaster === null) {


log.info("No employee master data was found for display ID E837645");
}
else {
// Do something with the data, based on the needs of the script
log.info("The email address for employee E837645 is " +
employeeMaster.email_address);
}

Note: The condition used here must match exactly zero or one employees. If more than one employee
matches the condition, an exception will be generated.

Looking up active employees


Many times it is desirable to identify only active employees, since most processing should not include
employees that are terminated. Because an active employee is defined by the status of all of the
assignments that belong to that employee, however, this can often require a deal of extra processing in order
to filter out the terminated employees. The Person Data API includes a couple of additional methods in order
to facilitate the identification of these sorts of employees.

Example 1: Getting employees with at least one active assignment


The following script example demonstrates how to find all matching employees that have at least one active
assignment on the indicated date. Soft-terminated assignments are considered to be inactive for purposes of
this example.
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition


// will match any employee with a home country code of "USA"
var condition = new MatchCondition("employee", "home_country_code",
MatchOperator.EQUALS, "USA");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the employees that match the condition on that date
// that have at least one active assignment
var employees = personDataAPI.getActiveEmployees(condition, effDt);

if (employees.length === 0) {
log.info("No active employee data was found for country code USA");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < employees.length; ++i) {
var employee = employees[i];
log.info("Employee " + employee.display_employee +

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 325


WT&A API Specifications 18.3 Person Data API

" has a country code of USA on " + effDt);


}
}

If no active employees match the specified condition, then an empty array will be returned.

Example 2: Getting employees with at least one active or soft-terminated assignment


The following script example demonstrates how to find all matching employees that have at least one
assignment that is not hard terminated on the indicated date. Both active and soft-terminated assignments
will be returned in this example.
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the employee. This condition


// will match any employee with a home country code of "USA"
var condition = new MatchCondition("employee", "home_country_code",
MatchOperator.EQUALS, "USA");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the employees that match the condition on that date
// that have at least one active or soft-terminated assignment
var employees = personDataAPI.getActiveOrSoftTerminatedEmployees(condition, effDt);

if (employees.length === 0) {
log.info("No active employee data was found for country code USA");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < employees.length; ++i) {
var employee = employees[i];
log.info("Employee " + employee.display_employee +
" has a country code of USA on " + effDt);
}
}

If no employee with at least one active or soft-terminated assignment matches the specified condition, then
an empty array will be returned.

Looking up a single effective-dated assignment record


The following script excerpts demonstrate how the Person Data API can be used to find a single effective-
dated assignment record.

Example 1: Employee ID is already known


If the Person Data API has already been used to identify an employee, and you desire to lookup information
about an assignment related to the employee, then this example shows how the API is able to lookup an
assignment matching a given condition for that employee.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 326


WT&A API Specifications 18.3 Person Data API

includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Employee data is looked up in some fashion, using the API


var employee = getEmployeeData();

// Define the match condition to identify the assignment. This condition


// will match the primary assignment for the employee
var condition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// The unique ID for the employee


var employeeId = employee.employee;

// Retrieve the assignment that matches the condition on that date


var assignment = personDataAPI.getAsgnmtRecordForEmployee(employeeId, condition,
effDt);

if (assignment === null) {


log.info("No primary assignment was found for employee " +
employeeId + " on " + effDt);
}
else {
// Do something with the data, based on the needs of the script
log.info("Primary assignment for employee " + employeeId + "
belongs to policy profile " + assignment.policy_profile + " on " + effDt);
}

Note: The condition used here must match exactly zero or one assignments for the indicated employee. If
more than one assignment matches the condition, an exception will be generated.

Example 2: Employee needs to be found based on a condition


If the employee the assignment belongs to is not already known, then the following script example shows
how the Person Data API is used to find an assignment matching a particular condition and belonging to an
employee matching a second condition.
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define a condition to identify the employee. In this case, the


// condition will match the employee with the ID E927288
var employeeCondition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E927288");

// Define the match condition to identify the assignment. This condition


// will match the primary assignment for the employee
var assignmentCondition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 327


WT&A API Specifications 18.3 Person Data API

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve the assignment that matches the assignment condition, for the
// employee matching the employee condition, on that date
var assignment = personDataAPI.getAsgnmtRecord(employeeCondition,
assignmentCondition, effDt);

if (assignment === null) {


log.info("No primary assignment was found for the matching employee on " +
effDt);
}
else {
// Do something with the data, based on the needs of the script
log.info("Primary assignment for the matching employee " +
belongs to policy profile " + assignment.policy_profile + " on " + effDt);
}

Note: The employee condition used here must match exactly zero or one employees and the assignment
condition must match exactly zero or one assignments belonging to the matching employee. If more
than one employee or assignment matches the conditions, an exception will be generated.

Looking up the entire effective-dated history for an assignment


The following script excerpts demonstrate how the Person Data API can be used to look up the entire
effective-dated history for an assignment.

Example 1: Employee ID is already known


If the Person Data API has already been used to identify an employee, and you desire to lookup information
about an assignment related to that employee, then this example shows how the API is able to lookup the
entire effective-dated history for an assignment matching a given condition for that employee:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Employee data is looked up in some fashion, using the API


var employee = getEmployeeData();

// Define the match condition to identify the assignment. This condition


// will match the primary assignment for the employee
var condition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

// The unique ID for the employee


var employeeId = employee.employee;

// Retrieve the full history for the assignment that matches the condition
var data = personDataAPI.getAsgnmtHistoryForEmployee(employeeId, condition,
effDt);

if (data.length === 0) {
log.info("No primary assignment was found for employee " + employeeId);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 328


WT&A API Specifications 18.3 Person Data API

else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < data.length; ++i) {
var assignment = data[i];
log.info("Primary assignment for employee " + employeeId +
" belongs to policy profile " + assignment.policy_profile +
" between " + assignment.eff_dt + " and " + assignment.end_eff_dt);
}
}

If no assignment belonging to the indicated employee matches the specified condition, then an empty array
will be returned.

Example 2: Employee needs to be found based on a condition


If the employee the assignment belongs to is not already known, then the following script example shows
how the Person Data API is able to find the entire effective-dated history for an assignment matching a given
condition and belonging to an employee matching a second condition:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define a condition to identify the employee. In this case, the


// condition will match the employee with the ID E766588
var employeeCondition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E766588");

// Define the match condition to identify the assignment. This condition


// will match the primary assignment for the employee
var assignmentCondition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

// Retrieve the full history for the assignment that matches the condition
var data = personDataAPI.getAsgnmtHistory(employeeCondition, assignmentCondition);

if (data.length === 0) {
log.info("No primary assignment was found for the matching employee");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < data.length; ++i) {
var assignment = data[i];
log.info("Primary assignment for the matching employee" +
" belongs to policy profile " + assignment.policy_profile +
" between " + assignment.eff_dt + " and " + assignment.end_eff_dt);
}
}

If no assignment belonging to the matching employees matches the specified condition, then an empty array
will be returned.

Note: the employee condition must match exactly zero or one employees. If more than employee matches the
condition, an exception will be generated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 329


WT&A API Specifications 18.3 Person Data API

Looking up all matching assignments


The previous examples have shown various ways of accessing data for a single assignment. However,
sometimes a script may have a need to access data for a whole set of assignments. For instance, it may need
to evaluate all employees in a given policy profile. The following script example shows how the Person Data
API can be used to find all assignments matching a given condition:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the assignments. This condition


// will match all assignments in the policy profile EXEMPT
var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the assignments that match the condition on that date
var assignments = personDataAPI.getAllAsgnmts(condition, effDt);

if (assignments.length === 0) {
log.info("No assignments were found in policy profile EXEMPT on " + effDt);
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < assignments.length; ++i) {
var assignment = assignments[i];
log.info("Assignment with ID " + assignment.computed_match_id +
" belongs to policy profile EXEMPT on " + effDt);
}
}

If the specified condition doesn’t match any assignments, then the array of records returned will be empty.

Looking up an assignment master record


The following script example shows how to access the assignment master record for an assignment meeting a
particular condition. Typically, this would be used when you already have a specific employee you are
working with, but it can also be used with a condition to define which employee you are interested in. In
these examples, we are looking up the assignment master record for the primary assignment for the
employee with display ID “E187756”:

Example 1: Employee ID is already known


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Employee data is looked up in some fashion, using the API


var employee = getEmployeeData();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 330


WT&A API Specifications 18.3 Person Data API

// Define the match condition to identify the assignments. This condition


// will match the primary assignment for the employee
var condition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

// The unique ID for the employee


var employeeId = employee.employee;

// Retrieve the assignment master record for the assignment that matches the condition
var assignmentMaster = personDataAPI.getAsgnmtMasterForEmployee(employeeId,
condition);

if (assignmentMaster === null) {


log.info("No assignment master was found for the primary assignment");
}
else {
// Do something with the data, based on the needs of the script
log.info("The description of the primary assignment for the employee is " +
assignmentMaster.description);
}

Note: The condition used here must match exactly zero or one assignments for the indicated employee. If
more than one assignment matches the condition, an exception will be generated.

Example 2: Employee needs to be found based on a condition


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define a condition to identify the employee. In this case, the


// condition will match the employee with the ID E377764
var employeeCondition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E377764"

// Define the match condition to identify the assignments. This condition


// will match the primary assignment for the employee
var assignmentCondition = new MatchCondition("asgnmt", "primary_asgnmt",
MatchOperator.EQUALS, "T");

// Retrieve the assignment master record for the assignment that matches
// both the employee and assignment conditions
var assignmentMaster = personDataAPI.getAsgnmtMaster(employeeCondition,
assignmentCondition);

if (assignmentMaster === null) {


log.info("No assignment master was found for the primary assignment");
}
else {
// Do something with the data, based on the needs of the script
log.info("The description of the primary assignment for the employee is " +
assignmentMaster.description);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 331


WT&A API Specifications 18.3 Person Data API

Note: The employee condition used here must match exactly zero or one employees and the assignment
condition must match exactly zero or one assignments belonging to the matching employee. If more
than one employee or assignment matches the conditions, an exception will be generated.

Looking up active assignments


The Person Data API can also be used to select only those assignments that are not terminated, since typically
these are the only assignments we are interested in processing. While the logic for these scenarios can be
added into the conditions being used to select the assignments, there are some helper methods to facilitate
these checks that are available to simplify the coding. These methods are demonstrated in the following
script examples:

Example 1: Getting only active assignments


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the assignments. This condition


// will match all assignments in the policy profile EXEMPT
var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the assignments that match the condition and are active on that
// date
var assignments = personDataAPI.getActiveAssignments(condition, effDt);

if (assignments.length === 0) {
log.info("No assignments were found in policy profile EXEMPT on " + effDt);
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < assignments.length; ++i) {
var assignment = assignments[i];
log.info("Assignment with ID " + assignment.computed_match_id +
" belongs to policy profile EXEMPT on " + effDt);
}
}

If no active assignments match the condition, then an empty array will be returned.

Example 2: Getting active or soft-terminated assignments


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 332


WT&A API Specifications 18.3 Person Data API

// Define the match condition to identify the assignments. This condition


// will match all assignments in the policy profile EXEMPT
var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define the effective date that we're interested in


var effDt = WFSDate.today();

// Retrieve all of the assignments that match the condition and are active on that date
var assignments = personDataAPI.getActiveOrSoftTerminatedAssignments(condition, effDt);

if (assignments.length === 0) {
log.info("No assignments were found in policy profile EXEMPT on " + effDt);
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < assignments.length; ++i) {
var assignment = assignments[i];
log.info("Assignment with ID " + assignment.computed_match_id +
" belongs to policy profile EXEMPT on " + effDt);
}
}

If no active or soft-terminated assignments match the condition, then an empty array will be returned.

Looking up a single user record


The following script excerpt demonstrates how the Person Data API can be used to look up the user
information for a user matching a given condition:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the user. This condition will
// match the user with the login ID E766598
var condition = new MatchCondition("app_user", "login_id",
MatchOperator.EQUALS, "E766598");

// Retrieve the user information for the user matching the condition
var user = personDataAPI.getUser(condition);

if (user === null) {


log.info("No user record found with login ID E766598");
}
else {
// Do something with the data, based on the needs of the script
log.info("User email address for user with login ID E766598 is " +
user.email_address);
}

Note: The condition used here must match exactly zero or one users. If more than one user matches the
condition, an exception will be generated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 333


WT&A API Specifications 18.3 Person Data API

Looking up all matching users


The following script excerpt demonstrates how the Person Data API can be used to look up the user
information for all users that match a given condition:
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the match condition to identify the user. This condition will
// match all users with a login ID beginning with the letter E
var condition = new MatchCondition("app_user", "login_id",
MatchOperator.LIKE, "E%");

// Retrieve the user information for the user matching the condition
var users = personDataAPI.getAllUsers(condition);

if (users.length === 0) {
log.info("No user records found with login ID beginning with E");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < users.length; ++i) {
log.info("User email address for user with login ID " + user.login_id +
" is " + user.email_address);
}
}

Note: The condition used here must match exactly zero or one users. If more than one user matches the
condition, an exception will be generated.

Finding users based on roles


The Person Data API can also be used to identify users belonging to a given set of roles on an indicated date.
The API can return all users or only non-terminated users. The following script examples demonstrate how
that can be done for both general and group roles:

Example 1: Finding all users based on general roles


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Array of roles that we are interested in


var roles = ["EMPLOYEE_GENERAL", "MANAGER_GENERAL", "TIMEKEEPER_GENERAL"];

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Retrieve the user information for the users in the specified roles
var users = personDataAPI.getUsersForGeneralRoles(roles, effDt);

if (users.length === 0) {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 334


WT&A API Specifications 18.3 Person Data API

log.info("No user records found with the specified roles");


}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < users.length; ++i) {
log.info("User with login ID " + user.login_id +
"has one of the indicated roles");
}
}

If no users are found matching the specified roles, then the array of users returned will be empty.

Example 2: Finding non-terminated users based on general roles


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Array of roles that we are interested in


var roles = ["EMPLOYEE_GENERAL", "MANAGER_GENERAL", "TIMEKEEPER_GENERAL"];

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Retrieve the user information for the non-terminated users in the specified roles
var users = personDataAPI.getNonTerminatedUsersForGeneralRoles(roles, effDt);

if (users.length === 0) {
log.info("No non-terminated user records found with the specified roles");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < users.length; ++i) {
log.info("User with login ID " + user.login_id +
"has one of the indicated roles");
}
}

If no non-terminated users are found matching the specified roles, then the array of users returned will be
empty.

Example 3: Finding all users based on group roles


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Array of roles that we are interested in


var roles = ["MANAGER_GROUP", "TIMEKEEPER_GROUP"];

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Retrieve the user information for the users in the specified roles

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 335


WT&A API Specifications 18.3 Person Data API

var users = personDataAPI.getUsersForGroupRoles(roles, effDt);

if (users.length === 0) {
log.info("No user records found with the specified roles");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < users.length; ++i) {
log.info("User with login ID " + user.login_id +
"has one of the indicated roles");
}
}
If no users are found matching the specified roles, then the array of users returned will be empty.

Example 4: Finding non-terminated users based on group roles


includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Array of roles that we are interested in


var roles = ["MANAGER_GROUP", "TIMEKEEPER_GROUP"];

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Retrieve the user information for the non-terminated users in the specified roles
var users = personDataAPI.getNonTerminatedUsersForGroupRoles(roles, effDt);

if (users.length === 0) {
log.info("No non-terminated user records found with the specified roles");
}
else {
// Do something with the data, based on the needs of the script
for (var i = 0; i < users.length; ++i) {
log.info("User with login ID " + user.login_id +
"has one of the indicated roles");
}
}
If no non-terminated users are found matching the specified roles, then the array of users returned will be
empty.

Determining the general roles assigned to a user


The following script examples show how the Person Data API can be used to determine which general roles
are assigned to a user:

Example 1: Determining the general role when user data has already been looked up
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// User data is looked up in some fashion, using the API


var user = getUserData();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 336


WT&A API Specifications 18.3 Person Data API

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Unique ID for the user record


var userId = user.app_user;

// Retrieve the user information for the users in the specified roles
var generalRoles = personDataAPI.getAllGeneralRolesForUser(userId, effDt);

// Do something with the data, based on the needs of the script


for (var i = 0; i < generalRoles.length; ++i) {
log.info("User " + user.login_id + " on " + effDt + " has " +
generalRoles[i] + " general role");
}

Note: If the specified user doesn’t exist, or doesn’t have a general role assigned, then an exception will be
generated.

Example 2: Determining the general role when the user is not yet known
includeDistributedPolicy("PERSON_DATA_API");

// Initialize the API


var personDataAPI = new PersonDataAPI();

// Define the condition to select the user. In this case, the condition
// will select the user with login ID E884521
var condition = new MatchCondition("app_user", "login_id",
MatchOperator.EQUALS, "E884521");

// Define the effective date we are interested in


var effDt = WFSDate.today();

// Retrieve the user information for the users in the specified roles
var generalRoles = personDataAPI.getAllGeneralRoles(condition, effDt);

// Do something with the data, based on the needs of the script


for (var i = 0; i < generalRoles.length; ++i) {
log.info("User E884521 on " + effDt + " has " + generalRoles[i] + " general role");
}

Note: If the specified condition doesn’t match exactly one user, with a general role defined, then an exception
will be generated.

Retrieving distinct values for fields


This script excerpt below demonstrates getting distinct values for a specified column in tables mentioned in
API_UTIL. To get the values, the name of the column and the name of the table should be specified, along
with the match conditions for the query. The result can also be effective dated if the date is provided.
var dateFormat = "yyyy-MM-dd";
var personDataApi = new PersonDataAPI();
// defining the match condition for the retrieval

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 337


WT&A API Specifications 18.3 Person Data API

var matchCondition = new MatchCondition('EMPLOYEE', 'DISPLAY_EMPLOYEE',


MatchOperator.NOT_EQUALS, '');
// getting the distinct values for the column ACT_COMPANY in the table EMPLOYEE
var distinctValuesMethod = personDataApi.getDistinctValues('ACT_COMPANY', 'EMPLOYEE',
matchCondition, WFSDate.valueOf("2017-01-01", dateFormat));

var queryResultCount = 0;
// query to verify the results returned by getDistinctValues()
var query = "select distinct ACT_COMPANY from EMPLOYEE where {ts '2017-01-01 00:00:00.000'}
between EFF_DT and END_EFF_DT";
var c = new Connection();
var distinctValuesQuery = [];
try {
var result = new Sql(c, query);

while (result.next()) {
queryResultCount++;
distinctValuesQuery.push(result.ACT_COMPANY);
}
}

distinctValuesMethod.sort();
distinctValuesQuery.sort();

if (distinctValuesMethod.length != distinctValuesQuery.length) {
throw "Values returned by method do not match values returned by query";
}

for (var i = 0; i < distinctValuesMethod.length; i++) {


test.assertEqual(distinctValuesMethod[i], distinctValuesQuery[i], "Method result value = "
+ distinctValuesMethod[i] + " , Query result value = " + distinctValuesQuery[i]);
}

Troubleshooting
The job log of the script using the Person Data API will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
Some common error messages, their causes, and the solution:
Error Message Cause Solution
Input parameter PARAMETER An API method was called Check that all calls to the API
DESCRIPTION not provided without a value being provided methods are supplying values for
for a required argument all of the required arguments
Multiple general roles found More than one record was Check that the condition
matching specified criteria returned by a call to specified in the call to
getGeneralRole getGeneralRole returns only one
user, and that that user doesn’t
have overlapping general role
records
No general role defined for user No records were returned by a Check that the condition or user
matching specified criteria call to getAllGeneralRoles or ID matches a valid existing user
getAllGeneralRolesForUser and that the user is correct

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 338


WT&A API Specifications 18.3 Person Data API

assigned a general role on the


specified date
Multiple TABLE NAME records A method that is expected to Update the condition being used
found matching specified criteria return only a single record to select the data to ensure that
instead returned more than one it only matches against a single
record record
Invalid role id ‘ROLE NAME’ A role name that does not match Make sure that the indicated role
provided for RIGHT TYPE user an existing role (or is not of the actually exists, and is of the right
right type right type) was specified for type (either general or group) for
getUsersForGeneralRoles or the method being used
getUsersForGroupRoles.
Table 62: Person Data API typical error messages, common causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Person Data API consists of the following component(s):
1. The MatchCondition, which defines a condition to select employee, assignment, or user records
a. This MatchCondition makes use of a MatchOperator which defines a comparison operation
to use in a condition for matching a specified value against the employee/assignment/user
data.
2. The PersonDataAPI, which provides assorted methods for accessing employee, assignment, or user
data.
See the contents of the PERSON_DATA_API policy in the Distributed JavaScript Library category of the Policy
Editor for full documentation on these methods. The following is a summary of the available methods and
common uses:

MatchOperator
EQUALS
Only data where the value in the specified field exactly matches the indicated value will be matched by the
condition

NOT_EQUALS
Only data where the value in the specified field does not match the indicated value will be matched by the
condition

GREATER_THAN
Only data where the value in the specified field is greater than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “3” is greater than “20”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 339


WT&A API Specifications 18.3 Person Data API

GREATER_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is greater than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “3” is greater than
“20”.

LESS_THAN
Only data where the value in the specified field is less than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “20” is less than “3”.

LESS_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is less than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “20” is less than
“3”.

IN
Only data where the value in the specified field exactly matches one of the values in the indicated array of
values will be matched by the condition.

NOT_IN
Only data where the value in the specified field does not match any of the values in the indicated array of
values will be matched by the condition.

LIKE
Only data where the value in the specified field matches the pattern defined by the indicated value will be
matched by the condition.

NOT_LIKE
Only data where the value in the specified field does not match the pattern defined by the indicated value
will be matched by the condition.

BETWEEN
Only data where the value in the specified falls between the two values defined by the indicated array of
values (inclusive of the two endpoints) will be matched by the condition. For string fields this is applied
lexicographically, meaning that “5” is between “37” and “62”.

MatchCondition
MatchCondition(table, field, operator, values, isNotOperator)
Creates a new MatchCondition for the indicated table/field combination that matches against the specified
value(s) using the indicated MatchOperator.
If the MatchOperator specified is IN or NOT_IN, then values is expected to be an array of all the different
values to be evaluated by the “in” operation. If the MatchOperator specified is BETWEEN, then values is
expected to be an array containing two values: the starting point and ending point of the range to be
evaluated by the “between” operation. For all other MatchOperators, values is expected to be a single
value.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 340


WT&A API Specifications 18.3 Person Data API

The isNotOperator controls whether the results of the MatchCondition should be negated. If this is set to
true, then a MatchCondition that normally evaluates to false will instead evaluate to true, and a
MatchCondition that normally evaluates to true will instead evaluate to false. This allows for conditions that
don’t have an explicit MatchOperator defined, such as “not between”, to be defined.

and(condition)
Modifies the MatchCondition to return only the intersection of its original condition and the specified
condition.

or(condition)
Modifies the MatchCondition to return the union of its original condition and the specified condition.

PersonDataAPI
PersonDataAPI()
Creates a new instance of the Person Data API

getEmployeeRecord(condition, effDate)
Returns a single effective-dated employee record for the employee matching the specified condition on the
indicated date.

getEmployeeHistory(condition)
Returns the full effective-dated employee history for the employee matching the specified condition.
Records will be ordered from earliest effective date to latest effective date.

getAllEmployees(matchCondition, effDate)
Returns a single effective-dated employee record for each employee matching the specified condition on the
indicated date.

getAllEmployeeHistory(matchCondition)
Returns the full effective-dated employee history for each employee matching the specified condition. For
each employee, records will be ordered from earliest effective date to latest effective date.

getEmployeeMaster(condition)
Returns a single employee master record for the employee matching the specified condition.

getActiveEmployees(matchCondition, effDate)
Returns a single effective-dated employee record for each employee matching the specified condition on the
indicated date where that employee has at least one assignment that is not in a hard-terminated or soft-
terminated state on that date.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 341


WT&A API Specifications 18.3 Person Data API

getActiveOrSoftTerminatedEmployees(matchCondition, effDate)
Returns a single effective-dated employee record for each employee matching the specified condition on the
indicated date where that employee has at least one assignment that is not in a soft-terminated state on that
date.

getEmployeeStageRecord(condition, effDate)
Returns a single employee stage record for the employee matching the specified condition. If no effective
date is specified, the condition must match to a single record. If an effective date is specified, then the
condition must match to a single employee and the record for that employee effective on the indicated date
will be returned.

getAllEmployeeStageRecords(matchCondition, effDate)
Returns all employee stage records matching the specified condition. If an effective date is specified, only
those records matching the condition on the indicated date will be returned.

clearEmployeeStageRecords(condition)
Deletes all records from the employee stage table that match the specified condition.

clearAllEmployeeStageRecords()
Deletes all records from the employee stage table.

getAsgnmtRecordForEmployee(employeeId, condition, effDate)


Returns the single effective-dated assignment record for the employee with the indicated ID where the
assignment matches the specified condition on the date indicated.

getAsgnmtHistoryForEmployee(employeeId, condition)
Returns the full effective-dated assignment history for the employee with the indicated ID where the
assignment matches the specified condition.

getAsgnmtRecord(employeeCondition, asgnmtCondition, effDate)


Returns the single effective-dated assignment record where the assignment matches the specified
assignment condition and the assignment belongs to the employee matching the specified employee
condition on the date indicated.

getAsgnmtHistory(employeeCondition, asgnmtCondition)
Returns the full effective-dated assignment history where the assignment matches the specified assignment
condition and the assignment belongs to the employee matching the specified employee condition. Records
will be ordered from earliest effective date to latest effective date.

getAllAsgnmts(matchCondition, effDate)
Returns the single effective-dated assignment record for all of the assignments matching the specified
condition on the indicated date.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 342


WT&A API Specifications 18.3 Person Data API

getAllAsgnmtHistory(matchCondition)
Returns the full effective-dated assignment history for each assignment matching the specified condition.
For each assignment, records will be ordered from earliest effective date to latest effective date.

getAsgnmtMasterForEmployee(employeeId, condition)
Returns the assignment master record for the employee with the specified ID that matches the indicated
condition.

getAsgnmtMaster(employeeCondition, asgnmtCondition)
Returns the assignment master record for the assignment matching the specified assignment condition
belonging to the employee matching the specified employee condition.

getActiveAssignments(matchCondition, effDate)
Returns the single effective-dated assignment record for each assignment matching the specified condition
on the indicated date where that assignment is not in a hard-terminated or soft-terminated state.

getActiveOrSoftTerminatedAssignments(matchCondition, effDate)
Returns the single effective-dated assignment record for each assignment matching the specified condition
on the indicated date where that assignment is not in a hard-terminated state.

getAsgnmtStageRecord(asgnmtCondition, effDate)
Returns a single assignment stage record for the assignment matching the specified condition. If no effective
date is specified, the condition must match to a single record. If an effective date is specified, then the
condition must match to a single assignment and the record for that assignment effective on the indicated
date will be returned.

getAllAsgnmtStageRecords(asgnmtCondition, effDate, orderBy)


Returns all assignment stage records matching the specified condition. If an effective date is specified, only
those records matching the condition on the indicated date will be returned.

clearAsgnmtStageRecords(condition)
Deletes all records from the assignment stage table that match the specified condition.

clearAllAsgnmtStageRecords()
Deletes all records from the assignment stage table.

getUser(condition)
Returns the user record for the user matching the specified condition.

getAllUsers(matchCondition)
Returns the user records for all users matching the specified condition.

getUsersForGeneralRoles(generalRoleIds, effDate)
Returns the user records for every user assigned to one of the specified general roles on the indicated date.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 343


WT&A API Specifications 18.3 Person Data API

getNonTerminatedUsersForGeneralRoles(generalRoleIds, effDate)
Returns the user records for non-terminated users assigned to one of the specified general roles on the
indicated date.

getUsersForGroupRoles(groupRoleIds, effDate)
Returns the user records for every user delegated rights to an assignment group with one of the specified
group roles on the indicated date.

getNonTerminatedUsersForGroupRoles(groupRoleIds, effDate)
Returns the user records for non-terminated users delegated rights to an assignment group with one of the
specified group roles on the indicated date.

getAllGeneralRoles(condition, effDate)
Returns all the general roles associated with the user matching the specified condition effective on the
indicated date.

getAllGeneralRolesForUser(appUser, effDate)
Returns all the general roles associated with the user with the specified internal user ID effective on the
indicated date.

isTerminatedUser(appUser, effDate)
Determines if an app user is terminated by evaluating the user’s roles. This method is valid for both stackable
general roles configurations and single general role configurations

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 344


WT&A API Specifications 18.3 Policy Creation API

Policy Creation API


Overview and Capabilities
The Policy Creation API provides a mechanism for scripts to create new policies from within a script. This can
be used as part of a job designed solely to create new policies, such as a
Schedule Template or Schedule Cycle import, or as smaller component of another job (e.g. creating a Time
Zone policy for an employee if the time zone specified in the source data does not match one of the existing
policies). This can be used in conjunction with the Policy Info API to determine what information is already
defined for the policy._Policy_Info_API
This API can be used to create new policies, or to add new effective-dated components to existing policies
(for policies that are effective dated). The policies (whether added or changed) can be automatically included
in either an existing bundle or a new bundle, or the changes can be made outside of any bundles. Only
certain types of policies are allowed to be created through this API, and all policies created need to pass the
standard policy validation for those types of policies in order to be imported successfully.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Understanding of policies and their settings

Components
This API consists of the following component(s):
• The distributed JavaScript library POLICY_CREATION_API.

Setup
No setup is necessary for the Policy Creation API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Creating Schedule Templates
The Policy Creation API allows for the creation of new Schedule Templates and updates to existing Schedule
Templates. Since Schedule Templates are effective dated, these updates can take the form of either an in-
place update to the existing data (if the same effective date is specified) or in the creation of a new effective-
dated row for the policy if a later effective date is specified.
The following script example demonstrates using the Policy Creation API to create a new Schedule Template
policy named “M_F_8A_5P”, which defines a schedule from 8:00am – 5:00pm for Monday through Friday:

Example: Creating a Schedule Template policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 345


WT&A API Specifications 18.3 Policy Creation API

// Define the details that will be included in the policy definition. In this case,
// this is a single slice running from 8:00am - 5:00pm for Monday through Friday,
// using the pay code SCHEDULED_IO.
var details = [];
for (var i = 2; i <= 6; ++i) { // 2 = Monday, 6 = Friday
// Define the settings for this detail
var detailParms = {
payCode: "SCHEDULED_IO", // The pay code for the detail
dayNumber: i, // Which day the detail is defining
startDayNumber: i, // The start time falls on the same day
endDayNumber: i, // The end time falls on the same day
details: {
start_tm: new WTime(8, 0, 0), // Starting at 8:00am
end_tm: new WTime(17, 0, 0) // Ending at 5:00pm
}
};
// Create the detail with the specified settings
var detail = new ScheduleTemplateSliceParms(detailParms);
// Add the detail to the detail array
details.push(detail);
}

// Define the settings for the template policy


var templateSettings = {
weekStartDay: 1, // Week starts on Sunday
details: details, // The array of details to include in the template
biweekly: false // This template only spans a single week
};
var templateParms = new ScheduleTemplateParms(templateSettings);

// Create the policy definition


var policyId = "M_F_8A_5P";
var description = "Monday - Friday, 8:00am - 5:00pm";
var effDate = WFSDate.VERY_EARLY_DATE;
var policyDefinition = new PolicyDefinition(policyId, templateParms, description,
effDate);

// Create the policy


api.createPolicy(policyDefinition);

Creating Schedule Cycles


The Policy Creation API allows for the creation of new Schedule Cycles and updates to existing Schedule
Cycles. Since Schedule Cycles are not effective dated, an update to an existing policy will completely replace
the existing definition for that policy.
The following script example demonstrates using the Policy Creation API to create a new Schedule Cycle
where the employee works a repeating pattern of four days on, two days off:

Example: Creating a Schedule Cycle policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define an array of the templates that should be included in this cycle.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 346


WT&A API Specifications 18.3 Policy Creation API

// The order of templates in this array will define the order in which they
// occur in the cycle. (Array element 0 will be the first template in the
// cycle, etc.)
var templates = [
"WORKING_SMTW__S_8A_5P",
"WORKING_SMT__FS_8A_5P",
"WORKING_SM__TFS_8A_5P",
"WORKING_S__WTFS_8A_5P",
"WORKING___TWTF__8A_5P",
"WORKING__MTWT___8A_5P"
];

// Define the settings for the cycle policy


var cycleSettings = {
templates: templates // Array of templates, in the order in which they occur
};
var cycleParms = new ScheduleCycleParms(cycleSettings);

// Create the policy definition


var policyId = "FOUR_DAYS_ON_TWO_OFF_8A_5P";
var description = "Four Days On, Two Off, 8:00am - 5:00pm";
var policyDefinition = new PolicyDefinition(policyId, cycleParms, description);

// Create the policy


api.createPolicy(policyDefinition);

Creating Pay Codes


The Policy Creation API allows for the creation of new Pay Codes and updates to existing Pay Codes. Since
Pay Codes are not effective dated, an update to an existing policy will completely replace the existing
definition for that policy.
The following script example demonstrates using the Policy Creation API to create a new Pay Code named
WORKED_IO:

Example: Creating a Pay Code policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define the settings for the pay code policy. Pay codes have no settings
// other than their name and description, so no additional settings need to be
// specified here.
var payCodeParms = new PayCodeParms();

// Create the policy definition


var policyId = "WORKED_IO";
var description = "Worked Time (In/Out)";
var policyDefinition = new PolicyDefinition(policyId, payCodeParms, description);

// Create the policy


api.createPolicy(policyDefinition);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 347


WT&A API Specifications 18.3 Policy Creation API

Creating Pay Code Values


The Policy Creation API allows for the creation of new Pay Code Values and updates to existing Pay Code
Values. Since Pay Code Values are not effective dated, an update to an existing policy will completely replace
the existing definition for that policy.
The following script example demonstrates using the Policy Creation API to create a new Pay Code Value
named REG with a pay_code_system1 value of “RG1” and a pay_code_other_string2 value of “RG2”:

Example: Creating a Pay Code Value policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define the settings for the pay code value policy


var settings = {
systems: {
1: "RG1" // Pay_code_system1 value
},
otherStrings: {
2: "RG2" // Pay_code_other_string2 value
},
otherNumber: {},
amount: 0,
factor: 0,
percent: 0,
rate: 0
};
var payCodeValueParms = new PayCodeValueParms(settings);

// Create the policy definition


var policyId = "REG";
var description = "REG Pay Code values";
var policyDefinition = new PolicyDefinition(policyId, payCodeValueParms, description);

// Create the policy


api.createPolicy(policyDefinition);

Creating Pay Code Maps


The Policy Creation API allows for the creation of new Pay Code Maps and updates to existing Pay Code
Maps. Since Pay Code Maps are effective dated, these updates can take the form of either an in-place
update to the existing data (if the same effective date is specified) or in the creation of a new effective-dated
row for the policy if a later effective date is specified. Both timesheet and schedule mappings can be
specified on the Pay Code Map policies being imported.
The following script example demonstrates using the Policy Creation API to create a new Pay Code Map
named “EXEMPT”, including several Pay Codes on both the timesheet and the schedule:

Example: Creating a Pay Code Map policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 348


WT&A API Specifications 18.3 Policy Creation API

var api = new PolicyCreationAPI();

// Define an array to hold the details for the pay code map
var details = [];

// Define the details for the timesheet mappings included in the pay code map
details.push(
{
isSchedule: false, // This detail is for the timesheet
payCode: "REG", // The pay code for the detail
entryField: "HOURS", // The entry field for the pay code
payCodeValue: "REG", // The pay code value to associate with the pay code
canView: "ALL_USERS", // Set of roles allowed to view the pay code
canEdit: "ALL_USERS" // Set of roles allowed to edit the pay code
}
);
details.push(
{
isSchedule: false,
payCode: "VAC",
bankUsage: "VAC", // The bank usage policy associated with the pay code
payCodeValue: "VAC",
canView: "ALL_USERS",
canEdit: "ADMIN_USERS"
}
);
details.push(
{
isSchedule: true, // This detail is for the schedule
payCode: "SCHEDULED",
entryField: "HOURS"
}
);

// Convert the detail definitions into parameter objects


var detailParms = [];
for (var i = 0; i < details.length; ++i) {
detailParms.push(new PayCodeMapDetailParms(details[i] ) );
}

// Define the settings for the pay code map policy


var payCodeMapSettings = {
details: detailParms
};
var payCodeMapParms = new PayCodeMapParms(payCodeMapSettings);

// Create the policy definition


var policyId = "EXEMPT";
var description = "Exempt Pay Code mappings";
var effDate = WFSDate.VERY_EARLY_DATE;
var policyDefinition = new PolicyDefinition(policyId, payCodeMapParms, description,
effDate);

// Create the policy


api.createPolicy(policyDefinition);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 349


WT&A API Specifications 18.3 Policy Creation API

Creating Exceptions
The Policy Creation API allows for the creation of new Exception Codes, Exception Rules, and Exception
Triggers and updates to existing policies of those types. These types of policies are treated as a single unit by
the API, so it is not possible to import an Exception Code separately from an Exception Trigger. Since
Exception Rule and Exception Trigger policies are effective dated, these updates can take the form of either
an in-place update to the existing data (if the same effective date is specified) or in the creation of a new
effective-dated row for the policy if a later effective date is specified. The Exception Code and Exception
Trigger Master policies, which are not effective dated, will have their existing definitions completely replaced
if an update is imported.
The following script example demonstrates using the Policy Creation API to create a new Exception named
“OVER_24_HOURS_IN_A_DAY”, which will trigger if more than 24 hours are on the timesheet for a given day:

Example: Creating an Exception and associated policies


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define the settings for the exception policies


var settings = {
// The exception should be error level
severity: "ERROR",

// The message that should appear to the user on the exceptions tab
message: "More than 24 hours worked on a single day",

// What the user should not be allowed to do when the exception is present
preventUserActions: "SUBMIT",

// Context in which the formula should be evaluated


context: "DAY",

// Formula to determine if the exception should trigger or not


formula: "sumtime(over day, hours)",

// Roles allowed to view the exception


canView: "ALL_ROLES"
};
var exceptionParms = new ExceptionParms(settings);

// Create the policy definition


var policyId = "OVER_24_HOURS_IN_A_DAY";
var description = "More than 24 hours in a day";
var effDate = WFSDate.VERY_EARLY_DATE;
var policyDefinition = new PolicyDefinition(policyId, exceptionParms, description, effDate);

// Create the policy


api.createPolicy(policyDefinition);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 350


WT&A API Specifications 18.3 Policy Creation API

Creating Bank Accrual Policies


The Policy Creation API allows for the creation of new Bank Accrual Policies and updates to existing Bank
Accrual Policies. Since Bank Accrual Policies are effective dated, these updates can take the form of either an
in-place update to the existing data (if the same effective date is specified) or in the creation of a new
effective-dated row for the policy if a later effective date is specified.
The following script example demonstrates using the Policy Creation API to create a new Bank Accrual Policy
named “EXEMPT_ACCRUALS”, which defines a monthly accrual with three different service range definitions:

Example: Creating a Bank Accrual Policy policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define an array to hold the service ranges for the bank accrual policy
var ranges = [];

// Define the service ranges to be included in the bank accrual policy


ranges.push(
{
rangeStart: 0, // The minimum length of service to qualify
rangeEnd: 2, // The maximum length of service to qualify
accrualFormula: "13.3", // The amount that should be accrued
qualification: 'assignment.flsa_status = "E"', // Qualification to accrue
maxLimit: "160" // Maximum amount allowed to be accrued
}
);
ranges.push(
{
rangeStart: 3,
rangeEnd: 5,
accrualFormula: "16.6",
qualification: 'assignment.flsa_status != "N"',
maxLimit: "160"
}
);
ranges.push(
{
rangeStart: 6,
rangeEnd: 999,
accrualFormula: "20",
qualification: "true",
maxLimit: "200"
}
);

// Convert the service range definitions into parameter objects


var rangeParms = [];
for (var i = 0; i < ranges.length; ++i) {
rangeParms.push(new BankAccrualServiceRangeParms(ranges[i] ) );
}

// Define the settings for the bank accrual policy


var accrualSettings = {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 351


WT&A API Specifications 18.3 Policy Creation API

// How often should the accrual happen?


frequency: "MONTHLY",

// What data qualification needs to be met to be eligible for this accrual?


qualification: "employee.standard_daily_hours > 5",

// What unit is length of service being measured in?


serviceUnits: "YEARS",

// What date is length of service being calculated from?


serviceDate: "EMP_DATE2",

// Which service ranges apply to this bank accrual policy?


serviceRanges: rangeParms,

// When in the month do the accruals happen?


monthlyAccrueOn: "SPECIFIC_DAY",

// Which specific date in the month do the accruals happen on?


dayNumber: 12,

// Should the amount being accrued be divided by the total number of periods in
// the year?
divideAccrualAmounts: false
};
var bankAccrualParms = new BankAccrualParms(accrualSettings);

// Create the policy definition


var policyId = "EXEMPT_ACCRUALS";
var description = "Accruals for exempt employees";
var effDate = WFSDate.VERY_EARLY_DATE;
var policyDefinition = new PolicyDefinition(policyId, bankAccrualParms, description,
effDate);

// Create the policy


api.createPolicy(policyDefinition);

Creating Time Zones


The Policy Creation API allows for the creation of new Time Zones and updates to existing Time Zones. Since
Time Zones are not effective dated, an update to an existing policy will completely replace the existing
definition for that policy.
The following script example demonstrates using the Policy Creation API to create a new Time Zone named
EST with an ISO Code of “America/New_York”:

Example: Creating a Time Zone policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define the settings for the time zone policy


var settings = {
isoCode: "America/New_York"
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 352


WT&A API Specifications 18.3 Policy Creation API

var timeZoneParms = new TimeZoneParms(settings);

// Create the policy definition


var policyId = "EST";
var description = "Eastern time zone, with DST";
var policyDefinition = new PolicyDefinition(policyId, timeZoneParms, description);

// Create the policy


api.createPolicy(policyDefinition);

Creating Field Security Policies


The Policy Creation API allows for the creation of new Field Security Policies and updates to existing Field
Security Policies. Since Field Security Policies are not effective dated, an update to an existing policy will
completely replace the existing definition for that policy.
The following script example demonstrates using the Policy Creation API to create a new Field Security Policy
named “HOURS_WORKED” that includes field definitions for the HOURS, PAY_CODE, and COMMENTS fields:

Example: Creating a Field Security Policy policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define an array to hold the field definitions for the policy


var fields = [];

// Define the field definitions to be included in the policy


fields.push(
{
fieldMappingPolicy: "HOURS",
canView: "ALL_ROLES",
canEdit: "ALL_ROLES"
}
);
fields.push(
{
fieldMappingPolicy: "PAY_CODE",
canView: "ALL_ROLES",
canEdit: "ALL_ROLES"
}
);
fields.push(
{
fieldMappingPolicy: "COMMENTS",
canView: "MANAGERS_ONLY",
canEdit: "MANAGERS_ONLY"
}
);

// Convert the field definitions into parameter objects


var fieldParms = [];
for (var i = 0; i < fields.length; ++i) {
fieldParms.push(new FieldSecurityFieldParms(fields[i] ) );
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 353


WT&A API Specifications 18.3 Policy Creation API

// Define the settings for the field security policy


var fieldSecuritySettings = {
fields: fieldParms
};
var fieldSecurityParms = new FieldSecurityParms(fieldSecuritySettings);

// Create the policy definition


var policyId = "HOURS_WORKED";
var description = "Hours Worked";
var policyDefinition = new PolicyDefinition(policyId, fieldSecurityParms,
description);

// Create the policy


api.createPolicy(policyDefinition);

Creating Data Elements


The Policy Creation API allows for the creation of new Data Elements and updates to existing Data Elements.
Since Data Elements are not effective dated, an update to an existing policy will completely replace the
existing definition for that policy.

Note: The API can only be used to create customer data elements (prefixed with “C_”). If the provided policy
ID does not begin with “C_”, that prefix will be added automatically.

The following script example demonstrates using the Policy Creation API to create a new Data Element
named “C_PROJECT” with mappings in the ASGNMT and TIME_SHEET_DETAIL tables:

Example: Creating a Data Element policy


includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for importing policy data
var api = new PolicyCreationAPI();

// Define an array to hold the mapping details for the data element
var mappings = [];

// Define the mappings to be included in the data element


mappings.push(
{
table: "ASGNMT",
fieldName: "LD",
varFieldNo: 4
}
);
mappings.push(
{
table: "TIME_SHEET_DETAIL",
fieldName: "LD",
varFieldNo: 4
}
);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 354


WT&A API Specifications 18.3 Policy Creation API

// Convert the table mappings into parameter objects


var mappingParms = [];
for (var i = 0; i < mappings.length; ++i) {
mappingParms.push(new DataElementDetailParms(mappings[i] ) );
}

// Define the settings for the data element


var dataElementSettings = {
details: mappingParms,
doNotProjectAlias: false
};
var dataElementParms = new DataElementParms(dataElementSettings);

// Create the policy definition


var policyId = "C_PROJECT";
var description = "Project";
var policyDefinition = new PolicyDefinition(policyId, dataElementParms, description);

// Create the policy


api.createPolicy(policyDefinition);

Applying policies to existing layouts


In addition to creating or updating new policy records, the Policy Creation API can also be used to assign
additional settings to all of the existing policies of certain types. This can be used in conjunction with creating
new Pay Codes to make those new Pay Codes usable within the configuration without needing to manually
link them to all of the needed policies. (Some manual configuration will still be needed in order to achieve
the final desired behavior, however.)

Example 1: Adding Pay Codes to Time Entry Groups


The following script example demonstrates using the Policy Creation API to add the Pay Code “REG_HOURS”
to all of the existing Time Entry Group policies:
includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for updating policy data
var api = new PolicyCreationAPI();

// Specify the pay code that should be added to the time entry groups
var payCode = "REG_HOURS";

// Add the pay code to the time entry groups


api.addPayCodeToTimeEntryGroups(payCode);

Example 2: Adding Pay Codes to Mobile Time Entry Layouts


The following script demonstrates using the Policy Creation API to add the Pay Code “WORKED_TIME” to all
of the existing Mobile Time Entry Layout policies:
includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for updating policy data
var api = new PolicyCreationAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 355


WT&A API Specifications 18.3 Policy Creation API

// Specify the pay code that should be added to the mobile time entry layouts
var payCode = "WORKED_TIME";

// Add the pay code to the mobile time entry layouts


api.addPayCodeToMobileTimeEntryLayouts(payCode);

Example 3: Adding Field Security Policy policies to Pay Code Maps


The Policy Creation API can also be used to assign Field Security Policy policies to Pay Codes in a Pay Code
Map. The Pay Code Map that they should be assigned to is determined by looking up which Pay Code Map is
associated with the Policy Profile that is specified.
The following script example demonstrates using the Policy Creation API to assign the Field Security Policy
“HOURS_WORKED” to the Pay Codes “REG”, “OT”, and “DT” in the Pay Code Map associated with the Policy
Profile “NON_EXEMPT_EMPLOYEES”:
includeDistributedPolicy("POLICY_CREATION_API");

// Create a new instance of the API to use for updating policy data
var api = new PolicyCreationAPI();

// Specify the field security policy that should be assigned


var fieldSecurityPolicy = "HOURS_WORKED";

// Specify the policy profile containing the pay code map that should be updated
var policyProfile = "NON_EXEMPT_EMPLOYEES";

// Specify the pay codes that should be updated


var payCodes = ["REG", "OT", "DT"];

// Update the pay code map with the field security policies
api.addFieldSecurityToPayCodeMap(fieldSecurityPolicy, policyProfile, payCodes);

Troubleshooting
The job log of the script using the Policy Creation API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No pay code map is The Policy Profile specified when Ensure that the Policy Profile
assigned to policy profile adding Field Security Policy policies specified has a corresponding Pay
POLICY_PROFILE. Unable to Pay Codes did not have a Pay Code Map policy linked to it.
to assign field security Code Map specified, which means
policy for pay codes. there is nothing to be updated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 356


WT&A API Specifications 18.3 Policy Creation API

Unable to create or modify A policy with the specified ID Ensure that all policies being created
policy of type POLICY_TYPE already exists and belongs to a do not already belong to a bundle or
with ID POLICY_ID as part different bundle than was belong to the bundle associated with
of bundle BUNDLE_NAME. specified when the API was the API being used to create them.
It already belongs to a instantiated.
different bundle,
OTHER_BUNDLE_NAME
No policy ID specified for The policy being created requires a Ensure that all required fields on the
required field FIELD_NAME foreign key link to another table in policy records being imported are
order to be saved successfully, and populated.
no policy ID was provided for that
field to create that link.
Unable to create formula The formula specified was invalid. Ensure that the formula is valid for
the context and expected return type.

Multiple entries found for The list of details provided for a Ensure that all details provided for a
FIELD_NAME with value policy included two or more details policy contain unique values for fields
VALUE. FIELD_NAME is that duplicated a value in the that aren’t allowed to be duplicated
required to contain unique indicated field. (For instance, two across the set of details.
values on all detail records details for the same table on a
Data Element)
Policy POLICY_ID does not No policy of the specified type Ensure that all of the foreign key
exist in table TABLE_NAME already exists references to other policies in the
policy data being imported point to
valid policies that are already defined.
Policy Set SET_ID does not No policy set of the specified type Ensure that all of the foreign key
exist for table already exists references to policy sets in the policy
TABLE_NAME data being imported point to valid
sets that are already defined.
Effective date EFF_DATE The effective date provided was Ensure that all effective dates
must be on or before 3000- later than 3000-12-31, which is the supplied for policies are no later than
12-31 latest effective date allowed for 3000-12-31.
policy data.
Time Zone ISO Code The ISO code specified when Ensure that all of the ISO codes
ISO_CODE is not a valid JDK importing a Time Zone was not a specified when creating Time Zone
ISO Code for a time zone valid ISO code policies are valid JDK ISO codes.
Service range from Two or more service ranges for a Ensure that all of the service ranges
RANGE_START to Bank Accrual Policy policy have associated with a Bank Accrual Policy
RANGE_END overlaps with overlapping ranges. policy do not have any overlaps
another service range between their ranges.
Value “VALUE” is not a The value specified for a Ensure that all DateChoice fields
valid DateChoice option. DateChoice field was not one of contain a value that is one of the valid
Valid values are the allowed values. choices listed in the error message.
DATE_CHOICE_OPTIONS

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 357


WT&A API Specifications 18.3 Policy Creation API

Invalid month/day The combination of month and day Ensure that all month/day
combination specified. specified represents an invalid combinations specified represent a
Month = MONTH, Day = date (for instance February 31st) valid day that exists within that
DAY month.
Range start RANGE_START The starting value for a service Ensure that all service ranges have a
is after range end range was later than the ending starting value that is less than or
RANGE_END value for the range. equal to their ending value.
Cannot create a Data No table details were specified for Ensure all Data Elements being
Element with no mappings a Data Element policy. imported include at least one table
mapping.
New formula context Exception data was imported to Ensure that all updates to Exceptions
NEW_CONTEXT does not update an existing policy but used use the same formula evaluation
match existing context a different evaluation context for context that the existing policy being
PRIOR_CONTEXT for the qualification than the existing updated used.
Exception Trigger Master data used.
POLICY_ID. Unable to
import new data
Index INDEX is no a valid The index specified for the Ensure that all field indices specified
index for a FIELD_TYPE field indicated field was outside of the for the indicated field type fall within
on a Pay Code Value policy. allowed range. The valid range is the allowed index range for that type
Valid indices are integers between 1 and the number of of field.
between 1 and MAX_INDEX variable fields of that time defined
in the configuration.
Table 63: Policy Creation API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The following is a summary of the available methods and common uses:

PolicyCreationAPI
PolicyCreationAPI(parms)
Creates a new instance of the Policy Creation API, using the specified settings.
The available parameters here are:
Parameter Name Description
Bundle The name of the bundle that the policies being imported should be added to. If the
bundle does not already exist, then a new bundle will be created with the indicated
name. If no bundle is specified, then the policies will not be added to a bundle.
enableDebugging Indicates if additional debug output should be written to the job log during
processing. Defaults to false.
Table 64: Parameters available when creating a new PolicyCreationAPI

getPolicyInformation(policyType, policyName)
Returns the policy information for the policy of the specified type with the indicated name.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 358


WT&A API Specifications 18.3 Policy Creation API

createPolicy(policyDefinition)
Creates a single new policy using the provided policy definition.

createPolicies(policyDefinitions)
Creates a new policy for each of the policy definitions specified in the provided array.

addPayCodeToTimeEntryGroups(payCode)
Adds the indicated Pay Code to all of the currently-defined Time Entry Group policies.

addPayCodeToMobileTimeEntryLayouts(payCode)
Adds the indicated Pay Code to all of the currently-defined Mobile Time Entry Layout policies.

addFieldSecurityToPayCodeMap(fieldSecurityPolicy, policyProfile, payCodes)


Updates the Pay Code Map policy that is linked to the indicated Policy Profile to assign the specified Field
Security Policy policy for all of the indicates Pay Codes.

PolicyDefinition
PolicyDefinition(policyId, parms, description, effDate)
Creates a new PolicyDefinition using the provided settings. The type of object specified for parms will
determine the type of policy being created. (For instance, if a ScheduleTemplateParms object is provided,
then the PolicyDefinition will reflect the definition for a Schedule Template policy). For non-effective-dated
policies, the effective date will not be used and does not need to be specified. For effective-dated policies,
the effective date will be defaulted to 1900-01-01 if not specified.
Parameter Type Description
ScheduleTemplateParms Used to create a new Schedule Template policy
ScheduleCycleParms Used to create a new Schedule Cycle policy
PayCodeParms Used to create a new Pay Code policy
PayCodeValueParms Used to create a new Pay Code Value policy
PayCodeMapParms Used to create a new Pay Code Map policy
ExceptionParms Used to create a new Exception Code, Exception Rule, and Exception Trigger
policy
BankAccrualParms Used to create a new Bank Accrual Policy policy
TimeZoneParms Used to create a new Time Zone policy
FieldSecurityParms Used to create a new Field Security Policy policy
DataElementParms Used to create a new Data Element policy
Table 65: Object classes that can be specified for the parms object

ScheduleTemplateParms
ScheduleTemplateParms(parms)
Used to create a new Schedule Template policy.
Available parameters are:
Parameter Name Description

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 359


WT&A API Specifications 18.3 Policy Creation API

weekStartDay The day of the week that the template starts on. 1 = Sunday, 7 = Saturday.
For biweekly templates, 8 = second Sunday, 14 = second Saturday.
Details Array of details for the slices that make up the template.
Biweekly Indicates if the template is a biweekly template. Defaults to false.
hideFromScreen Indicates if the template should not be visible on the schedule screen. Defaults to
false.
Table 66: Parameters available when creating a new ScheduleTemplateParm

ScheduleTemplateSliceParms
ScheduleTemplateSliceParms(parms)
Defines the details for a single time slice that makes up a Schedule Template policy.
Available parameters are:
Parameter Name Description
payCode The pay code for the slice
dayNumber Number indicating which day the slice falls on. 1 = Sunday, 7 = Saturday. For
biweekly templates, 8 = second Sunday, 14 = second Saturday.
startDayNumber Number indicating which day the beginning of the slice falls on.
endDayNumber Number indicating which day the end of the slice falls on.
Hours Formula to use to compute the hours that apply for the slice.
Details JS object with properties corresponding to the additional settings that should apply
to the slice. Property name corresponds to the field name on the slice and the
property value is the value that should be used for that field.
Table 67: Parameters available when creating a new ScheduleTemplateSliceParms

ScheduleCycleParms
ScheduleCycleParms(parms)
Used to create a new Schedule Cycle policy.
Available parameters are:
Parameter Name Description
Templates Array of Schedule Template policy IDs, in the order
in which they should occur within the cycle.
Indicates if the template should not be visible on
hideFromScreen
the schedule screen. Defaults to false.
Table 68: Parameters available when creating a new ScheduleCycleParms

PayCodeParms
PayCodeParms(parms)
Used to create a new Pay Code policy.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 360


WT&A API Specifications 18.3 Policy Creation API

PayCodeValuesParms
PayCodeValuesParms(parms)
Used to create a new Pay Code Value policy.
Available parameters are:
Parameter Name Description
Systems JS object mapping from pay_code_system field
number to the value for that field
JS object mapping from pay_code_other_string
otherStrings
field number to the value for that field
JS object mapping from pay_code_other_number
otherNumbers
field number to the value for that field
The amount value for the Pay Code Value. Defaults
Amount
to 0.
The factor value for the Pay Code Value. Defaults
Factor
to 0.
The percent value for the Pay Code Value. Defaults
Percent
to 0.
The rate value for the Pay Code Value. Defaults to
Rate
0.
Table 69: Parameters available when creating a new PayCodeValueParms

PayCodeMapParms
PayCodeMapParms(parms)
Used to create a new Pay Code Map policy.
Available parameters are:
Parameter Name Description
Array of pay code map details for the pay codes in
Details
the pay code map.
Table 70: Parameters available when creating a new PayCodeMapParms

PayCodeMapDetailParms
PayCodeMapDetailParms(parms)
Used to define a single detail row defining the behavior for one Pay Code within a Pay Code Map.
Available parameters are:
Parameter Name Description
isSchedule True if the detail is describing a schedule mapping,
false if it is describing a timesheet mapping.
payCode The Pay Code associated with the map entry.
The Field Mapping Policy defining the entry type to
entryField
use for the Pay Code.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 361


WT&A API Specifications 18.3 Policy Creation API

The Bank Usage Policy associated with the Pay


bankUsage
Code.
The Pay Code Formula that applies for the Pay
payCodeFormula
Code.
payCodeValue The Pay Code Value that applies for the Pay Code.
The Field Security Policy associated with the Pay
fieldSecurity
Code.
ID of the role set identifying which roles can view
canView
the Pay Code.
ID of the role set identifying which roles can add or
canEdit
delete the Pay Code.
Table 71: Parameters available when creating a new PayCodeMapDetailParms

ExceptionParms
ExceptionParms(parms)
Used to create a new Exception Code policy, along with its associated Exception Rule and Exception Trigger
policies.
Available parameters are:
Parameter Name Description
Severity The severity of the exception.
The message that should be displayed by the
Message
exception.
Defines which actions the user is prohibited from
preventUserActions
performing if the exception is present.
The message describing the action that needs to be
requiredAction
taken by the user to resolve the exception.
The formula context in which the exception should
Context
be evaluated.
The formula to be evaluated to determine if the
Formula
exception should trigger.
ID of the role set identifying which roles can see the
canView
exception.
The calculation stage where the exception should
calcStage trigger. Defaults to EXCEPTION_TRIGGER_001 if
not specified.
Table 72: Parameters available when creating a new ExceptionParms

BankAccrualParms
BankAccrualParms(parms)
Used to create a new Bank Accrual Policy policy.
Available parameters are:
Parameter Name Description
Frequency Defines how often the accrual happens.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 362


WT&A API Specifications 18.3 Policy Creation API

Formula that determines if the accrual should


Qualification
trigger.
serviceUnits Units to use for measuring the length of service.
Reference date that the length of service is
serviceDate
measured from.
Array of service ranges and their associated
serviceRanges
settings.
Number of days before/after the anniversary date
anniversaryOffset
to accrue on.
The date the anniversary should be measured
anniversaryDate
from.
dayNumber Day of the month the accrual should happen on.
Indicates whether semi-monthly accruals happen
semiMonthlyAccrueOn
on the period end date or on a specific other date.
First day that semi-monthly accruals should
semiMonthlyDayOne
happen on.
Second day that semi-monthly accruals should
semiMonthlyDayTwo
happen on.
Indicates how day two for semi-monthly accruals is
semiMonthlyDayTwoOption
defined.
Defines which day of the month is used for
monthlyAccrueOn
monthly accruals.
Defines how often accruals that happen multiple
xMonthlyAccrueOn
times per year should happen.
Defines the reference month for accruals that
xMonthlyReferenceMonth
happen multiple times per year.
annualAccrueOn Defines when annual accruals happen.
annualMonth The month to accrue during for annual accruals.
The day within the month to accrue on for annual
annualDay
accruals.
Defines whether period-based accruals happen at
periodReferenceDate the beginning of the period or the end of the
period.
Defines how accruals that happen on holidays
holidayAccrueOn
should happen.
Number of days before/after the holiday date
holidayOffset
accruals should happen on.
The set of holidays that should trigger the accrual
holidaySet
to happen.
Indicates if accrual amounts should be divided by
divideAccrualAmounts the number of periods in the year. Defaults to
true.
Table 73: Parameters available when creating a new BankAccrualParms

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 363


WT&A API Specifications 18.3 Policy Creation API

BankAccrualServiceRangeParms
BankAccrualServiceRangeParms(parms)
Used to define a single service range detail that makes up a Bank Accrual Policy policy.
Available parameters are:
Parameter Name Description
rangeStart The minimum length of time (in the service units
indicated on the corresponding Bank Accrual Policy
policy) the employee needs to have worked to
qualify for this service range.
The maximum length of time (in the service units
indicated on the corresponding Bank Accrual Policy
rangeEnd
policy) the employee needs to have worked to
qualify for this service range.
The formula to evaluate to determine the amount
accrualFormula
that should be accrued.
The formula to evaluate to determine if this service
Qualification
range applies to an employee.
The formula to evaluate to determine the
maxLiimit
maximum balance an employee is allowed to have.
Table 74: Parameters available when creating a new BankAccrualServiceRangeParms

TimeZoneParms
TimeZoneParms(parms)
Used to create a new Time Zone policy.
Available parameters are:
Parameter Name Description
isoCode The ISO code specifying which time zone the policy
represents.
Table 75: Parameters available when creating a new TimeZoneParms

FieldSecurityParms
FieldSecurityParms(parms)
Used to create a new Field Security Policy policy.
Available parameters are:
Parameter Name Description
Fields Array of field details for the policy.
Table 76: Parameters available when creating a new FieldSecurityParms

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 364


WT&A API Specifications 18.3 Policy Creation API

FieldSecurityFieldParms
FieldSecurityFieldParms(parms)
Used to define a single set of field details belonging to a Field Security Policy policy.
Available parameters are:
Parameter Name Description
fieldMappingPolicy The Field Mapping Policy for the detail record.
The role set ID for the set of roles allowed to view
canView
the field.
The role set ID for the set of roles allowed to edit the
canEdit
field.
Table 77: Parameters available when creating a new FieldSecurityFieldParms

DataElementParms
DataElementParms(parms)
Used to create a new Data Element policy.
Available parameters are:
Parameter Name Description
Details Array of details defining the table mappings for this
Data Element.
The distributed Data Element whose definition
overrideElement
should be overridden by this policy.
Indicates if the policy ID should not be projected as
doNotProjectAlias
an alias in the tables. Defaults to false.
Table 78: Parameters available when creating a new DataElementParms

DataElementDetailParms
DataElementDetailParms(parms)
Used to define a single table mapping for a Data Element policy.
Available parameters are:
Parameter Name Description
tableName The name of the table that the mapping applies to.
fieldname The field in the table that the mapping applies to.
Variable field number that should be used for the
mapping, if the field selected is a variable field. If
varFieldNo
not specified for a variably-numbered field then the
next available field will be automatically used.
Table 79: Parameters available when creating a new DataElementDetailParms

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 365


WT&A API Specifications 18.3 Policy Info API

Policy Info API


Overview and Capabilities
The Policy Info API provides a mechanism for scripts to lookup information about the policies that are defined
in the current configuration. This can be used to drive script logic (such as looking up a setting from the
System Setup policy and using that to control the logic in the script), for validating that a particular policy
exists, or to look up additional information about a policy (for example, an export that needs to extract the
description defined for a Pay Code rather than the actual Pay Code ID itself).
The data returned by the Policy Info API is read-only, and cannot be used to modify the configuration from
within a script. If a script needs to make changes to policy information, the Policy Creation API should be
used._Policy_Creation_API

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Understanding of policies and their settings

Components
This API consists of the following component(s):
• The distributed JavaScript library POLICY_INFO_API

Setup
No setup is necessary for the Policy Info API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Loading Data for a Non-Effective-Dated Policy
The Policy Info API can be used to load data for policies that are not effective dated. In these cases, no
effective date needs to be supplied in order to access the policy information.
The following examples demonstrate how the Policy Info API can be used to look up information for the Role
“EMPLOYEE_GENERAL”:

Example 1: Loading master data for a non-effective-dated policy


includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Role EMPLOYEE_GENERAL


var policyType = "RIGHT_GRP";
var policyName = "EMPLOYEE_GENERAL";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 366


WT&A API Specifications 18.3 Policy Info API

log.info("Data for Role EMPLOYEE_GENERAL");


log.info("Policy type = " policyData.getPolicyType() );

// Get the master data for the policy


var masterData = policyData.getMasterInfo();

// Print out information about the master details


log.info("Policy name = " + masterData.right_grp);
log.info("Description = " + masterData.short_description);
log.info("Type of role = " + masterData.role_type);

Note: For policies that don’t include an effective-dated component, getMasterInfo() and getMasterDetails()
will both return exactly the same information.

Example 2: Loading detail data for a non-effective-dated policy


includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Role EMPLOYEE_GENERAL


var policyType = "RIGHT_GRP";
var policyName = "EMPLOYEE_GENERAL";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Role EMPLOYEE_GENERAL");
log.info("Policy type = " policyData.getPolicyType() );

// Get the detail data for the policy. In this case, get the list of system features
// that are available to the role
var details = policyData.getDetailInfo("RIGHT_GRP_DETAIL");

// Iterate over the details and print out the system features that are available
for (var i = 0; i < details.length; ++i) {
log.info("System feature = " + details[i].system_feature);
log.info("Security option = " + details[i].security_option);
}

Loading Data for an Effective-Dated Policy


The Policy Info API can be used to load data for policies that are effective dated. In these cases, an effective
date needs to be supplied when accessing the policy data in order to get the correct data returned.
The following examples demonstrate how the Policy Info API can be used to look up information for the Pay
Code Map “EXEMPT”:

Example 1: Loading master data for an effective-dated policy


includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 367


WT&A API Specifications 18.3 Policy Info API

// Load the policy information for the Pay Code Map EXEMPT
var policyType = "PAY_CODE_MAP";
var policyName = "EXEMPT";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Pay Code Map EXEMPT");
log.info("Policy type = " policyData.getPolicyType() );

// Define the effective date we're interested in


var asOfDate = WFSDate.today();

// Get the master data for the policy


var masterData = policyData.getMasterInfo(asOfDate);

// Print out information about the master details


log.info("Policy name = " + masterData.pay_code_map);
log.info("Effective date = " + masterData.eff_dt);
log.info("End effective date = " + masterData.end_eff_dt);

Note: For policies that don’t include a non-effective-dated component, getMasterInfo() and
getMasterDetails() will both return exactly the same information.

Example 2: Loading detail data for an effective-dated policy


includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Pay Code Map EXEMPT
var policyType = "PAY_CODE_MAP";
var policyName = "EXEMPT";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Pay Code Map EXEMPT");
log.info("Policy type = " policyData.getPolicyType() );

// Define the effective date we're interested in


var asOfDate = WFSDate.today();

// Get the timesheet details for the policy


var timeSheetDetails = policyData.getDetailInfo("PAY_CODE_MAP_DETAIL", asOfDate);

// Iterate over the timesheet details and print out information about them
log.info("Timesheet details:");
for (var i = 0; i < timeSheetDetails.length; ++i) {
log.info("Pay code = " + timeSheetDetails[i].pay_code);
log.info("Entry field = " + timeSheetDetails[i].entry_field);
log.info("Pay code formula = " + timeSheetDetails[i].pay_code_formula);
log.info("Pay code value = " + timeSheetDetails[i].pay_code_value);
}

// Get the schedule details for the policy

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 368


WT&A API Specifications 18.3 Policy Info API

var scheduleDetails = policyData.getDetailInfo("PAY_CODE_MAP_SCHED_DETAIL",


asOfDate);

// Iterate over the schedule details and print out information about them
log.info("Schedule details:");
for (var i = 0; i < scheduleDetails.length; ++i) {
log.info("Pay code = " + scheduleDetails[i].pay_code);
log.info("Entry field = " + scheduleDetails[i].entry_field);
}

Loading Data for a Policy with Both Effective-Dated and Non-Effective-


Dated Components
Some policies, such as the Exception Trigger Group or Policy Profile Master, include both an effective dated
component and a non-effective-dated component. The Policy Info API can be used to load data for this
variety of policy as well. In these cases, an effective date needs to be supplied when accessing the effective-
dated portion of the policy data in order to get the correct data returned, but is not needed when accessing
the non-effective dated portion.
The following examples demonstrate how the Policy Info API can be used to look up information for the
Exception Trigger Group “EXEMPT_TRIGGERS”:

Example 1: Loading the non-effective-dated master data for a policy with both effective-
dated and non-effective-dated components
includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Exception Trigger Group EXEMPT_TRIGGERS
var policyType = "EX_TRIGGER_GRP_MASTER";
var policyName = "EXEMPT_TRIGGERS";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Exception Trigger Group EXEMPT_TRIGGERS");
log.info("Policy type = " policyData.getPolicyType() );

// Get the non-effective-dated master data for the policy


var masterData = policyData.getMasterInfo();

// Print out information about the non-effective-dated master data


log.info("Policy name = " + masterData.exception_trigger_group);
log.info("Description = " + masterData.long_description);

Example 2: Loading the effective-dated master data for a policy with both effective-
dated and non-effective-dated components
includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 369


WT&A API Specifications 18.3 Policy Info API

// Load the policy information for the Exception Trigger Group EXEMPT_TRIGGERS
var policyType = "EX_TRIGGER_GRP_MASTER";
var policyName = "EXEMPT_TRIGGERS";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Exception Trigger Group EXEMPT_TRIGGERS");
log.info("Policy type = " policyData.getPolicyType() );

// Define the effective date we're interested in


var asOfDate = WFSDate.today();

// Get the effective-dated master data for the policy


var masterDetails = policyData.getMasterDetails(asOfDate);

// Print out information about the effective-dated master data


log.info("Policy name = " + masterDetails.exception_trigger_group);
log.info("Effective date = " + masterDetails.eff_dt);
log.info("End effective date = " + masterDetails.end_eff_dt);

Example 3: Loading detail information for a policy with both effective-dated and non-
effective-dated components
includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Exception Trigger Group EXEMPT_TRIGGERS
var policyType = "EX_TRIGGER_GRP_MASTER";
var policyName = "EXEMPT_TRIGGERS";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Exception Trigger Group EXEMPT_TRIGGERS");
log.info("Policy type = " policyData.getPolicyType() );

// Define the effective date we're interested in


var asOfDate = WFSDate.today();

// Get the exception triggers that are part of the trigger group
var triggers = policyData.getDetailInfo("EX_TRIGGER_GRP_DETAIL", asOfDate);

// Iterate over the triggers and print out information about them
for (var i = 0; i < triggers.length; ++i) {
log.info("Exception trigger = " + triggers[i].exception_trigger);
}

Dealing with Policy Changes During Script Execution


If the script using the Policy Info API is running over an extended period of time, or if it is modifying policy
information directly, then there is the possibility that the policy data that existed at the time the Policy Info
API was instantiated may no longer be correct. The Policy Info API will not automatically update to reflect

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 370


WT&A API Specifications 18.3 Policy Info API

these changes; unless special action is taken, the data returned by the Policy Info API will always reflect the
configuration as it existed at the time the API was created in the script.
The loadLatestPolicies() method can be used to update the Policy Info API to take into account all of the
latest policy changes. The following script example demonstrates how this method could be used within a
script:

Example: Dealing with policy changes during script execution


includeDistributedPolicy("POLICY_INFO_API");

// Create a new instance of the API


var api = new PolicyInfoAPI();

// Load the policy information for the Role EMPLOYEE_GENERAL


var policyType = "RIGHT_GRP";
var policyName = "EMPLOYEE_GENERAL";
var policyData = api.getPolicyInformation(policyType, policyName);

// Print out information about the policy


log.info("Data for Role EMPLOYEE_GENERAL");
log.info("Policy type = " policyData.getPolicyType() );

// Get the master data for the policy


var masterData = policyData.getMasterInfo();

// Print out information about the master details


log.info("Policy name = " + masterData.right_grp);
log.info("Description = " + masterData.short_description);
log.info("Type of role = " + masterData.role_type);

// At this point it is assumed that some policy changes happen that


// would change the data in this policy

// Refresh the policy information used by the API


api.loadLatestPolicies();

// Get the information for the Role policy again. This will now
// reflect any changes that were made after the API was originally
// instantiated.
policyData = api.getPolicyInformation(policyType, policyName);

// Get the master data for the policy


var masterData = policyData.getMasterInfo();

// Print out information about the master details


log.info("Policy name = " + masterData.right_grp);
log.info("Description = " + masterData.short_description);
log.info("Type of role = " + masterData.role_type);

Checking if a policy exists


If you are not sure if a policy exists when writing the script and want to avoid exception handling everywhere
it is referenced, you can use the exists(policyType, policyName) method in the API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 371


WT&A API Specifications 18.3 Policy Info API

Example: Dealing with possibly missing policies


includeDistributedPolicy("POLICY_INFO_API");
// Create a new instance of the API
var api = new PolicyInfoAPI();

// check if a policy exist and return early if it does not


var policyType = "EX_TRIGGER_GRP_MASTER";
var policyName = "EXEMPT_TRIGGERS";

if (!api.exists(policyType, policyName)) {
// throw an error here or log something
Return;
}

This way you can make sure that every time you need to reference the policy after this point, it will exist and
no additional try-catch blocks are needed

Getting names of all policies of specific type


This script excerpt below demonstrates getting the name of all policies of the specified policy type.

Example: Retrieving names of policies


includeDistributedPolicy("POLICY_INFO_API");

var policyInfoAPI = new PolicyInfoAPI();


// get all policies for the policy type ADP_EXPORT
var getPoliciesMethodResult = policyInfoAPI.getPolicyList('ADP_EXPORT');
// query for getting all policies for policy type ADP_EXPORT for verification
var query = "select ADP_EXPORT from ADP_EXPORT";
var c = new Connection();
var getPoliciesQueryResult = [];
try {
var result = new Sql(c, query);
// storing the query result in array for comparison
while (result.next()) {
getPoliciesQueryResult.push(result.ADP_EXPORT);
}
}
// if the count of both results are not same, there is no need to compare the results
if (getPoliciesQueryResult.length == getPoliciesQueryResult.length) {
for (var i = 0; i < getPoliciesMethodResult.length; i++) {
var found = false;
// using for loop here since array.indexof was not working in rhinoscript
for (var j = 0; j < getPoliciesQueryResult.length &amp;&amp; found == false; j++) {
if (getPoliciesMethodResult[i] == getPoliciesQueryResult[j]) {
found = true;
}
}
if (!found) {
throw "Values returned by method do not match values returned by query";
}
}
}
else {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 372


WT&A API Specifications 18.3 Policy Info API

throw "Values returned by method do not match values returned by query";


}

Troubleshooting
The job log of the script using the Policy Info API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No policy table specified The script tried to load data for a Ensure that every attempt to load
policy without specifying which policy data correctly specifies a source
type of policy should be looked up. table for the policy that should be
loaded.
Table TABLE_NAME does The table name specified when Ensure that all policy tables referenced
not exist loading policy data does not match when loading policy data represent
a table defined by WorkForce Time valid tables in the WorkForce Time and
and Attendance. Attendance schema.
POLICY_TYPE is not a valid The table name specified when Ensure that all tables referenced when
policy type loading policy data matched an loading policy data represent valid
WorkForce Time and Attendance tables that contain policy data.
table, but that table does not
contain policy data.
POLICY_TYPE is a detail type, The table name specified when Ensure that the master table for the
not a master policy type. To loading policy data was a table that desired type of policy information is
access this information, a stores policy details (e.g. detail specified when loading policy
policy type of rows on a tab of a policy), rather information.
PARENT_POLICY_TYPE than the master table for the policy
should be specified itself.
Non-policy table The table name specified when Ensure that all policy tables referenced
TABLE_NAME specified loading policy data either didn’t when loading policy data represent
match an WorkForce Time and valid tables in the WorkForce Time and
Attendance table, or matched an Attendance schema that contain policy
WorkForce Time and Attendance data.
table but that table does not
contain policy data.
Policy POLICY_NAME is not a No policy of the specified name Ensure that a valid policy name is
valid policy of type exists for the indicated policy type. specified by the script, or include error
POLICY_TYPE handling in the script that checks for
this condition if a missing policy is a
valid condition for the script.
An as-of date must be An attempt was made to access Ensure that an as-of date is always
specified when accessing details of an effective-dated policy supplied by the script when attempting
DETAIL_TYPE details of without having specified an as-of to look up policy details for effective-
effective-dated policy date to use to evaluate the policy dated policies.
POLICY_NAME of type data.
POLICY_TYPE

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 373


WT&A API Specifications 18.3 Policy Info API

Invalid detail type An attempt was made to access Ensure that all attempts to access
DETAIL_TYPE specified for detail information of a policy of a detail information for a policy are
policy type POLICY_TYPE. type that does not exist for that specifying a detail type that actually
Valid detail types are: policy. exists for that type of policy.
LIST_OF_VALID_DETAIL_TYP
ES
An as-of date must be An attempt was made to access the Ensure that an as-of date is always
specified when accessing master information of an effective- supplied by the script when attempting
master details of effective- dated policy without having to look up policy master information
dated policy POLICY_NAME specified an as-of date to use to for effective-dated policies.
of type POLICY_TYPE evaluate the policy data.
Table 80: Policy Info API typical error messages, root problems, and solution

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Policy Info API defines a mechanism for requesting information about policies:
• Returned by the PolicyInfoApi are _PolicyInfo objects, which encapsulate all policy information
(include master and detail information, and all effective-dated changes) for a particular policy. These
objects cannot be instantiated directly.
See the contents of the POLICY_INFO_API policy in the Distributed JavaScript Library category for full
documentation on these methods. The following is a summary of the available methods and common uses:

PolicyInfoAPI
PolicyInfoAPI()
Creates a new instance of the Policy Info API.

getPolicyInformation(policyType, policyName)
Returns the policy information for the policy of the specified type with the indicated name.

loadLatestPolicies()
Refreshes the policy information in the PolicyInfoAPI to reflect the latest policy data. This needs to be called
anytime there are policy changes after the PolicyInfoAPI is created in order for its results to reflect those
policy changes.

exists(policyType, policyName)
Returns true if the specified policy exists, false otherwise.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 374


WT&A API Specifications 18.3 Policy Info API

_PolicyInfo
getPolicyType()
Returns which type of policy is represented by the data contained in this object. The policy type returned will
always reflect the table name of the top-level parent table for the policy type (e.g. for an Exception Trigger
policy, the value returned would be “EXCEPTION_TRIGGER_MASTER”).

getMasterInfo(asOfDate)
Returns the master policy information for the policy. If the policy is effective dated, this will return the policy
information that is effective on the specified as-of date.
If the policy includes both effective-dated and non-effective-dated components, this will return the non-
effective-date portion of the policy data. If the policy only includes either effective-dated or non-effective-
dated data, then this will return the same data as getMasterDetails().

getMasterDetails(asOfDate)
Returns the master detail policy information for the policy. If the policy includes both effective-dated and
non-effective dated components, this will return the effective-dated portion of the policy data. Otherwise,
this will return exactly the same data that getMasterInfo() returns.

getDetailInfo(detailType, asOfDate)
Returns an array of details for the policy of the indicated detail type. The detail type should reflect the table
name for the type of details that should be returned (e.g. for the schedule mappings in a Pay Code Map, this
should be “PAY_CODE_MAP_SCHED_DETAIL”). If the policy is effective dated, this will return the details that
are effective on the specified as-of date.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 375


WT&A API Specifications 18.3 Policy Mapping API

Policy Mapping API


Overview and Capabilities
The Policy Mapping API provides a mechanism for evaluating policy mappings to determine which policy the
given record maps to.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• Understanding of policies and their settings

Components
This API consists of the following component(s):
• The distributed JavaScript library POLICY_MAPPING_API

Setup
No setup is necessary for the Policy Info API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
DETERMINE THE HOLIDAY POLICY TO BE APPLIED TO THE EMPLOYEE
Example 1: DETERMINE THE HOLIDAY POLICY TO BE APPLIED TO THE EMPLOYEE
includeDistributedPolicy("POLICY_MAPPING_API");

// Create a new instance of the API


var api = new PolicyMappingAPI();

// Use the policy mapping screen logic to define the holiday set
try {
assignment.holiday_set = api.evaluate("HOLIDAYS", employee, assignment);
} catch (e) {
log.warning("No specific mapping for received CALENDAR value: '" + source.CALENDAR +
"', will try to assign value as the employee's Holiday Set");
}

Troubleshooting
The job log of the script using the Policy Mapping API will contain information messages and in the case of
problems, any error messages that were generated during processing. This job log should be reviewed if
there are any problems encountered when using the API.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 376


WT&A API Specifications 18.3 Policy Mapping API

Error Message Problem Solution


No mapping found The mapping parameters defined Supply valid parameters.
returned no match
Table 81: Policy Mapping API typical error messages, root problems, and solution

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Policy Mapping API defines a mechanism for evaluating policy mappings to determine which policy the
given record maps to:
• When no Mapping is found, the PolicyMappingApi triggers an exception. The error is a string
detailing the nature of the problem.
See the contents of the POLICY_MAPPING_API policy in the Distributed JavaScript Library category for full
documentation on these methods. The following is a summary of the available methods and common uses:

PolicyMappingAPI
PolicyMappingAPI()
Creates a new instance of the Policy Mapping API.

evaluateAsOf(policyType: String, employee: DbRecEmployee, asgnmt: DbRecAsgnmt,


asOfDate: WDate)
Evaluates the mappings defined for the specified policy type, returning the first policy ID that the data maps
to.

evaluateAllAsOf(policyType: String, employee: DbRecEmployee, asgnmt: DbRecAsgnmt,


asOfDate: WDate)
Evaluates the mappings defined for the specified policy type, returning all the policy IDs that the data maps
to.

evaluate(policyType: String, employee: DbRecEmployee, asgnmt: DbRecAsgnmt)


Evaluates the mappings defined for the specified policy type, returning the first policy ID that the data maps
to. The effective date used to determine which mapping definition to use will be based on the effective dates
specified on the employee/assignment records. If the assignment's effective date is populated, that date will
be used, otherwise the employee's effective date will be used.

evaluateAll(policyType: String, employee: DbRecEmployee, asgnmt: DbRecAsgnmt)


Evaluates the mappings defined for the specified policy type, returning all the policy IDs that the data maps
to. The effective date used to determine which mapping definition to use will be based on the effective dates
specified on the employee/assignment records. If the assignment's effective date is populated, that date will
be used, otherwise the employee's effective date will be used.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 377


WT&A API Specifications 18.3 Policy Set API

Policy Set API


Overview and Capabilities
The Policy Set API provides a means for interface scripts to determine which policies belong to a given set on
a particular date. This can be used for validation purposes, such as validating that a value provided in the
source data is an allowed value for an import, or to drive logic in a script (e.g. filtering out all records with pay
codes not in a particular set as part of an Incremental Export).

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• How policy sets function within WorkForce Time and Attendance

Components
This API consists of the following component(s):
• The Distributed JavaScript Library policy POLICY_SET_API

Setup
No setup is necessary for the Policy Set API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Identifying Policies in a Policy Set
The Policy Set API allows a script to determine the policy IDs of all policies that belong to a particular set on a
given date. The following example demonstrates using the Policy Set API to look up all pay codes in the set
PAY_CODES_TO_IMPORT, rejecting any records that specify a pay code not included in the set:

Example: Identifying Policies in a Policy Set


includeDistributedPolicy("POLICY_SET_API");
includeDistributedPolicy("EMPLOYEE_IMPORT_UTIL");

// Initialize the API


var api = new PolicySetAPI();

// Define the set to be looked up


var policyType = "PAY_CODE";
var setName = "PAY_CODES_TO_IMPORT";
var asOfDate = WFSDate.today();

// Look up all of the policies in the set


var policies = api.getPoliciesInSet(policyType, setName, asOfDate);

// Process all records in a result set named "source"


while (source.next() ) {
// Assume the source contains a field named "pay_code"

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 378


WT&A API Specifications 18.3 Policy Set API

var sourcePayCode = source.pay_code;

// Compare the pay code from the source against the policy set
if (inArray(policies, sourcePayCode) ) {
// The policy set contains the pay code, so do whatever processing is needed
}
else {
// The set does not contain the pay code, so display an error message
log.error("The policy set " + setName + " does not contain a " + policyType +
" policy named " + sourcePayCode);
}
}

Note: Policy sets are effective dated within WorkForce Time and Attendance, which means that the policies
that belong to a set can vary depending on the date being evaluated. If your script is processing
records that can span multiple dates, such as time records, be sure that you are evaluating them using
the policy set data for the correct date.

If additional information is needed about a policy belonging to a set beyond just its policy ID, then the Policy
Info API can be used to load all of the additional attributes for that policy._Policy_Info_API

Retrieving names of policy sets for a policy type


This script excerpt demonstrates getting the name of all policy sets of the specified policy type.

Example: Retrieving names of policy sets


includeDistributedPolicy("POLICY_SET_API");

var policySetAPI = new PolicySetAPI();


// get all policy sets for the policy type RETRO_TRIGGER_FIELD
var getPolicySetMethodResult = policySetAPI.getPolicySetList('RETRO_TRIGGER_FIELD');
// query for getting all policy sets for policy type RETRO_TRIGGER_FIELD for verification
var query = "select distinct RULE_SET from RULE_SET_DETAIL where SOURCE_TABLE like
'RETRO_TRIGGER_FIELD'";
var c = new Connection();
var getPolicySetQueryResult = [];
try {
var result = new Sql(c, query);
// storing the query result in array for comparison
while (result.next()) {
getPolicySetQueryResult.push(result.RULE_SET);
}
}
// if the count of both results are not same, there is no need to compare the results
if (getPolicySetMethodResult.length == getPolicySetQueryResult.length) {
for (var i = 0; i < getPolicySetMethodResult.length; i++) {
var found = false;
// using for loop here since array.indexof was not working in rhinoscript
for (var j = 0; j < getPolicySetQueryResult.length &amp;&amp; found == false; j++) {
if (getPolicySetMethodResult[i] == getPolicySetQueryResult[j]) {
found = true;
}
}
if (!found) {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 379


WT&A API Specifications 18.3 Policy Set API

throw "Values returned by method do not match values returned by query";


}
}
}
else {
throw "Values returned by method do not match values returned by query";
}

Troubleshooting
The job log of the script using the Policy Set API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No policy set type specified A call was made to Ensure that the script is correctly
getPoliciesInSet() where the policy specifying a value for the policyType
type was either not specified or argument when calling
was null/blank. getPoliciesInSet().
No policy set name A call was made to Ensure that the script is correctly
specified getPoliciesInSet() where the name specifying a name for the policy set to
of the set to look up was either not look up when calling
specified or was null/blank. getPoliciesInSet().
POLICY_TYPE is not a valid The policy type specified does not Ensure that the value specified for the
policy set type corresponding to a valid policy type to look up matches the
WorkForce Time and Attendance table name in the database of a table
policy type. that contains policy information.
No as-of date specified An attempt was made to look up a Ensure that the script is providing a
when evaluating a policy policy set of the indicated type and value for the as-of date when looking
set (Policy type = set name without specifying an as- up the policies in a set.
POLICY_TYPE, policy name of date. Since the policies in a set
= SET_NAME) can change depending on the date,
a date is necessary in order to look
up the right policy information.
Policy Set SET_NAME does The current WorkForce Time and Ensure that the script is using a set
not exist for type Attendance configuration does not name that is actually defined for the
POLICY_TYPE on include a definition for a policy set type of set being looked up. If the set
AS_OF_DATE of the indicated type with the was potentially created after the API
specified set name that is effective was initialized but before looking up
on the specified as-of date. the policies in the set, it is possible
that the API might need to be
refreshed using loadLatestPolicies().
Table 82: Policy Set API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 380


WT&A API Specifications 18.3 Policy Set API

PolicySetAPI
Creates a new instance of the Policy Set API. Policy data as it exists in the configuration at the time this is
called will be used for determining which policies belong to which sets.

getPoliciesInSet(policyType, setName, asOfDate)


Returns an array containing the names of all of the policies belonging to the specified set on the indicated
date.

loadLatestPolicies()
Updates the policy information used by the API to reflect any changes that have been made to the policies
since the API was originally instantiated. This is particularly important if the script itself is making any
changes to the policies in the configuration.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 381


WT&A API Specifications 18.3 PPI Data Connector API

PPI Data Connector API


Overview and Capabilities
The PPI Data Connector API lets you create data connectors to read/write data from various sources or
channels, including File, SFTP, SQL, and CSV file.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The PPI_DATA_CONNECTOR Distributed JavaScript Library

Setup
No setup is necessary for the PPI_DATA_CONNECTOR. The distributed library is automatically available in
WT&A.

Use Cases
Creating a file data connector to get read/write access to a file
The following script example demonstrates how the FileConnector can be created to get read/write access to
a file.

Example 1: Reading data from a system file


This example shows how to read data as a string from a file.
includeDistributedPolicy("PPI_DATA_CONNECTOR");

var FILE_PATH = "/workforce/RegTests/PartnerProductInterface/HRImport/ImportDataXmls/";


var FILE_NAME = "TT29866_UFT_16_1.xml";
var characterEncoding = "UTF-16"; // Encoding

try {
// Create data connector for a file
var dataConnector = FileConnector(FILE_PATH + FILE_NAME , characterEncoding);
//get data from a file through data connector
var fileData = dataConnector.getData();
log.info("Printing Data: \n" + fileData);
log.info("DataConnector read data from the file successfully.");
} catch (e) {
log.error("Error: " + e);
}

Example 2: Writing data to a system file


This example shows how to write data to a file.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 382


WT&A API Specifications 18.3 PPI Data Connector API

includeDistributedPolicy("PPI_DATA_CONNECTOR");

var FILE_PATH = "/workforce/RegTests/PartnerProductInterface/HRImport/ImportDataXmls/";


var FILE_NAME = "TT29866_UFT_16_1.xml";
var characterEncoding = "UTF-16"; // Encoding
try {
//Create data connector for a file
var dataConnector = new FileConnector(FILE_PATH + FILE_NAME , characterEncoding);
//write data to a file through data connector
dataConnector.sendData("Hello World"); // write data without placeholder
// dataConnector.sendData("Hello %name%",{name: John}); // write data with
placeholders

log.info("DataConnector writes data to the file successfully.");


} catch (e) {
log.error("Error: " + e);
}

Creating a SFTP data connector to read/write a file


The following script example demonstrates how the SFTPConnector can be created to read/write a file
from/on a specified SFTP server.

Example 1: Reading data from a remote file


This example shows how to read a remote file from SFTP server.
includeDistributedPolicy("PPI_DATA_CONNECTOR");

try {
// Create data connector for a SFTP server
var dataConnector = new SFTPConnector("10.110.1.66", "workforce", "mittens", "22",
"/UTF-8.csv", "UTF-8", false, "", true);
//get data from a file through data connector
var fileData = dataConnector.getData();
log.info("Printing Data: \n" + fileData);
log.info("DataConnector read data from the file successfully.");
} catch (e) {
log.error("Error: " + e);
}

Example 2: Writing data to a remote file


This example shows how to write data to a remote file on the SFTP server.
includeDistributedPolicy("PPI_DATA_CONNECTOR");

try {
// Create data connector for a SFTP server
var dataConnector = new SFTPConnector("10.110.1.66", "workforce", "mittens", "22",
"/UTF-8.csv", "UTF-8", false, "", true);
//write data to a file through data connector
dataConnector.sendData("Hello World"); // write data without placeholder
// dataConnector.sendData("Hello %name%",{name: John}); // write data with
placeholders
log.info("DataConnector writes data to the file successfully.");
} catch (e) {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 383


WT&A API Specifications 18.3 PPI Data Connector API

log.error("Error: " + e);


}

Creating a CSV file data connector to read data from a CSV file
The following script example demonstrates how the CSVConnector can be created to read a CSV file from the
system.

Example 1: Reading data from a remote file


This example shows how to read data from a CSV file.
includeDistributedPolicy("PPI_DATA_CONNECTOR");
var FILE_PATH = "workforce/RegTests/PartnerProductInterface/HRImport/ImportDataXmls/";
var fileName = ['ppi_csv_import_test_1_data.csv', 'ppi_csv_import_test_2_data.csv'];
var parameters = {baseDir: FILE_PATH, fileNames: [fileName]};
try {
// Create data connector for a CSV file
var dataConnector = new CSVFileConnector(parameters);
//get data from a file through data connector
var fileData = dataConnector.getData();
log.info("Printing Data: \n" + fileData);
log.info("DataConnector read data from the file successfully.");
} catch (e) {
log.error("Error: " + e);
}

Creating a SQL data connector to read data from a database


The following script example demonstrates how the SQLConnector can be created to read data from a
database.

Example 1: Reading data from a database


This example shows how to read data from a database.
includeDistributedPolicy("PPI_DATA_CONNECTOR");

var sourceConnectionInfo ="EMPCENTER_CONNECTION_1"; // DB_CONNECTION_INFO policy Name


// SQL Query for fetching data from SQL Source.
var sourceQuery="Select other_Date1 EFF_DT, Other_string1 EMP_ID, other_string2 " +
"from Ld20 where ld2=?";
var queryParams ="TT32644"; // SQL Query parameters try {
// Create data connector for a database
var dataConnector = new SQLConnector (sourceConnectionInfo, sourceQuery, queryParams);
//get data from a database through data connector
var data = dataConnector.getData();
log.info("Printing Data: \n" + data);
log.info("DataConnector read data from the database successfully.");
} catch (e) {
log.error("Error: " + e);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 384


WT&A API Specifications 18.3 PPI Data Connector API

Creating a data connector for a specified PPI Data Connector policy


The following script example demonstrates how the data connector for specific policy can be created to read
data.

Example 1: Reading data through the data connector


This example shows how to read data using the PPI Data Connector policy
includeDistributedPolicy("PPI_DATA_CONNECTOR");

try {
// get data connector of given policy id
var dataConnector = new getDataConnector("INT_1236_2");
//get data through data connector
var data = dataConnector.getData();
log.info("Printing Data: \n" + data);
log.info("DataConnector read data successfully.");
} catch (e) {
log.error("Error: " + e);
}

Example 2: Writing data through the data connector


This example shows how to write data through the data connector if the retuned data connector of a given
policy id supports to ability to write.
includeDistributedPolicy("PPI_DATA_CONNECTOR");

try {
// get data connector of given policy id
var dataConnector = new getDataConnector("INT_1236_2");
//write data through data connector
dataConnector.sendData("Hello World"); // write data without placeholder
// dataConnector.sendData("Hello %name%",{name: John}); // write data with
placeholders
log.info("DataConnector writes data to the file successfully.");
} catch (e) {
log.error("Error: " + e);
}

Troubleshooting
The job log of the script using the PPI Data Connector API will include informational messages, and in the case
of problems, error messages. This job log should be reviewed if there are problems using the library.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
No file path specified No file path specified as parameter for Provide the file path
method FileConnector
At least one file name should No file name is provided for Provide at least one file name
be provided to the CSVFileConnector or an array of file names
CSVFileConnector

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 385


WT&A API Specifications 18.3 PPI Data Connector API

File path is not specified for Base directory is not specified for Provide the base directory path
the CSVFileConnector CSVFileConnector from where file(s) should be
read
The directory does not exist at Incorrect base directory is provided for Provide correct base directory
specified path CSVFileConnector path
The path does not represent a Provided base directory path for Provide the correct base
directory CSVFileConnector is not a directory directory path and it should be
a directory
The directory at path (baseDir)
Provided base directory for Make sure the file(s) at
does not have read access CSVFileConnector doesn’t have read provided directory have read
access access
No DB Connection Info policy Name of DB_CONNECTION_INFO Provide correct name of the
specified for connecting Policy Name is not provided or DB_CONNECTION_INFO Policy
SQLConnector incorrect for SQLConnector
No SQL query provided for SQL query is not provided or null for Provide the SQL query
SQLConnector SQLConnector
Table 83: PPI_DATA_CONNECTOR common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to make the best use of this section.

PPI Data Connector


The following methods are available in the PPI_DATA_CONNECTOR Distributed JavaScript Library.

FileConnector (filePath, characterEncoding, encrypted, encryptionAlias,


enforceCharsetEncoding)
Creates an instance of a FileSystemConnector – an object that implements the DataConnector interface and
provides read/write access to a file on the file system.
Parameter Description
filePath (required) The absolute or relative path to the file from which data needs to be read or
written to
characterEncoding (optional) Canonical name of character set encoding, default is UTF-8 if not specified.
encrypted (optional) Flag to indicate whether file is encrypted or not (default false)
encryptionAlias(optional) Alias used for PGP encryption
enforceCharsetEncoding If true, file will be validated if it contains the correct character set, i.e.
(optional) specified. Defaults to false.

SFTPConnector (host, username, password, port, remoteFilePath, characterEncoding,


encrypted, encryptionAlias, enforceCharsetEncoding)
Creates an instance of a SFTPConnector – an object that implements the DataConnector interface and
provides read/write access to a file on a specified sftp server.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 386


WT&A API Specifications 18.3 PPI Data Connector API

Parameter Description
host (required) The name of sftp server
username (required) The username for authentication of the sftp server
password (required) The password for authentication of the sftp server
port (required) The port on which sftp server runs
remoteFilePath (required) Path to the file from root of sftp server from which data needs to be read or
written to
characterEncoding (optional) Canonical name of character set encoding, default is UTF-8 if not specified.
encrypted (optional) Flag to indicate whether file is encrypted or not (default false)
encryptionAlias(optional) Alias used for PGP encryption
enforceCharsetEncoding If true, file will be validated if it contains the correct character set, i.e.
(optional) specified. Defaults to false.

CSVFileConnector (parameters)
Creates an instance of a CSVFileConnector – an object that implements the DataConnector interface and
provides access for reading data from a CSV file. Takes an object as its parameter, which includes defined
parameters in the table.
Parameter Description
baseDir (required) The file path to the source file(s)
fileNames (required) Array of strings with the source file name(s)
delimiter (optional) A single character string with the custom delimiter. Default is ","
characterSet (optional) Name of the character set to be used to read the CSV files. Default is UTF-8.
startingLine (optional) The 0-based line number from where to start reading the CSV file. Lines
before this will be ignored. Default is 0.
autoTrim (optional) If true, white spaces are removed from the beginning and end of field values.
Default is false.
archiveFiles (optional) If true, CSV files passed in fileNames parameter are archived to a directory
specified in the archivePath parameter. Default is false.
archivePath (optional) Path where files will be archived. Default is [baseDir]\archive.
enforceCharsetEncoding If true, file will be validated if it contains the correct character set, i.e.
(optional) specified. Defaults to false.

SQLConnector (srcDBConnectionInfoPolicy, sourceQuery, queryParams)


Creates an instance of a SQLConnector – an object that implements the DataConnector interface and
provides access for reading data from a SQL data source.
Parameter Description
srcDBConnectionInfoPolicy The name of DB_CONNECTION_INFO Policy Name
(required)
sourceQuery (required) The string base SQL Query
queryParams (optional) An array of objects defining the query parameters

getDataConnector (policyId)
Returns the data connector for the specified PPI Data Connector policy ID.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 387


WT&A API Specifications 18.3 PPI Data Connector API

Parameter Description
policyId (required) Start date-time for the date-time range

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 388


WT&A API Specifications 18.3 Retro Trigger API

Retro Trigger API


Overview and capabilities
The Retro Trigger API lets you create, activate, deactivate, delete, and fetch retro triggers for
assignments.

Prerequisites
To use this API, you should know the following:

• Basic JavaScript coding

Components
The components of the Retro Trigger API are as follows:

1. The RETRO_TRIGGER_API Distributed JavaScript library


a. This automatically includes the API_UTIL Distributed JavaScript library
2. The MatchCondition, which defines a condition to select employee, assignment, or user records.

Setup
No setup is necessary for the Retro Trigger API. The distributed library is automatically available within
WT&A.

Use cases
Example 1: Create new Retro Trigger Event
The following script example demonstrates how the Retro Trigger API can be used to create a new retro
trigger event for an assignment based on a provided employee and assignment match condition.

includeDistributedPolicy("RETRO_TRIGGER_API");

//setup parameters
var parms = {
enableDebugging: true,
description: “API created group”
};

// Initialize the API


var retroApi = new RetroTriggerAPI (parms);

//Define match condition for an employee. This match condition will match an employee with the
display ID of 1163297

var empMatchCondition = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",


MatchOperator.EQUALS, "1163297");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 389


WT&A API Specifications 18.3 Retro Trigger API

//Define match condition for an assignment. This match condition will match an assignment with
the computed match ID of 1163297202327-5301

var asgMatchCondition = new MatchCondition(MatchTable.ASGNMT, "COMPUTED_MATCH_ID",


MatchOperator.EQUALS, "1163297202327-5301");

var triggerDate = new WFSDate(2017,10,11);

//Create retro-trigger event


retroApi.createRetroTrigger(empMatchCondition, asgMatchCondition, triggerDate ,"comments");

//Commit all created retro trigger events. This function must be called after the creation of
all retro trigger events to write them in database.

retroApi.commitRetroTriggers();

Note: The condition used here must match exactly one employee and assignment. If more than one employee
and assignment matches the condition, an exception will be generated.

Example 2: Activate Retro Trigger Events


The following script example demonstrates how the Retro Trigger API can be used to activate existing,
unprocessed inactive retro trigger events for an assignment.

includeDistributedPolicy("RETRO_TRIGGER_API");

var parms = {
enableDebugging: false,
description: "API created group"
};

//Initialize API
var retroApi = new RetroTriggerAPI(parms);

//Define match condition for an employee. This match condition will match an employee with the
display ID of 1163297
var empMatchCondition = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",
MatchOperator.EQUALS, "1163297");

//Define match condition for an assignment. This match condition will match an assignment with
the computed match ID of 1163297202327-5301
var asgMatchCondition = new MatchCondition(MatchTable.ASGNMT, "COMPUTED_MATCH_ID",
MatchOperator.EQUALS, "1163297202327-5301");

var startDate = new WFSDate(2017,10,11); //start trigger date for date range
var endDate = new WFSDate(2017,12,31); //end trigger date for date range
var includeInactive = true; // flag to include inactive records

//Get all active/inactive retro triggers within date range for an assignment
var list =
retroApi.getRetroTriggerEventsToBeProcessed(empMatchCondition,asgMatchCondition,startDate,endD
ate,includeInactive);

//activating first retro trigger in list.


retroApi.activateRetroTrigger(list[0]);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 390


WT&A API Specifications 18.3 Retro Trigger API

Example 3: Deactivate Retro Trigger Events


The following script example demonstrates how the Retro Trigger API can be used to deactivate existing,
unprocessed active retro trigger events for an assignment.

includeDistributedPolicy("RETRO_TRIGGER_API");

//setup parameters
var parms = {
enableDebugging: true,
description: “API created group”
};

// Initialize the API


var retroApi = new RetroTriggerAPI (parms);

//Define match condition for an employee. This match condition will match an employee with the
display ID of 1163297
var empMatchCondition = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",
MatchOperator.EQUALS, "1163297");

//Define match condition for an assignment. This match condition will match an assignment with
the computed match ID of 1163297202327-5301
var asgMatchCondition = new MatchCondition(MatchTable.ASGNMT, "COMPUTED_MATCH_ID",
MatchOperator.EQUALS, "1163297202327-5301");

var startDate = new WFSDate(2017,10,11); //start trigger date for date range
var endDate = new WFSDate(2017,12,31); //end trigger date for date range
var includeInactive = true; // flag to include inactive records

//Get all active/inactive retro triggers within date range for an assignment
var list =
retroApi.getRetroTriggerEventsToBeProcessed(empMatchCondition,asgMatchCondition,startDate,endD
ate,includeInactive);

//Deactivating first retro trigger in list


retroApi.deactivateRetroTrigger(list[0]);

Example 4: Delete Retro Trigger Events


The following script example demonstrates how the Retro Trigger API can be used to delete existing
unprocessed active/inactive retro trigger events for an assignment.

includeDistributedPolicy("RETRO_TRIGGER_API");

//setup parameters
var parms = {
enableDebugging: true,
description: “API created group”
};

// Initialize the API


var retroApi = new RetroTriggerAPI (parms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 391


WT&A API Specifications 18.3 Retro Trigger API

//Define match condition for an employee. This match condition will match an employee with the
display ID of 1163297
var empMatchCondition = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",
MatchOperator.EQUALS, "1163297");

//Define match condition for an assignment. This match condition will match an assignment with
the computed match ID of 1163297202327-5301
var asgMatchCondition = new MatchCondition(MatchTable.ASGNMT, "COMPUTED_MATCH_ID",
MatchOperator.EQUALS, "1163297202327-5301");

var startDate = new WFSDate(2017,10,11); //start trigger date for date range
var endDate = new WFSDate(2017,12,31); //end trigger date for date range
var includeInactive = true; // flag to include inactive records

//Get all active/inactive retro triggers within date range for an assignment
var list =
retroApi.getRetroTriggerEventsToBeProcessed(empMatchCondition,asgMatchCondition,startDate,endD
ate,includeInactive);

//Deleting first retro-trigger event in list


retroApi.deleteRetroTrigger(list[i]);

Example 5: Fetch Retro Trigger Events


The following script example demonstrates how the Retro Trigger API can be used to fetch existing active or
inactive retro trigger events for an assignment based on a provided employee and assignment match
condition within the given trigger date range. The returned list is Read-Only; therefore, records in the list
cannot be modified and will throw exception if an attempt is made to modify the records.

includeDistributedPolicy("RETRO_TRIGGER_API");

//setup parameters
var parms = {
enableDebugging: true,
description: “API created group”
};

// Initialize the API


var retroApi = new RetroTriggerAPI (parms);

//Define match condition for an employee. This match condition will match an employee with the
display ID of 1163297

var empMatchCondition = new MatchCondition(MatchTable.EMPLOYEE, "DISPLAY_EMPLOYEE",


MatchOperator.EQUALS, "1163297");

//Define match condition for an assignment. This match condition will match an assignment with
the computed match ID of 1163297202327-5301

var asgMatchCondition = new MatchCondition(MatchTable.ASGNMT, "COMPUTED_MATCH_ID",


MatchOperator.EQUALS, "1163297202327-5301");

var startEffDate = new WFSDate(2017,10,11); // can be null


var endEffDate = new WFSDate(2017,12,11); // can be null

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 392


WT&A API Specifications 18.3 Retro Trigger API

var includeInactive = true;

//Fetch active/inactive retro-trigger events with or without effective trigger date.


var list = retroApi.getRetroTriggerEventsToBeProcessed
(empMatchCondition,asgMatchCondition, startEffDate, endEffDate, includeInactive);

//OR Fetch only active retro-trigger events with or without effective trigger date.
var includeInactive = false;

var list = retroApi.getRetroTriggerEventsToBeProcessed


(empMatchCondition,asgMatchCondition, startEffDate, endEffDate, includeInactive);

Troubleshooting
The job log of the script using the Retro Trigger API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


Input parameter An API method was called without a Check that all calls to the API methods
PARAMETER DESCRIPTION is value being provided for a required are supplying values for all the
not provided argument. required arguments.

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Retro Trigger API consists of two components:
3. The MatchCondition, which defines a condition to select employee, assignment, or user records.
a. This MatchCondition makes use of a MatchOperator which defines a comparison operation
to use in a condition for matching a specified value against the employee/assignment/user
data.
4. The RetroTriggerAPI, which provides methods to create, update (activate/deactivate), and fetch
retro trigger events.
See the contents of the RETRO_TRIGGER_API policy in the Distributed JavaScript Library category of the
Policy Editor for full documentation on these methods. The following is a summary of the available methods
and common uses:

MatchOperator
EQUALS
Only data where the value in the specified field exactly matches the indicated value will be matched by the
condition.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 393


WT&A API Specifications 18.3 Retro Trigger API

NOT_EQUALS
Only data where the value in the specified field does not match the indicated value will be matched by the
condition.

GREATER_THAN
Only data where the value in the specified field is greater than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “3” is greater than “20”.

GREATER_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is greater than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “3” is greater than
“20”.

LESS_THAN
Only data where the value in the specified field is less than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “20” is less than “3”.

LESS_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is less than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “20” is less than
“3”.

IN
Only data where the value in the specified field exactly matches one of the values in the indicated array of
values will be matched by the condition.

NOT_IN
Only data where the value in the specified field does not match any of the values in the indicated array of
values will be matched by the condition.

LIKE
Only data where the value in the specified field matches the pattern defined by the indicated value will be
matched by the condition.

NOT_LIKE
Only data where the value in the specified field does not match the pattern defined by the indicated value
will be matched by the condition.

BETWEEN
Only data where the value in the specified falls between the two values defined by the indicated array of
values (inclusive of the two endpoints) will be matched by the condition. For string fields this is applied
lexicographically, meaning that “5” is between “37” and “62”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 394


WT&A API Specifications 18.3 Retro Trigger API

MatchCondition
MatchCondition(table, field, operator, values, isNotOperator)
Creates a new MatchCondition for the indicated table/field combination that matches against the specified
value(s) using the indicated MatchOperator.
If the MatchOperator specified is IN or NOT_IN, then values are expected to be an array of all the different
values to be evaluated by the “in” operation. If the MatchOperator specified is BETWEEN, then values are
expected to be an array containing two values: the starting point and ending point of the range to be
evaluated by the “between” operation. For all other MatchOperators, values are expected to be a single
value.
The isNotOperator controls whether the results of the MatchCondition should be negated. If this is set to
true, then a MatchCondition that normally evaluates to false will instead evaluate to true, and a
MatchCondition that normally evaluates to true will instead evaluate to false. This allows for conditions that
don’t have an explicit MatchOperator defined, such as “not between”, to be defined.

and(condition)
Modifies the MatchCondition to return only the intersection of its original condition and the specified
condition.

or(condition)
Modifies the MatchCondition to return the union of its original condition and the specified condition.

RetroTriggerAPI
RetroTriggerAPI(parms)
Create new instance of RetroTriggerAPI.

createRetroTrigger(employeeMatchCondition, asgnmtMatchCondition, retro_trigger_date,


comments)

Creates a new retro trigger event with a given trigger date for an assignment based on provided employee
and assignment match conditions.

commitRetroTriggers()

Commits all created retro trigger events into the retro_trigger_event table in the database.

activateRetroTrigger(retroTriggerEvent)

Activates the provided retro trigger event.

deactivateRetroTrigger(retroTriggerEvent)

Deactivates the provided retro trigger event.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 395


WT&A API Specifications 18.3 Retro Trigger API

deleteRetroTrigger(retroTriggerEvent)
Deletes the provided retro trigger event.

getRetroTriggerEventsToBeProcessed(employeeMatchCondition, asgnmtMatchCondition,
startDate, endDate, includeInactive)
Returns a Read-Only list of active/inactive unproccessed retro trigger events within a given trigger date
range for an assignment based on the provided match condition of employee and assignment.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 396


WT&A API Specifications 18.3 Schedule Detail Output API

Schedule Detail Output API


Overview and Capabilities
This API lets you retrieve schedule data from the WT&A database.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The SCHEDULE_DETAIL_API distributed JavaScript Library
• The ScheduleDetailAPI Java class
• The API_UTIL Distributed JavaScript Library

Setup
No setup is necessary for the Schedule Detail API. The distributed library is automatically available in
WorkForce Time and Attendance.

Use Cases
Getting SD data using Match Condition for assignment; Version: INITIAL
Schedule is not locked.
includeDistributedPolicy("SCHEDULE_DETAIL_API ");

var api = new ScheduleDetailAPI();

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
startDate: new WFSDate(2008, 04, 21),
endDate: new WFSDate(2008, 04, 25),
version:"INITIAL"
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Getting SD data using Match Condition for assignment; Version: OPEN


Schedule is not locked.
includeDistributedPolicy("SCHEDULE_DETAIL_API ");

var api = new ScheduleDetailAPI();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 397


WT&A API Specifications 18.3 Schedule Detail Output API

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:"OPEN"
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Getting SD data using Match Condition for assignment; Version: LATEST


Schedule is locked.
includeDistributedPolicy("SCHEDULE_DETAIL_API");

var api = new ScheduleDetailAPI();

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:"LATEST"
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Getting SD data using Match Condition for assignment; Version:


LATEST_CLOSED
Schedule is locked.
includeDistributedPolicy("SCHEDULE_DETAIL_API");

var api = new ScheduleDetailAPI();

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:" LATEST_CLOSED"
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Getting SD data for specific PayCodeSet


includeDistributedPolicy("SCHEDULE_DETAIL_API");

var api = new ScheduleDetailAPI();

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 398


WT&A API Specifications 18.3 Schedule Detail Output API

asgnmtEffDate: new WFSDate(2010, 05, 29),


asOfDate: new WFSDate(2008, 04, 26),
version: "LATEST_CLOSED",
payCodeSet: "INT_5184_TEST"
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Getting SD data with specific SD fields using TimesheetMatchCondition


Here’s how to filter SD records using TimesheetMatchCondition with specific SD fields.
includeDistributedPolicy("SCHEDULE_DETAIL_API");

var api = new ScheduleDetailAPI();

var matchConditionParam = {
table: TimesheetMatchTable.SCHEDULE_DETAIL,
field: "HOURS",
operator: MatchOperator.EQUALS,
values: ["3"]
};

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version: "LATEST_CLOSED",
payCodeSet: "INT_5184_TEST",
sdMatchCondition: new TimesheetMatchCondition(matchConditionParam)
};
var result = api.getScheduleDetailForPeriodAsOf(queryParms);

Troubleshooting
The job log of the script using the Schedule Detail API will include informational messages, and in the case of
problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
Invalid Pay Code Set provided The API will throw an error if the Pass a valid PayCodeSet
name of PayCodeSet is not valid
Version invalid The API will throw an error if the Pass a valid version from the
version is not valid. following: OPEN, LATEST,
LATEST_CLOSED, INITIAL

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 399


WT&A API Specifications 18.3 Schedule Detail Output API

getScheduleDetailForPeriodAsOf ()
Performs a lookup on SD table using provided match condition and returns matching rows as
ReadOnlyScriptables for the period the provided effective date is in. Takes an object as parameter, having the
following fields:
Parameter Description
matchCondition The condition to select the assignment. Condition can be from EMPLOYEE,
EMPLOYEE_MASTER, ASGNMT and/or ASGNMT_MASTER table
asgnmtEffDate The effective date to use for the retrieval of the assignment record
asOfDate The date to retrieve the period of schedule
The version of schedule for which to retrieve the SD records. The 4 versions
version
are INITIAL, LATEST, LATEST_CLOSED, OPEN
payCodeSet (optional) The pay codes for which to retrieve the SD records
sdMatchCondition (optional) The TimesheetMatchCondition for SD table to put additional filter criteria

getScheduleDetailBetweenWorkDates ()
Performs a lookup on SD table using provided match condition and returns matching rows as
ReadOnlyScriptables between the provided dates. Takes an object as parameter, having the following fields:
Parameter Description
matchCondition The condition to select the assignment. Condition can be from EMPLOYEE,
EMPLOYEE_MASTER, ASGNMT and/or ASGNMT_MASTER table
asgnmtEffDate The effective date to use for the retrieval of the assignment record
startDate The start date to use for calculation of schedule
endDate The end date to use for calculation of schedule
The version of schedule for which to retrieve the SD records. The 4 versions
version
are INITIAL, LATEST, LATEST_CLOSED, OPEN
payCodeSet (optional) The pay codes for which to retrieve the SD records
sdMatchCondition (optional) The TimesheetMatchCondition for SD table to put additional filter criteria

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 400


WT&A API Specifications 18.3 SSO API

SSO API
Definitions of Terms Used in This Section
SSO - Single sign-on (SSO) is a session/user authentication process that permits a user to enter one name and
password in order to access multiple applications.
SAML - Security Assertion Markup Language (SAML, pronounced sam-el) is an XML-based, open-standard
data format for exchanging authentication and authorization data between parties, in particular, between an
identity provider and a service provider.
SP - Service Provider – A website that hosts applications. In this case Workforce Software is acting as the
Service Provider.
IdP - Identity Provider – A trusted provider that enables using SSO to access other websites. In this case we
are relying on the customers using the product to act as the Identity Provider.

Overview and Capabilities


The SSO API provides support for SAML-based SSO into the WorkForce Time and Attendance application. The
SAML 2.0 standard protocol is supported, and can be used in either Service Provider initiated SSO, or Identity
Provider initiated SSO. The SSO API also provides utilities for troubleshooting and debugging purposes, to
assist with initial setup of an SSO solution.
The API provides standard behavior for authenticating users and redirecting users, but also provides options
to implement custom behavior for specific requirements.
The SSO API is used to configure SAML 2.0-based SSO into WorkForce Time and Attendance. This means that
users will authenticate against a system external to WorkForce Time and Attendance, in order to gain access
to the WorkForce Time and Attendance application. This requires that the external system can provide a
unique user identifier to WorkForce Time and Attendance. Usually, WorkForce Time and Attendance will
already have this unique identifier in order to identify the corresponding user. However, if necessary, the
SSO API provides the capability to process or transform the identifier provided by the external system in
order to match the corresponding unique identifier within WorkForce Time and Attendance. In a scenario
like this, coordination with the employee import logic may be necessary to identify or provide such a unique
identifier.
The SSO API can also control which WorkForce Time and Attendance page the user will be sent to upon
successful authentication. In the simplest case, all users are directed to the main page. More complex
scenarios can be created, where Mobile users are directed to WorkForce Mobile, and users who interact
primarily with the WorkForce WebClock are sent to that page.
The SSO API provides logging capabilities to assist with analysis, troubleshooting, and resolution of problems
setting up an SSO solution.
Lastly, the SSO API provides a public URL from which WorkForce Time and Attendance (as the SP) can expose
its metadata to be consumed by the Identity Provider.
Some limitations of the SSO API are:
• Does not support using WorkForce Time and Attendance as the Identity Provider for an SSO setup.
• Does not provide support for non-SAML based SSO, such as OpenID, OAuth, or other SSO solutions.
• Does not support the SuccessFactors integration.
• Does not support encryption of the SAML.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 401


WT&A API Specifications 18.3 SSO API

Prerequisites
To use this API, you should be familiar with the following functionality:
• How to create policies within the Policy Editor
• Basic SAML concepts, particularly those of metadata, Service Provider (SP), and Identity Provider (IdP)
• Basic JavaScript coding (for advanced SSO scenarios)
• Basic understanding of HTTP requests (for advanced SSO scenarios)

Components
This API consists of the following component(s):
• The SSO_API JavaScript library
• One or more SAML SSO Profile policies in Policy Editor
• One or more Authentication Mechanism Policy details (or 'bands')

Setup
Make sure the following requirements are met before using this API.

The SSO_API JavaScript Library


The SSO API library is distributed by WorkForce Software, so it should already be present in any EmpCenter
16.1 or later instance. No action needs to be taken for this component.

SAML SSO Profile Policy


Use of the SSO API requires one or more SAML SSO Profile policies, which are located and set up in Policy
Editor. You must create these policies manually. See the Policy Configuration Guide for full details on the
SAML SSO Profile policy; a short summary of the most important policy fields appears below.
Create the SAML SSO Profile policy or policies based on the SSO requirements. Typically, there will be one
SAML SSO Profile policy per Identity Provider.

Field Description
The IdP EntityID to Fill in the unique identifier (EntityID) of the Identity Provider.
expect
IdP Metadata WorkForce Time and Attendance can retrieve the Identity Provider's metadata
Location Type from either a file or a public URL. Specify which option will be used here.
IdP Metadata Specify the exact location of the Identity Provider's metadata. If 'File' was chosen,
Location fill in the file location. For 'URL', fill in the full URL
SP EntityID Choose a unique identifier for the WorkForce Time and Attendance instance.
Table 84: Fields in SAML SSO Profile policy.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 402


WT&A API Specifications 18.3 SSO API

Example SAML SSO Profile


Below is an example SAML SSO Profile policy named SAMPLE_PROFILE.

This guide will refer to this example in further sections.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 403


WT&A API Specifications 18.3 SSO API

Authentication Mechanism Policy Detail


Use of the SSO API requires one or more Authentication Mechanism policy details. These policy details will
need to be created manually. See the Policy Configuration Guide for full details on the Authentication
Mechanism policy and its details; a short summary of the fields relevant to the SSO API appears below.
In the Authentication Mechanism policy, add the necessary detail row or rows, based on the SSO
requirements. Typically, there will be one detail per Identity Provider.
Field Description
SSO Script JavaScript that controls the logic of the SSO process. This is the primary field
related to the SSO API. Its use will be covered extensively in this guide.
Custom SSO Log Off If enabled, this specifies the URL to which users will be redirected upon logging out
Redirect URL of WorkForce Time and Attendance.
Table 85: Fields in Authentication Mechanism Policy that are relevant to SSO API.

Use Cases
Accessing WorkForce Time and Attendance SP Metadata
Identity Providers (IdP) often require access to the Service Provider's (SP) metadata in order to enable SSO
between the systems. An WorkForce Time and Attendance instance's metadata can be accessed via an
instance URL.
First, set up a SAML SSO Profile policy as described above. Note the name of the policy.
The URL to access the metadata is in the form:
https://<instance base>/workforce/metadata/sp/<policy name>
So for the sample instance and SAML SS Profile in the example, the URL would be:
https://company.workforcehosting.com/workforce/metadata/sp/SAMPLE_PROFILE
WorkForce recommends the use of the URL-based metadata wherever possible. If the Identity Provider
requires a file, copy the contents of the XML on the page to a file.

Enabling SP-Initiated SSO with Default Options


The simplest use case of the SSO API is for SP-initiated SSO against a single IdP, without any customizations of
the behavior. In this case, these default behaviors will apply:
• RelayState will not be used
• No data will be persisted across the request/response cycle
• The SAML response will be expected to contain a single NameID element, with a unique identifier for the
user
• The unique identifier will be present within WorkForce Time and Attendance, on the table and field as
defined by the Authentication Mechanism policy, as an exact match
• All users will be sent to the application main page upon successful authentication

To set up SP-Initiated SSO:


First, set up a SAML SSO Profile policy as described above. This example will use the sample from above; see
Example SAML SSO Profile. _Example_SAML_SSO

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 404


WT&A API Specifications 18.3 SSO API

Next, create an Authentication Mechanism detail policy as described in Authentication Mechanism Policy
Detail. Here is a basic script that can be put into the SSO Script field to do the
SSO:_Authentication_Mechanism_Policy
Example: Basic SP-initiated SSO Script

includeDistributedPolicy("SSO_API");
SsoApi.doSpSaml("SAMPLE_PROFILE");

Specify the name of the SAML SSO Policy on the second line; in this example it is the sample policy named
SAMPLE_PROFILE.
Setup is now complete. To test the process, open a web browser and go to the SSO endpoint. For the
sample instance, this would be https://company.workforcehosting.com/workforce/SSO.do
The browser should be redirected to the Identity Provider, which should prompt for authentication if
necessary. Then, the browser should be redirected to the WorkForce Time and Attendance main page.

Enabling IdP-Initiated SSO with Default Options


IdP-Initiated SSO is set up in a very similar way to SP-Initiated SSO. The main difference is that going to the
SSO endpoint directly will not redirect the browser to the Identity Provider; SSO will instead fail. In this case,
the identify provider needs to be set up to send the user to WorkForce Time and Attendance with the
authentication information. The typical reason to choose this SSO setup is to ensure that all users go through
a single, central web page, such as a company portal or intranet page.
These default behaviors will apply to this use case:
• RelayState will not be used
• The SAML response will be expected to contain a single NameID element, with a unique identifier for the
user
• The unique identifier will be present within WorkForce Time and Attendance, on the table and field as
defined by the Authentication Mechanism policy, as an exact match
• All users will be sent to the application main page upon successful authentication

To set up IdP-Initiated SSO:


First, set up a SAML SSO Profile policy. This example will use the sample from above; see Example SAML SSO
Profile. _Example_SAML_SSO
Next, create an Authentication Mechanism detail policy as described in Authentication Mechanism Policy
Detail. Here is a basic script that can be put into the SSO Script field to do the
SSO:_Authentication_Mechanism_Policy
Example: Basic ldP-initiated SSO Script

includeDistributedPolicy("SSO_API");
SsoApi.doIdpSaml("SAMPLE_PROFILE");

Specify the name of the SAML SSO Policy on the second line; in this example it is the sample policy named
SAMPLE_PROFILE.
This script goes into the SSO Script field of the Authentication Mechanism being used.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 405


WT&A API Specifications 18.3 SSO API

Setup is now complete. To test the process, the IdP should be set up to authenticate a user and send the
SAML to the SSO endpoint; this may require additional configuration of the IdP.
For the sample instance, the WorkForce Time and Attendance SSO endpoint would be
https://company.workforcehosting.com/workforce/SSO.do
Once the IdP is configured, users sent to WorkForce Time and Attendance should be directed to the
application main page.

Processing the IdP's Unique Identifier


In order to identify the user that should be authenticated in WorkForce Time and Attendance, the Identity
Provider must transmit a unique identifier in the SAML. In the optimal case, the value from the Identity
Provider will be transmitted in a NameID element, and already be stored in WorkForce Time and Attendance
as an exact match. However, it may be the case that the identifier needs to be processed or transformed in
order to exactly match the corresponding value in WorkForce Time and Attendance. For instance:
• The NameID may need to be converted to uppercase to match the WorkForce Time and Attendance
value
• The NameID may have a prefix that is not present on the WorkForce Time and Attendance value
• Multiple NameID elements may be present
• The identifier may be in an Attribute element instead of a NameID element
The SSO API provides a way to manipulate the value from the SAML before attempting to match it to an
WorkForce Time and Attendance user. A custom JavaScript function can be included in the SSO Script to
implement the necessary transformation logic.

Example 1: A script that converts the provided NameID identifier into upper case
includeDistributedPolicy("SSO_API");

function customUserHook(samlResponse, nameIds) {


// For this example, we assume there will be exactly one NameID
return nameIds[0].toUpperCase();
}

SsoApi.doSpSaml("SAMPLE_PROFILE");

Example 2: A script that strips the prefix 'WORKFORCE\' off the provided NameID
identifier
includeDistributedPolicy("SSO_API");

function customUserHook(samlResponse, nameIds) {


// For this example, we assume there will be exactly one NameID
return nameIds[0].replace('WORKFORCE\', '');
}

SsoApi.doSpSaml("SAMPLE_PROFILE");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 406


WT&A API Specifications 18.3 SSO API

Example 3: A script that extracts the value of the "EmailAddress" attribute as the
identifier
includeDistributedPolicy("SSO_API");
function customUserHook(samlResponse, nameIds) {
var attributes = samlResponse.getAttributes();
var emailAttributes = attributes['EmailAddress'];
// This is actually a list, though it likely has exactly one member, so extract the first
item
var emailAttribute = emailAttributes.get(0);
// This is actually an XML element, to get a string representation, call getValue()
return emailAttribute.getValue();
}
SsoApi.doSpSaml("SAMPLE_PROFILE");

Customizing Redirection
The default behavior of the SSO API is to direct users to the main page of the application upon successful
authentication. The SSO API provides a way to specify alternate redirect pages based on custom logic.
Convenient methods have been provided for the most common redirects (the main page, Mobile,
Accessibility, and WebClock), as well as a method for sending the user to any page within WorkForce Time
and Attendance.

Example 1: Conditionally redirecting to various pages


includeDistributedPolicy("SSO_API");

function customRedirectHook(samlResponse, userId) {


var isWebclockUser = true; // Specific logic to detect a webclock user would go here
var isAccessibilityUser = true; // Specific logic to detect an Accessibility user would go
here

if (isWebclockUser) {
SsoApi.redirectToWebclock();
} else if (isAccessibilityUser) {
SsoApi.redirectToAccessibility();
} else {
SsoApi.redirectToMain();
}
}

SsoApi.doSpSaml("SAMPLE_PROFILE");

Example 2: Redirecting to the End of Period Processing screen


includeDistributedPolicy("SSO_API");

function customRedirectHook(samlResponse, userId) {


SsoApi.redirectTo("EndOfPeriodProcessing.do");
}

SsoApi.doSpSaml("SAMPLE_PROFILE");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 407


WT&A API Specifications 18.3 SSO API

Handling Mobile SSO


The most common use of redirection is to send users on Mobile devices to the WorkForce Mobile application.
The SSO API provides a built-in way to allow WorkForce Time and Attendance to attempt auto-detection of
mobile browsers to automatically handle redirection. There are two alternate ways to handle Mobile
redirects, if the auto-detection is not sufficient, or if other redirect logic needs to be considered as well.

Example 1: Enabling auto-detection of mobile devices


Auto-detection of mobile devices is enabled via the Global Security Options tab of the System Setup policy in
the Policy Editor. Enable the 'Redirect to Desktop/Mobile Logon' option as shown below:

In this case, no scripting customizations are necessary. The SSO API will attempt to automatically detect
mobile browsers and direct the user to Mobile or the main page appropriately. Note that this approach is
not compatible with any custom redirection logic; if the customRedirectHook is used, the auto-detection will
not be used.

Example 2: Customizing the mobile detection logic


includeDistributedPolicy("SSO_API");

function customRedirectHook(samlResponse, userId) {


var isMobile = isMobileUser(); // Write a custom function to detect mobile users

if (isMobile == "true") {
SsoApi.redirectToMobile();
} else {
SsoApi.redirectToMain();
}
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 408


WT&A API Specifications 18.3 SSO API

SsoApi.doIdpSaml("SAMPLE_PROFILE");

Example 3: Providing additional information in the HTTP request


includeDistributedPolicy("SSO_API");

function customRedirectHook(samlResponse, userId) {


var mobileParam = SsoApi.getRequestParameter("mobile");

if (mobileParam == "true") {
SsoApi.redirectToMobile();
} else {
SsoApi.redirectToMain();
}
}

SsoApi.doIdpSaml("SAMPLE_PROFILE");

Persisting Data
In order to implement custom behavior, it may be necessary to retain information across an SP-initiated SSO
request/response cycle. The most common reason for this is when HTTP parameters are used to specify
information. Normally, this information would be lost during the SAML request and response.
For example, the user might include an HTTP Parameter named 'accessibility', which will have a 'true' value if
the user should be directed to the Accessibility page upon login.

Example: Storing an HTTP parameter, later using it to control redirection


includeDistributedPolicy("SSO_API");

function preRequestHook(samlRequest) {
// Retrieve the parameter value
var accessibilityParameter = SsoApi.getRequestParameter('accessibility');

// Persist it
samlRequest.persistProperty('accessibility', accessibilityParameter);
}

function customRedirectHook(samlResponse, userId) {


// Retrieve the persisted value
var persistedParameter = samlResponse.getPersistedProperties()['accessibility'];

if (persistedParameter == "true") {
SsoApi.redirectToAccessibility();
} else
SsoApi.redirectToMain();
}
}

SsoApi.doSpSaml("SAMPLE_PROFILE");

Using the Logging and Debugging Capabilities


Especially during initial setup and testing of an SSO implementation, it can be useful to have additional
information to determine the cause of any problems or errors that are occurring. The SSO API provides some
logging and debugging capabilities, such as:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 409


WT&A API Specifications 18.3 SSO API

• Logging additional information about the validation of the SAML


• Outputting the SAML XML directly to a log, for inspection
• Enabling user-defined logging statements in the SSO Script

Example: API debugging statements


includeDistributedPolicy("SSO_API");

SsoApi.debugHttpRequest(); // Will print information about the actual request to sso_log.txt


SsoApi.printSamlResponse(); // Will print the SAML XML to sso_log.txt
SsoApi.debug("This is a debug message"); // Will print the specified message to sso_log.txt

SsoApi.doSpSaml("SAMPLE_PROFILE");

Logging in as a Proxy User


As of EmpCenter v16.3, superusers have the ability to login as a proxy user via SSO. The user to be
authenticated by SSO must have the "SUPERUSER" system feature. The WorkForce Time and Attendance user
to use as the proxy must be included in the SAML response from the Idp. The SAML response must include an
attribute statement with the name "proxyId" and the attribute value of the proxy user ID. The ID included in
the SAML response will be used to look up the proxy user based on the Authentication Mechanism's match
field.
It is possible that no changes to the SSO script would be required to enable SSO proxy login. If the Idp
provides the proxyId and the proxyId will match an WorkForce Time and Attendance app user based on the
Authentication Mechanism's match field, the system will attempt an SSO proxy login. No changes to the SSO
script would be required. However, if custom processing of the Idp-provided proxyIds is required, a custom
hook is available.

Example 1: The Idp sends a single proxyId which does not require custom processing
This is the case where no changes to the SSO script would be required. The script could look as simple as the
basic Idp-initiated script.
includeDistributedPolicy("SSO_API");
SsoApi.doIdpSaml("SAMPLE_PROFILE");

Example 2: Strip 'WORKFORCE\' off the provided Name ID and Proxy ID if provided. If no
Proxy ID provided, proceed as a normal SSO login
includeDistributedPolicy("SSO_API");

function customUserHook(samlResponse, nameIds) {


// For this example, we assume there will be exactly one NameID
return nameIds[0].replace('WORKFORCE\', '');
}

function customProxyUserHook(samlResponse, proxyIds) {


// For this example, we assume there will be either zero or exactly one ProxyID
if(proxyIds.length == 0) {
return null;
return proxyIds[0].replace('WORKFORCE\', '');
}

SsoApi.doIspSaml("SAMPLE_PROFILE");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 410


WT&A API Specifications 18.3 SSO API

Troubleshooting
There are two sources of information for problems encountered with getting SAML SSO working:
• The WorkForce Time and Attendance server_log.txt file
• The WorkForce Time and Attendance sso_log.txt file
Usually, messages about an error or problem can be found in one or both of these logs, depending on the
nature of the error and where in the process it occurred.
The sso_log.txt file will contain the output of the debugHttpRequest, printSamlResponse, and debug
methods of the SSO API. It will also contain the logging generated by use of the "Enable Debug Logging"
option of the SAML SSO Profile policy.
The server_log.txt file will contain all other messages, such as those about errors processing the metadata
file or URL, errors in the script itself, or errors finding a user.
Error Message Problem Solution
Non-ok status code 404 WorkForce Time and Attendance Make sure the URL entered in the
returned from remote cannot retrieve the IdP metadata SAML SSO Profile Policy is correct and
metadata source via URL because the URL is not publicly accessible
http://example.com found
Error retrieving metadata WorkForce Time and Attendance Add the SSL certificate of the
from https://example.com cannot retrieve the IdP metadata metadata's URL to WorkForce Time
No trusted certificate via URL because the SSL connection and Attendance via the Certificate
found cannot be made Administration page. Note that this
needs to be done on each instance in
a load-balanced situation, and that it
also needs to be redone on every
upgrade.
Expected metadata file not WorkForce Time and Attendance Ensure the file is in the correct place
found at idp_metadata.xml cannot read the IdP metadata from and accessible to WorkForce Time and
a file Attendance
Signature validation failed The metadata has expired Check the expiration date of the
metadata and its certificate

Signature validation failed The signature on the SAML does not Make sure the correct metadata is
match the metadata being used
No valid nameIds were WorkForce Time and Attendance Inspect the SAML to ensure the IdP is
found in the SAML cannot find a user identifier in the sending an identifier in the expected
Response - a custom user SAML element – most often, a NameID
hook is required unless you have implemented custom
user logic
Employee not found for WorkForce Time and Attendance Check that the match table and match
EXTERNAL_ID = cannot find a user to authenticate field on the Authentication Mechanism
'SAMPLE_USER' policy hold the identifier from the IdP

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 411


WT&A API Specifications 18.3 SSO API

Error validating SAML info: Clock drift between the SP and IdP Use the "Assertion time window" field
Current time Time X is not means the SAML is invalid on the SAML SSO Policy to allow for
between Time A and Time drift
B
Table 86: SSO API common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The SSO API consists of the following component(s):
1. The SsoApi namespace, which provides convenience methods for common SSO operations
a. This namespace uses a SamlRequest, which represents a SAML request sent to the IdP.
b. This namespace uses a SamlResponse, which represents a SAML response received from the
IdP.
2. One or more SAML SSO Profile policies. There is typically one per Identity Provider.
3. One or more Authentication Mechanism Policy. There is typically one per Identity Provider and these
will generally contain the SSO Scripts with the logic of the SSO Process.
Note that in almost all cases, direct creation of the SamlRequest or SamlResponse will not be necessary; the
API will create them, and their behavior can be customized through optional functions that you can write.
The following is a summary of the available methods and common uses.

SsoApi Namespace provides the following methods:


SsoApi.debugHttpRequest()
Output information about the HTTP request to the sso_log.txt file. May be useful for debugging.

SsoApi.debug(message)
Output the provided string message to the sso_log.txt file. May be useful for debugging.

SsoApi.printSamlResponse()
Output the raw XML of the SAML received by the script. If no SAML response was received, that will be
indicated instead. May be useful for debugging.

SsoApi.isSsoRequest()
Returns true if the HTTP request was sent to the WorkForce Time and Attendance SSO endpoint. Usually
used to control whether the script should run.

SsoApi.isMobileAgent()
Returns true if WorkForce Time and Attendance could detect the user is signing in on a mobile device. Often
used to redirect the user to the Mobile page. Note that WorkForce Time and Attendance will by default
attempt to automatically redirect mobile users based on this unless a custom redirection method is
implemented.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 412


WT&A API Specifications 18.3 SSO API

SsoApi.isSamlResponseAvailable()
Returns true if a SAMLResponse was available in the request. May be useful for debugging.

SsoApi.getRequestParameter(parameterName)
Extract an HTTP parameter from the HTTP request. Often used to allow the IdP to send additional
information that can affect the behavior of the SSO script

SsoApi.redirectToMobile()
Instruct the SSO script to direct the user to Mobile. Often used if customizing the redirect logic in the script.

SsoApi.redirectToAccessibility()
Instruct the SSO script to direct the user to Accessibility. Often used if customizing the redirect logic in the
script.

SsoApi.redirectToWebclock()
Instruct the SSO script to direct the user to WebClock. Often used if customizing the redirect logic in the
script.

SsoApi.redirectToMain()
Instruct the SSO script to direct the user to the application's main page. Often used if customizing the
redirect logic in the script.

SsoApi.redirectTo(target)
Instruct the SSO script to direct the user to the indicated target. Often used if customizing the redirect logic
in the script.

SsoApi.fail(message)
Instruct the SSO script to fail authentication and display the provided message. Rarely used.

SsoApi.doSpSaml(ssoPolicy)
Instruct the SSO script to run SP-initiated SAML, using the settings in the specified SAML SSO Policy

SsoApi.doIdpSaml(ssoPolicy)
Instruct the SSO script to run IdP-initiated SAML, using the settings in the specified SAML SSO Policy
The SamlRequest class provides the following methods:

SamlRequest(ssoPolicy)
Create a SAML Authentication Request suitable for sending to the IdP, using the settings in the specified
SAML SSO policy

setRelayState(relayState)
Set the SAML RelayState.The IdP will retransmit this value back. Could be used to retain information from
the request to make it available when the response is received.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 413


WT&A API Specifications 18.3 SSO API

persistProperty(propertyName, propertyValue)
Store a name/value pair in the request, which will be available when processing the response. Preferred to
relay state for retaining information during the request to make it available when the response is received.

dispatchRedirect()
Instruct the SSO Script to dispatch the Authentication response via HTTP Redirect.

dispatchPost()
Instruct the SSO Script to dispatch the Authentication request via HTTP POST. Automatically done if
SsoApi.doSpSaml() is used.

The SamlResponse class provides the following methods:


SamlResponse(ssoPolicy)
Create a SamlResponse that simplifies access to the information received from the IdP

getRelayState()
Get the relay state that arrived with the response

getNameIds()
Get the NameIds that the IdP sent in the response. Usually there will only be one.

getPersistedProperties()
Retrieve any properties that were persisted using the persistProperty() method on SamlRequest, when
processing the response to that request. In IdP-initiated SAML, this will be an empty object.

getAssertions()
ADVANCED USE ONLY - provides direct access to the SAML Assertions in the Response. Should only be used
in very complex SSO script scenarios

getAttributes()
ADVANCED USE ONLY - provides direct access to the SAML Attributes in the Response. Should only be used
in very complex SSO script scenarios.

Custom Hook Functions


In addition to the API methods, the API supports the use of custom 'hook' functions to modify or extend the
behavior of the API. Some of these hooks were demonstrated in the code examples, but a full listing can be
found below

preRequestHook(samlRequest)
Called before the SAML request is dispatched. This is the place where the SamlRequest methods
setRelayState() and persistProperty() would be called. No return value.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 414


WT&A API Specifications 18.3 SSO API

postRequestHook()
Called after the SAML request has been dispatched but before the script completes. Very rarely used. No
return value.

preResponseHook()
Called before the Saml Response is processed. Most common use would be for logging debugging
information about the http request or saml response, using SsoApi.debugHttpRequest(),
SsoApi.debug(message), or SsoApi.printSamlResponse(). No return value.

responseHook(samlResponse)
Called after the Saml Response has been processed and validated, but before any values are extracted. Very
rarely used. No return value.

customUserHook(samlResponse, nameIds)
Called instead of the default user determination logic. The SamlResponse and the nameIds present in the
SAML are provided. Must return a string which will be used to look up the user based on the Authentication
Mechanism's match field. Must be implemented if zero or more than one NameId is provided by the IdP;
optional otherwise.

customProxyUserHook(samlResponse, proxyIds)
Called instead of the default proxy user determination logic. The SamlResponse and the proxyIds present in
the SAML are provided. Must return either null or a string which will be used to look up the proxy user based
on the Authentication Mechanism's match field. If the function returns null, the system will attempt a normal
SSO login, not an SSO proxy login.

customRedirectHook(samlResponse, userId)
Called instead of the default redirect logic - the default logic is to try to determine mobile users based on the
User-Agent header, and send mobile users to Mobile, all other users to Desktop. If customUserHook is
implemented, userId will be the value returned by that function. Otherwise it will be the NameId provided by
the IdP. Usually calls the SsoApi.redirectToMain(), SsoApi.redirectToMobile(),
SsoApi.redirectToAccessibility(), SsoApi.redirectToWebclock(), or SsoApi.redirect(target) methods in
conditional logic. Will often use the relay state (samlResponse.getRelayState()) or http parameters
(SsoApi.getRequestParameter(paramName)) to drive the conditional logic. Less commonly, may use the
SsoApi.fail(message) method to fail authentication. No return value.

postResponseHook(samlResponse, userId)
Called just before the script completes. Very rarely used. No return value.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 415


WT&A API Specifications 18.3 Swipe Import API

Swipe Import API


Overview and Capabilities
The Swipe Import API provides scripts running in WorkForce Time and Attendance the ability to import swipe
data onto employees’ timesheets. Typically, this swipe data would originate in some other system that the
customer is using, such as their own form of time clocks. This allows WorkForce Time and Attendance to
remain in sync with these external devices. The functionality provided by this API can either be used within a
script solely dedicated to that purpose, such as a script to import new time off requests, or it can be used as
part of a larger process to accomplish just a portion of the desired task.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The Distributed JavaScript Library SWIPE_IMPORT_API

Setup
No setup is necessary for the Swipe Import API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Importing Swipes
The Swipe Import API allows for swipes to be imported from any data source into timesheets. It is the calling
script’s responsibility to handle reading the data from the data source and formatting it into JS objects that
match the structure of the SWIPE_IMPORT_STAGING_TABLE table. The Swipe Import API can then take that
formatted data and post it to timesheets.

Example: Importing swipes


includeDistributedPolicy("SWIPE_IMPORT_API");

// Create an instance of the API


var api = new SwipeImportAPI();

// Get the data from the data source


var dataSource = getDataToBeImported();

// Iterate over the source data, creating new swipe records and adding them to the API
while (dataSource.next()) {
var swipe = {
id_type1: "DISPLAY_EMPLOYEE",
id_data: dataSource.employeeId,
transaction_dttm: dataSource.timeOfSwipeEvent,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 416


WT&A API Specifications 18.3 Swipe Import API

pay_code: dataSource.pay_code,
event_type: dataSource.swipeType
};
api.addSwipe(swipe);
}

// Once all of the swipes have been added, process them to the timesheets
api.processSwipes();

Note: A record will be created in the SWIPE_IMPORT_STAGING_TABLE table for all swipes processed by
addSwipe(). This allows for auditing of what swipes have been processed by the API

Reprocessing Swipes from the Staging Table


If there are already swipes in the SWIPE_IMPORT_STAGING_TABLE (e.g. from a previous job that had not
called processSwipes), the Swipe Import API has support for processing those swipes directly without
needing to query them and re-add them to the API using addSwipe again. This allows for a multi-part job,
with one job creating the staging records and another doing the final processing. It also allows for recovery
from certain error conditions if the data was written to the SWIPE_IMPORT_STAGING_TABLE but had not
been able to be processed successfully.

Example: Reprocessing swipes from the staging table


includeDistributedPolicy("SWIPE_IMPORT_API");

// Create an instance of the API


var api = new SwipeImportAPI();

// Process all of the swipes from the staging table that have not yet been processed
api.processSwipesFromStagingTable();

Fetching all the Unprocessed Swipes from the Staging Table


Gets all the unprocessed swipes present in the SWIPE_IMPORT_STAGING_TABLE. These swipes will be
marked as processed after being evaluated by the API, so that they won’t be picked up again by the next run
of the import. Swipes processed through this method will also be marked as “claimed” by the currently-
running job, so that other swipe import jobs running simultaneously will not try to process those same swipes
at the same time.

Example: Reprocessing swipes from the staging table


includeDistributedPolicy("SWIPE_IMPORT_API");

// Create an instance of the API


var api = new SwipeImportAPI();

// gets All the unprocessed records present in the SWIPE_IMPORT_S


var stagingRecords = api.getAllUnprocessedSwipeStagingRecords();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 417


WT&A API Specifications 18.3 Swipe Import API

Troubleshooting
The job log of the script using the Swipe Import API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No swipes to process A call was made to processSwipes() Ensure that records exist in a state to
when no data had been loaded be processed before attempting to
using addSwipe(), or a call was process swipes.
made to
processSwipesFromStagingTable()
when no records exist in the staging
table that are not processed.
None of the swipes All of the swipes added using Ensure that at least one swipe contains
contained valid data; addSwipe() contained an error, valid data to be posted to a timesheet
skipping processing job resulting in no data to process before attempting to process swipes.
through to timesheets.
No ID_TYPE1 value specified Swipe data was specified in Ensure that all swipe data specifies a
addSwipe that did not include a value for the ID_TYPE1 attribute.
value for the ID_TYPE1 attribute.
This attribute is necessary to
identify which method of matching
should be used for linking the swipe
to a timesheet.
No ID_DATA value specified Swipe data was specified in Ensure that all swipe data specifies a
addSwipe that did not include a value for the ID_DATA attribute.
value for the ID_DATA attribute.
This attribute is necessary to
identify the ID to be matched on for
linking the swipe to a timesheet.
No PAY_CODE value Swipe data was specified in Ensure that all swipe data specifies a
specified addSwipe that did not include a value for the PAY_CODE attribute.
value for the PAY_CODE attribute.
No TRANSACTION_DTTM Swipe data was specified in Ensure that all swipe data specifies a
value specified addSwipe that did not include a value for the TRANSACTION_DTTM
value for the TRANSACTION_DTTM attribute.
attribute.
No EVENT_TYPE value Swipe data was specified in Ensure that all swipe data specifies a
specified addSwipe that did not include a value for the EVENT_TYPE attribute.
value for the EVENT_TYPE attribute.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 418


WT&A API Specifications 18.3 Swipe Import API

No badge group policy exists The badge group being used to Ensure that all swipes that specify
with ID BADGE_GROUP_ID evaluate the match ID for the swipe badge groups, as well as the default
does not correspond to a Badge badge group called out when
Group policy defined in the initializing the API, specify values that
configuration. match the name of a Badge Group
policy in the configuration
Unable to determine badge A swipe using badge-based Ensure that a badge record matches
group for swipe with badge matching was unable to determine the ID specified on all swipes being
ID BADGE_ID which badge group the swipe processed using badge-based mapping
belonged to.
Invalid value VALUE Swipe data was specified in Ensure that the values entered on all
specified for field FIELD. addSwipe that included an invalid swipes for the specified field are one of
Valid options are OPTIONS value for the indicated field. the options listed in the error message.
Table 87: Swipe Import API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

SwipeImportAPI
Creates a new instance of the Swipe Import API

addSwipe(swipe)
Adds the specified swipe data to the set of swipes to be processed by this object. Also creates a record in
SWIPE_IMPORT_STAGING_TABLE for the swipe data.

processSwipes()
Sorts the swipe data by employee and transaction time (from earliest to latest), and processes each of the
swipes to import the data onto the employees’ timesheets.

processSwipesFromStagingTable()
Loads all of the records in SWIPE_IMPORT_STAGING_TABLE where PROCESSED is false and
IMPORT_JOB_NAME is not set into memory, as though they had been added by calls to addSwipe(), and then
performs the same actions as processSwipes().

getAllUnprocessedSwipeStagingRecords()
Fetches all the unprocessed swipes present in the SWIPE_IMPORT_STAGING_TABLE. The criteria to fetch the
unprocessed swipe is that the PROCESSED field should be false which states that the swipe is in unprocessed
state.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 419


WT&A API Specifications 18.3 Time Entry Import API

Time Entry Import API


Overview and Capabilities
The Time Entry Import API lets you import time records into the system. It is used within the Time Entry
Import policy. This API provides functionality to import time entries into the staging table in the first phase,
then commits those time entries into the actual table in the second phase, and then in the third cleanup
phase, this API allows for any amended timesheets that were created during the import to be automatically
approved.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding
• WorkForce Time and Attendance Time Entry and Schedule

Components
This API consists of the following component(s):
• The TIME_ENTRY_IMPORT_API distributed JavaScript Library
• The API_UTIL distributed JavaScript Library

Setup
No setup is necessary for the Time Entry Import API. The distributed library is automatically available in
WT&A.

Use Cases
Printing Available Parameters for API Configuration
This script excerpt demonstrates how to print available configuration parameters of the API to use them
correctly.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

//print available parameters for TimeEntryImportAPI


var teiAPI = new TimeEntryImportAPI(parms);
teiAPI.printAvailableAPIParms();

//print available parameters for TimeEntryImportAPI


var teicAPI = new TimeEntryImportCommitAPI (parms);
teicAPI.printAvailableAPIParms();

//print available parameters for TimeEntryImportAPI


var ticAPI = new TimeImportControllerAPI (parms);
ticAPI.printAvailableAPIParms();

Time Entry Import


This use case defines the behavior of time entry import using diverse types of data source.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 420


WT&A API Specifications 18.3 Time Entry Import API

Example 1: Import single time record using mapping function


Imports a single time record from a single source data record to the TIME_ENTRY_DETAIL_IMPORT (TEDI)
staging table.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies how the data should be mapped from the source result set to the
//TIME_ENTRY_DETAIL_IMPORT records being imported.
// Valid options are DECODER or FUNCTION. (Values are not case sensitive.)
mappingType: "FUNCTION",

// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
//which assignment to import the time record to.
matchField: "computed_match_id",

// Specifies an array of field names that are expected to be included in the source result set
//data. If all of the listed fields are not found, no data will be imported. Additional
//fields not specified in the array are allowed to be included.
fieldNames:
"EMPLOYEE_ID,DATE,START_TIME,END_TIME,DURATION,PAY_CODE,HOME_DEPT,JOB_CODE,COST_CENTER,CLIE_WO
RK,CLIE_CONV,CLIE_POSTN,AH_DEPTID,AH_JOBCODE,DEPTID2,JOBCODE2,AH_EMP_SLOT,AH_LOCATION,AH_RPT_S
LOT,AH_RPT_LOCATION".split(","),

// Specifies the date format that all date strings are expected to be provided in
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in
dateTimeFormat: "MM/dd/yyyy HH:mm",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
//If a pay code set is defined, only pay codes in that set can be imported. If set to null or
//an empty string, all pay codes will be allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
//work date that falls in a closed period is imported. If set to false, records with work
//dates in a closed period will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
//automatically unapproved when a time record with a work date that falls in that period is
//imported.If amendTimeSheetsIfNecessary is set to false, then this option will have no
//effect.
unapproveAmendedPeriods: false,

// Specifies the login_id of the user to use for generating unapprovals when
//unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

function mappingFunction(record) {

return {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 421


WT&A API Specifications 18.3 Time Entry Import API

"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": record.work_dt,
"start_dttm": record.work_dt + " 09:00:00",
"end_dttm": record.work_dt + " 17:00:00",
"pay_code": "REG",
"hours": "8",
"OTHER_TEXT10": "TT28437_2",
"comments": "TT28437_2"
};
}

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
var errors = [];

record.hours = parseFloat(record.hours) + 0.5; //Data can be modified in this function.

if (isBlank(record.EMPLOYEE_LOOKUP_ID)) {
errors.push("EMPID is required");
}
return errors;
}

var teiAPI = new TimeEntryImportAPI(parms);

teiAPI.importSingleTimeRecord(mappingFunction, validationFunction);// with validation function


//OR
teiAPI.importSingleTimeRecord(mappingFunction);// without validation function

Example 2: Import single time record using decoder


Imports a single time record from a single source data record to the TIME_ENTRY_DETAIL_IMPORT staging
table.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies how the data should be mapped from the source result set to the
//TIME_ENTRY_DETAIL_IMPORT records being imported.
// Valid options are DECODER or FUNCTION. (Values are not case sensitive.)
mappingType: "DECODER",

// Specifies the field on the ASGNMT record that the value being mapped to

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 422


WT&A API Specifications 18.3 Time Entry Import API

// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine


//which assignment to import the time record to.
matchField: "computed_match_id",

// Specifies the field in the decoder that identifies the source fields in the result set.
decoderSourceCol: "SOURCE",

// Specifies the field in the decoder that identifies the target fields to write the data to
on the.
decoderDestCol: "TIME_ENTRY_DETAIL_IMPORT",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
//If a pay code set is defined, only pay codes in that set can be imported. If set to null or
//an empty string, all pay codes will be allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
//work date that falls in a closed period is imported. If set to false, records with work
//dates in a closed period will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
//automatically unapproved when a time record with a work date that falls in that period is
//imported.If amendTimeSheetsIfNecessary is set to false, then this option will have no
//effect.
unapproveAmendedPeriods: false,

// Specifies the login_id of the user to use for generating unapprovals when
//unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportAPI(parms);


teiAPI.importSingleTimeRecord(DECODER_POLICY, validationFunction);

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
var errors = [];

if (isBlank(record.EMPLOYEE_LOOKUP_ID)) {
errors.push("EMPID is required");
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 423


WT&A API Specifications 18.3 Time Entry Import API

return errors;
}

Example 3: Import multiple time record with an array of records


Imports an array of time records from a single source data record to the TIME_ENTRY_DETAIL_IMPORT
staging table.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies how the data should be mapped from the source result set to the
//TIME_ENTRY_DETAIL_IMPORT records being imported.
// Valid options are DECODER or FUNCTION. (Values are not case sensitive.)
mappingType: "FUNCTION",

// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
//which assignment to import the time record to.
matchField: "computed_match_id",

// Specifies an array of field names that are expected to be included in the source result set
//data. If all of the listed fields are not found, no data will be imported. Additional
//fields not specified in the array are allowed to be included.
fieldNames:
"EMPLOYEE_ID,DATE,START_TIME,END_TIME,DURATION,PAY_CODE,HOME_DEPT,JOB_CODE,COST_CENTER,CLIE_WO
RK,CLIE_CONV,CLIE_POSTN,AH_DEPTID,AH_JOBCODE,DEPTID2,JOBCODE2,AH_EMP_SLOT,AH_LOCATION,AH_RPT_S
LOT,AH_RPT_LOCATION".split(","),

// Specifies the date format that all date strings are expected to be provided in
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in
dateTimeFormat: "MM/dd/yyyy HH:mm",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
//If a pay code set is defined, only pay codes in that set can be imported. If set to null or
//an empty string, all pay codes will be allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
//work date that falls in a closed period is imported. If set to false, records with work
//dates in a closed period will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
//automatically unapproved when a time record with a work date that falls in that period is
//imported.If amendTimeSheetsIfNecessary is set to false, then this option will have no
//effect.
unapproveAmendedPeriods: false,

// Specifies the login_id of the user to use for generating unapprovals when
//unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 424


WT&A API Specifications 18.3 Time Entry Import API

function mappingFunction(record) {
var results = [];
var workDt = new WFSDate.today();
results.push({
"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": workDt,
"pay_code": "REG",
"hours": "8",
"OTHER_TEXT10": "TT28437_3",
"comments": "TT28437_3",
"Extra_field":"extra_value"
});

results.push({
"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": workDt.addDays(1),
"pay_code": "REG",
"hours": "10",
"OTHER_TEXT10": "TT28437_3",
"comments": "TT28437_3",
"Nonexistent_field1": "valueA",
"Nonexistent_field2": "valueB"
});

return results;
}

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
var errors = [];

if (isBlank(record.EMPLOYEE_LOOKUP_ID)) {
errors.push("EMPID is required");
}
return errors;
}

var teiAPI = new TimeEntryImportAPI(parms);


teiAPI.importSingleTimeRecord(mappingFunction, validationFunction);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 425


WT&A API Specifications 18.3 Time Entry Import API

Example 4: Import multiple time record using multiple calls to the single record creation
function
Imports an array of time records from a single source data record to the TIME_ENTRY_DETAIL_IMPORT
staging table.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies how the data should be mapped from the source result set to the
//TIME_ENTRY_DETAIL_IMPORT records being imported.
// Valid options are DECODER or FUNCTION. (Values are not case sensitive.)
mappingType: "FUNCTION",

// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
//which assignment to import the time record to.
matchField: "computed_match_id",

// Specifies an array of field names that are expected to be included in the source result set
//data. If all of the listed fields are not found, no data will be imported. Additional
//fields not specified in the array are allowed to be included.
fieldNames:
"EMPLOYEE_ID,DATE,START_TIME,END_TIME,DURATION,PAY_CODE,HOME_DEPT,JOB_CODE,COST_CENTER,CLIE_WO
RK,CLIE_CONV,CLIE_POSTN,AH_DEPTID,AH_JOBCODE,DEPTID2,JOBCODE2,AH_EMP_SLOT,AH_LOCATION,AH_RPT_S
LOT,AH_RPT_LOCATION".split(","),

// Specifies the date format that all date strings are expected to be provided in
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in
dateTimeFormat: "MM/dd/yyyy HH:mm",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
//If a pay code set is defined, only pay codes in that set can be imported. If set to null or
//an empty string, all pay codes will be allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
//work date that falls in a closed period is imported. If set to false, records with work
//dates in a closed period will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
//automatically unapproved when a time record with a work date that falls in that period is
//imported.If amendTimeSheetsIfNecessary is set to false, then this option will have no
//effect.
unapproveAmendedPeriods: false,

// Specifies the login_id of the user to use for generating unapprovals when
//unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 426


WT&A API Specifications 18.3 Time Entry Import API

function mappingFunction1(record) {
return {
"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": record.work_dt,
"start_dttm": record.work_dt + " 09:00:00",
"end_dttm": record.work_dt + " 17:00:00",
"pay_code": "REG",
"hours": "8",
"OTHER_TEXT10": "TT28437_2",
"comments": "TT28437_2"
};
}

function mappingFunction2(record) {
return {
"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": Packages.com.workforcesoftware.Util.DateTime.WDate.valueOf(record.work_dt,
DATE_FMT).addDays(1),
"pay_code": "REG",
"hours": "6",
"OTHER_TEXT10": "TT28437_2",
"comments": "TT28437_2"
};
}

function mappingFunction3(record) {
return {
"employee_lookup_id": record.display_employee,
"asgnmt_match_fld_value": record.asgnmt,
"work_dt": Packages.com.workforcesoftware.Util.DateTime.WDate.valueOf(record.work_dt,
DATE_FMT).addDays(2),
"pay_code": "REG",
"hours": "4",
"OTHER_TEXT10": "TT28437_2",
"comments": "TT28437_2"
};
}

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 427


WT&A API Specifications 18.3 Time Entry Import API

function validationFunction(asgnmtInfo, entryType, record) {


var errors = [];

if (isBlank(record.EMPLOYEE_LOOKUP_ID)) {
errors.push("EMPID is required");
}
return errors;
}

var teiAPI = new TimeEntryImportAPI(parms);


teiAPI.importSingleTimeRecord(mappingFunction1, validationFunction);
teiAPI.importSingleTimeRecord(mappingFunction2, validationFunction);
teiAPI.importSingleTimeRecord(mappingFunction3, validationFunction);

Time Entry Import Commit


This use case defines the behavior that will be used to merge the new set of records being imported with the
existing time that is already on employees' time sheets.

Example 1: Replace existing records on day


Removes existing records from the timesheet/schedule for only the days with new time being imported for
the current assignment being processed.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Specifies whether the changes made to the time sheet/schedule by the commit process
should be audited. This should

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 428


WT&A API Specifications 18.3 Time Entry Import API

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


teiAPI.replaceExistingRecordsOnDay();

Example 2: Replace existing records in period


Removes existing records from the timesheet/schedule for all days in the periods with new time being
imported for the current assignment being processed.
First setup API in “Commit Setup Script” section of Time Entry Import policy.
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


teiAPI.replaceExistingRecordsInPeriod();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 429


WT&A API Specifications 18.3 Time Entry Import API

Example 3: Replace existing records in date range


Removes existing records from the timesheet/schedule for all days in between the earliest date and the
latest date that time is being imported on for the current assignment being processed.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


teiAPI.replaceExistingRecordsInDateRange();

Example 4: Replace existing or importing records with replacement function


Allows for custom removal behavior to be defined to control the removal of existing or importing records
from the timesheet/schedule.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 430


WT&A API Specifications 18.3 Time Entry Import API

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:

teiAPI.replaceExistingRecords(replacementFunction);

function replacementFunction(asgnmtInfo, importedRecords, existingRecords) {


var asgnmt = asgnmtInfo.asgnmt.toString();

// filter out existingRecords


if (asgnmt == "14234570514") {
for (var i = 0; i < existingRecords.length; ++i) {
existingRecords[i] = null;
}
}
// filter out records being imported
else if (asgnmt == "14234570502") {
for (var i = 0; i < importedRecords.length; ++i) {
importedRecords[i] = null;
}
}
// filter out records being imported
else if (asgnmt == "14234570485") {
for (var i = 0; i < importedRecords.length; ++i) {
if (importedRecords[i].work_dt > "2014-02-25") {
importedRecords[i] = null;
}
}
for (var i = 0; i < existingRecords.length; ++i) {
if (existingRecords[i] != null && existingRecords[i].work_dt < "2014-02-26") {

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 431


WT&A API Specifications 18.3 Time Entry Import API

existingRecords[i] = null;
}
}
}
}

Example 5: Replace existing records in specified date range


Removes existing records from the timesheet/schedule for all days that fall between the start-date and end-
date, inclusive.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


var startDate = new WFSDate(2014,02,23);
var endDate = new WFSDate(2014,02,25);
teiAPI.replaceExistingRecordsInSpecifiedDateRange(startDate, endDate);

Example 6: Approve amended time sheets and send exception notification


This script excerpt demonstrates how to approve any amended time sheets with time imported and how to
send exception notifications for periods with time.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 432


WT&A API Specifications 18.3 Time Entry Import API

First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: true,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


teiAPI.replaceExistingRecordsOnDay();
Call the function in “Commit Cleanup Script” section as follows:
teiAPI.approveAmendedTimeSheets(); // approving any amended time sheets with time imported
teiAPI.sendExceptionNotifications(); // sending exception notifications for periods with time
imported

Example 7: Importing deletion-only records


This script excerpt demonstrates how the import can be used to delete records.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 433


WT&A API Specifications 18.3 Time Entry Import API

// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: true,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false,

//The field on the time record containing the indicator used to identify deletion-only records
deleteField: "OTHER_TEXT1",

// Array of values that mark a record as deletion only


deleteValues: ["Y"]
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Example 8: Replace existing records using overriding match string


Removes existing records with matching string from the timesheet/schedule for only the day with new time
being imported for the current assignment being processed.
First setup API in “Commit Setup Script” section of Time Entry Import policy as follows:
includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Match strings to match existing time records against.This overrides the default behavior of
//using the match values defined on the records being imported
timeRecordIDStrings: ["TT28437_3"],

// Specifies whether new records will be allowed to be imported on days that already contain
manually-edited time

// records. If this is set to true, any records in the import record set that fall on days
containing manually-edited
// time will be filtered out and the existing records will be left untouched. Otherwise,
manually-edited time will be
// subject to the indicated time record replacement behavior.
dontImportOnManuallyEditedDays: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 434


WT&A API Specifications 18.3 Time Entry Import API

// Specifies whether or not time records will be allowed to be imported prior to the current
period. If set to false,
// any records with a work date prior to the current period will be filtered out.
amendTimeSheets: false,

// Specifies the login_id of the user to use for approving any amended time sheets with new
time being imported.
approver: "WORKFORCE",

// Specifies the approval level to assign to amended time sheets being approved
automatically
approvalLevel: 5,

// Indicates if the API logging should use the expanded name (including the employee first and
last name), or if it should only output the internal ID numbers
useExpandedAsgnmtName: false,

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

var teiAPI = new TimeEntryImportCommitAPI(parms);

Call the function in “Commit Entry Script” section as follows:


teiAPI.replaceExistingRecordsOnDay();

Time Import Controller


This use case defines the behavior that will be used for the creation of TIME_ENTRY_DETAIL_IMPORT
records, linking them to the corresponding time_entry_imp_batch records as appropriate, as well as the
running of multiple Time Entry Import Commit jobs.

Example 1: Single time entry import controller


This script excerpt demonstrates Time Entry Import that uses a single controller to load data to the time
sheet detail table.

includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
which assignment to
// import the time record to.
matchField: "COMPUTED_MATCH_ID",

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// TIME_SHEET_DETAIL table. If there is only one Time Entry Import policy to be run, this
should be the exact name of
// that policy. If multiple Time Entry Import policies should be run, those policies should
be named <policy name>1,
// <policy name>2, and so on (for example TIME_IMPORT_1, TIME_IMPORT_2, etc.) and this
should just specify the
// <policy name> portion of that identifier, i.e. "TIME_IMPORT_". If this is set to an
empty string, no jobs will be
// run to import TIME_SHEET_DETAIL records.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 435


WT&A API Specifications 18.3 Time Entry Import API

timeImportPolicy: "TIME_IMPORT_POLICY",

// Specifies the number of different Time Entry Import policies that should be used to write
records to the
// TIME_SHEET_DETAIL table. The assignments that time records belong to will automatically
be distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
timeImportCount: 1,

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// SCHEDULE_DETAIL table. If there is only one Time Entry Import policy to run, this should
be the exact name of that
// policy. If multiple Time Entry Import policies should be run, those policies should be
named <policy name>1,
// <policy name>2, and so on (for example SCHEDULE_IMPORT_1, SCHEDULE_IMPORT_2, etc.) and
this should just specify the
// <policy name> portion of that identifier, i.e. "SCHEDULE_IMPORT_". If this is set to an
empty string, no jobs will
// be run to import SCHEDULE_DETAIL records.
scheduleImportPolicy: "",

// Specifies the number of different Time Entry Import policies that should be used to write
records to the
// SCHEDULE_DETAIL table. The assignments that time records belong to will automatically be
distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
scheduleImportCount: 1,

// Specifies the date format that all date strings are expected to be provided in.
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in.
dateTimeFormat: "MM/dd/yyyy HH:mm:ss",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
If a pay code set is
// defined, only pay codes in that set can be imported. If set to null or an empty string,
all pay codes will be
// allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
work date that falls in a
// closed period is imported. If set to false, records with work dates in a closed period
will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
automatically unapproved when a
// time record with a work date that falls in that period is imported. If
amendTimeSheetsIfNecessary is set to false,
// then this option will have no effect.
unapproveAmendedPeriods: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 436


WT&A API Specifications 18.3 Time Entry Import API

// Specifies the login_id of the user to use for generating unapprovals when
unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false,

// Specifies whether the timesheet/schedule records should be consolidated


consolidateRecords: false
};

/**
* Uses the data in the source data record to construct a JavaScript object with properties
corresponding to the fields
* in the TIME_ENTRY_DETAIL_IMPORT table and add that object to the list of records to be
processed.
*
* @param {TimeImportControllerAPI} teiAPI the import API
* @param {ResultSet} source the current source data record
*/
function importRecord(teiAPI, source) {
// Example mapping:
var record = {
employee_lookup_id: source.EMPLOYEE_ID,
asgnmt_match_fld_value: source.EMPLOYEE_ID,
work_dt: source.WORK_DATE,
hours: source.HOURS,
pay_code: source.PAY_CODE,
other_text10: "Time Import"
};

// Add the record to the set of records being imported. The second parameter specifies
whether the record being
// added should map to TIME_SHEET_DETAIL or to SCHEDULE_DETAIL. Valid options are
TIME_ENTRY or SCHEDULE. (Case does
// not matter.)
teiAPI.addRecord(record, "TIME_ENTRY", validationFunction); //with validation function
// teiAPI.addRecord(record, "TIME_ENTRY"); //without validation function

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
return [];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 437


WT&A API Specifications 18.3 Time Entry Import API

function main() {
try {
// Initialize the API with the parameters defined above
var teiAPI = new TimeImportControllerAPI(parms);

// Loop through the records in your source data


var source = new CSVResultSet("interface/incoming/time_import.csv");
while (source.next() ) {
jsHost.throwIfAbortRequested();
importRecord(teiAPI, source);
}

// Commit the records to the database and launch the additional job(s) needed to finish
importing the records
teiAPI.runTimeImportJobs();
}
catch (e) {
log.error("Error: " + e);
}
}

main();

Example 2: Multiple time entry import controller


This script excerpt demonstrates Time Entry Import that uses multiple controllers to load data to the time
sheet detail table.

includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
which assignment to
// import the time record to.
matchField: "COMPUTED_MATCH_ID",

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// TIME_SHEET_DETAIL table. If there is only one Time Entry Import policy to be run, this
should be the exact name of
// that policy. If multiple Time Entry Import policies should be run, those policies should
be named <policy name>1,
// <policy name>2, and so on (for example TIME_IMPORT_1, TIME_IMPORT_2, etc.) and this
should just specify the
// <policy name> portion of that identifier, i.e. "TIME_IMPORT_". If this is set to an
empty string, no jobs will be
// run to import TIME_SHEET_DETAIL records.
timeImportPolicy: "TIME_IMPORT_POLICY",

// Specifies the number of different Time Entry Import policies that should be used to write
records to the

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 438


WT&A API Specifications 18.3 Time Entry Import API

// TIME_SHEET_DETAIL table. The assignments that time records belong to will automatically
be distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
timeImportCount: 2,

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// SCHEDULE_DETAIL table. If there is only one Time Entry Import policy to run, this should
be the exact name of that
// policy. If multiple Time Entry Import policies should be run, those policies should be
named <policy name>1,
// <policy name>2, and so on (for example SCHEDULE_IMPORT_1, SCHEDULE_IMPORT_2, etc.) and
this should just specify the
// <policy name> portion of that identifier, i.e. "SCHEDULE_IMPORT_". If this is set to an
empty string, no jobs will
// be run to import SCHEDULE_DETAIL records.
scheduleImportPolicy: "",

// Specifies the number of different Time Entry Import policies that should be used to write
records to the
// SCHEDULE_DETAIL table. The assignments that time records belong to will automatically be
distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
scheduleImportCount: 1,

// Specifies the maximum number of time entry import jobs launched by this script that are
allowed to run at one time.
// If more time entry import jobs than this number are intended to be launched by this job,
only this number will be
// started initially and then as each of those jobs finishes the next one will be started
automatically. If this is
// set to zero, all jobs will be run simultaneously.
maximumSimultaneousJobs: 5,

// Specifies the date format that all date strings are expected to be provided in.
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in.
dateTimeFormat: "MM/dd/yyyy HH:mm:ss",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
If a pay code set is
// defined, only pay codes in that set can be imported. If set to null or an empty string,
all pay codes will be
// allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
work date that falls in a
// closed period is imported. If set to false, records with work dates in a closed period
will error out.
amendTimeSheets: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 439


WT&A API Specifications 18.3 Time Entry Import API

// Specifies whether amended time sheets that have already been approved should be
automatically unapproved when a
// time record with a work date that falls in that period is imported. If
amendTimeSheetsIfNecessary is set to false,
// then this option will have no effect.
unapproveAmendedPeriods: false,

// Specifies the login_id of the user to use for generating unapprovals when
unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

/**
* Uses the data in the source data record to construct a JavaScript object with properties
corresponding to the fields
* in the TIME_ENTRY_DETAIL_IMPORT table and add that object to the list of records to be
processed.
*
* @param {TimeImportControllerAPI} teiAPI the import API
* @param {ResultSet} source the current source data record
*/
function importRecord(teiAPI, source) {
// Example mapping:
var record = {
employee_lookup_id: source.EMPLOYEE_ID,
asgnmt_match_fld_value: source.EMPLOYEE_ID,
work_dt: source.WORK_DATE,
hours: source.HOURS,
pay_code: source.PAY_CODE,
other_text10: "Time Import"
};

// Add the record to the set of records being imported. The second parameter specifies
whether the record being
// added should map to TIME_SHEET_DETAIL or to SCHEDULE_DETAIL. Valid options are
TIME_ENTRY or SCHEDULE. (Case does
// not matter.)
teiAPI.addRecord(record, "TIME_ENTRY", validationFunction); //with validation function
// teiAPI.addRecord(record, "TIME_ENTRY"); //without validation function
}

function main() {
try {
// Initialize the API with the parameters defined above
var teiAPI = new TimeImportControllerAPI(parms);

// Loop through the records in your source data


var source = new CSVResultSet("interface/incoming/time_import.csv");
while (source.next() ) {
jsHost.throwIfAbortRequested();
importRecord(teiAPI, source);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 440


WT&A API Specifications 18.3 Time Entry Import API

// Commit the records to the database and launch the additional job(s) needed to finish
importing the records
teiAPI.runTimeImportJobs();
}
catch (e) {
log.error("Error: " + e);
}
}

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
return [];
}

main();

Example 3: Controller to import schedule


This script excerpt demonstrates how to import schedules using single time import controller.

includeDistributedPolicy("TIME_ENTRY_IMPORT_API");

var parms = {
// Specifies the field on the ASGNMT record that the value being mapped to
// TIME_ENTRY_DETAIL_IMPORT.ASGNMT_MATCH_FLD_VALUE is expected to match against to determine
which assignment to
// import the time record to.
matchField: "COMPUTED_MATCH_ID",

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// TIME_SHEET_DETAIL table. If there is only one Time Entry Import policy to be run, this
should be the exact name of
// that policy. If multiple Time Entry Import policies should be run, those policies should
be named <policy name>1,
// <policy name>2, and so on (for example TIME_IMPORT_1, TIME_IMPORT_2, etc.) and this
should just specify the
// <policy name> portion of that identifier, i.e. "TIME_IMPORT_". If this is set to an
empty string, no jobs will be
// run to import TIME_SHEET_DETAIL records.
timeImportPolicy: "",

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 441


WT&A API Specifications 18.3 Time Entry Import API

// Specifies the number of different Time Entry Import policies that should be used to write
records to the
// TIME_SHEET_DETAIL table. The assignments that time records belong to will automatically
be distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
timeImportCount: 1,

// Specifies the name of the Time Entry Import policy that should be kicked off
automatically to write records to the
// SCHEDULE_DETAIL table. If there is only one Time Entry Import policy to run, this should
be the exact name of that
// policy. If multiple Time Entry Import policies should be run, those policies should be
named <policy name>1,
// <policy name>2, and so on (for example SCHEDULE_IMPORT_1, SCHEDULE_IMPORT_2, etc.) and
this should just specify the
// <policy name> portion of that identifier, i.e. "SCHEDULE_IMPORT_". If this is set to an
empty string, no jobs will
// be run to import SCHEDULE_DETAIL records.
scheduleImportPolicy: " TIME_IMPORT_POLICY ",

// Specifies the number of different Time Entry Import policies that should be used to write
records to the
// SCHEDULE_DETAIL table. The assignments that time records belong to will automatically be
distributed evenly
// across these different import jobs, so that all of the records being imported for a given
assignment will be
// processed during the same import job.
scheduleImportCount: 1,

// Specifies the date format that all date strings are expected to be provided in.
dateFormat: "MM/dd/yyyy",

// Specifies the date-time format that all date-time strings are expected to be provided in.
dateTimeFormat: "MM/dd/yyyy HH:mm:ss",

// Specifies the pay code set to use to limit which pay codes are allowed to be imported.
If a pay code set is
// defined, only pay codes in that set can be imported. If set to null or an empty string,
all pay codes will be
// allowed to import successfully.
payCodeSet: "",

// Specifies whether time sheets should be automatically amended when a time record with a
work date that falls in a
// closed period is imported. If set to false, records with work dates in a closed period
will error out.
amendTimeSheets: false,

// Specifies whether amended time sheets that have already been approved should be
automatically unapproved when a
// time record with a work date that falls in that period is imported. If
amendTimeSheetsIfNecessary is set to false,
// then this option will have no effect.
unapproveAmendedPeriods: false,

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 442


WT&A API Specifications 18.3 Time Entry Import API

// Specifies the login_id of the user to use for generating unapprovals when
unapproveAmendedPeriods is set to true.
approver: "WORKFORCE",

// Specifies whether additional debug information should be written to the job log.
enableDebugLogging: false
};

/**
* Uses the data in the source data record to construct a JavaScript object with properties
corresponding to the fields
* in the TIME_ENTRY_DETAIL_IMPORT table and add that object to the list of records to be
processed.
*
* @param {TimeImportControllerAPI} teiAPI the import API
* @param {ResultSet} source the current source data record
*/
function importRecord(teiAPI, source) {
// Example mapping:
var record = {
employee_lookup_id: source.EMPLOYEE_ID,
asgnmt_match_fld_value: source.EMPLOYEE_ID,
work_dt: source.WORK_DATE,
hours: source.HOURS,
pay_code: source.PAY_CODE,
other_text10: "Time Import"
};

// Add the record to the set of records being imported. The second parameter specifies
whether the record being
// added should map to TIME_SHEET_DETAIL or to SCHEDULE_DETAIL. Valid options are
TIME_ENTRY or SCHEDULE. (Case does
// not matter.)
teiAPI.addRecord(record, "TIME_ENTRY", validationFunction); //with validation function
// teiAPI.addRecord(record, "SCHEDULE "); //without validation function

/**
* This function is executed after the data mappings are complete, and allows for custom
validation logic to be applied
* to each record to determine if it should be imported or not. This function also allows for
any final modifications
* to be made to the data mappings.
*
* @param {AssignmentInfo} asgnmtInfo information for the assignment the record is being
imported for
* @param {Entry_type} entryType the entry type associated with the record
* @param {Object} record scriptable object containing the values mapped to the
TIME_ENTRY_DETAIL_IMPORT table
* @returns {String[]} array of error messages generated for this record
*/
function validationFunction(asgnmtInfo, entryType, record) {
return [];
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 443


WT&A API Specifications 18.3 Time Entry Import API

function main() {
try {
// Initialize the API with the parameters defined above
var teiAPI = new TimeImportControllerAPI(parms);

// Loop through the records in your source data


var source = new CSVResultSet("interface/incoming/time_import.csv");
while (source.next() ) {
jsHost.throwIfAbortRequested();
importRecord(teiAPI, source);
}

// Commit the records to the database and launch the additional job(s) needed to finish
importing the records
teiAPI.runTimeImportJobs();
}
catch (e) {
log.error("Error: " + e);
}
}

main();

Troubleshooting
The job log of the script using the Time Entry Import API will include informational messages, and in the case
of problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
teiApiJavaWrapper is a reserved name An object is defined with name Don’t use any
when using this API. Please modify teiApiJavaWrapper and this object name is object with name
your script not to define any objects reserved for API use teiApiJavaWrapper
with this name.
startDate and endDate are required for Start and endDate are not provided for Provide start and
the replace existing records in specified replaceExistingRecordsInSpecifiedDateRange end dates
date range option method

startDate and endDate must be Start and end dates are instance of WDate startDate and
instances of WFSDate instead of WFSDate endDate must be
instances of
WFSDate
Invalid type specified in Invalid type is specified in the second Provide valid type
TimeImportControllerAPI.addRecord() parameter of TIME_ENTRY or
Valid options are options TIME_ENTRY TimeImportControllerAPI.addRecord() SCHEDULE
or SCHEDULE
Unable to process record: No mapping Mapping type is not defined in API parameters Define mapping
type defined type either
Function or
Decoder

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 444


WT&A API Specifications 18.3 Time Entry Import API

Replacement function provided must be Replacement function is not a function Replacement


a function function must be a
function
Validation function provided must be a Validation function is not a function Validation function
function should be a
function

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Time Entry Import API consist of following component(s).
1. TimeEntryImportAPI
2. TimeEntryImportCommitAPI
3. TimeImportControllerAPI

TimeEntryImportAPI
This API use within the Script Text portion of a Time Entry Import policy, this API provides methods to import
time records. Before importing any records, this API will validate that the Time Entry Import is configured
correctly for use with this functionality, and will stop any records from being processed if the configuration is
incorrect. The following methods are available for TimeEntryImportAPI.

TimeEntryImportAPI (parms)
Creates an instance of TimeEntryImportAPI.
Parameter Description
parms JavaScript object containing the configuration settings to use with this API

importSingleTimeRecord (mapping, validationFunction)


Imports a single time record from a single source data record to the TIME_ENTRY_DETAIL_IMPORT staging
table.
Parameter Description
mapping if the API is set to operate on a decoder, this should be the name of the
decoder policy to use. If the API is set to operate on a function, this should be
a function that returns a JS object mapped from the source data representing
the time data to be imported. This function should include the following
parameters:
(1) current data row in the source result set
validationFunction (optional) function that returns a JS array of error messages for the source
record being processed. This function should include the following
parameters:
(1) AssignmentInfo for the assignment of the record being processed
(2) Entry_type for the pay code of the record being processed
(3) The mapped data for the record

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 445


WT&A API Specifications 18.3 Time Entry Import API

importMultipleTimeRecords (mapping, validationFunction)


Imports an array of time records from a single source data record to the TIME_ENTRY_DETAIL_IMPORT
staging table.
Parameter Description
mapping If the API is set to operate on a function, this should be a function that returns
a JS object mapped from the source data representing the time data to be
imported. This function should include the following parameters:
(1) current data row in the source result set
validationFunction (optional) function that returns a JS array of error messages based on the
mapped record being processed. This function will trigger once for each
record returned in the mapping array by the mapping function. This function
should include the following parameters:
(1) AssignmentInfo for the assignment of the record being processed
(2) Entry_type for the pay code of the record being processed
(3) The mapped data for the record

Note: This method cannot be used with the API set to operate on a decoder

printAvailableAPIParms ()
Prints a list of the parameters that are available for this API, along with the expected data types, to the log.

TimeEntryImportCommitAPI
This API provides methods for reconciling records being imported with the records that already exist on the
time sheet or schedule. It also provides functionality for approving any amended timesheets that have had
time imported into them during the import and for generating exception notifications for periods containing
imported time. The following methods are available for TimeEntryImportCommitAPI.

TimeEntryImportCommitAPI (parms)
Creates an instance of TimeEntryImportCommitAPI.
Parameter Description
parms JavaScript object containing the configuration settings to use with this API

Note: This API should be instantiated in the Commit Setup script section of the Time Entry Import policy.

replaceExistingRecordsOnDay ()
Removes existing records from the timesheet/schedule for only the days with new time being imported for
the current assignment being processed.

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 446


WT&A API Specifications 18.3 Time Entry Import API

replaceExistingRecordsInPeriod ()
Removes existing records from the timesheet/schedule for all days in the periods with new time being
imported for the current assignment being processed.

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

replaceExistingRecordsInDateRange ()
Removes existing records from the timesheet/schedule for all days in between the earliest date and the
latest date that time is being imported on for the current assignment being processed.

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

replaceExistingRecordsInWeek ()
Removes existing records from the timesheet/schedule for all days that fall in weeks with new time being
imported on for the current assignment being processed.

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

replaceExistingRecordsInSpecifiedDateRange (startDate, endDate)


Removes existing records from the timesheet/schedule for all days that fall between the startDate and
endDate, inclusive.
Parameter Description
startDate the first date of the range where existing records will be removed
endDate the last date of the range where existing records will be removed

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

replaceExistingRecords (replacementFunction)
Allows for custom removal behavior to be defined to control the removal of existing records from the
timesheet/schedule.
Parameter Description
replacementFunction The replacement function to use. To remove an existing record within this
function, set that record to null within the provided array. Likewise, to
prevent a record in the import set from being imported, set it to null within its
array. This function should include the following parameters:
(1) AssignmentInfo for the assignment being processed
(2) the array of records being imported for this assignment
(3) the array of existing records for this assignment that fall within the
periods with new records being imported

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 447


WT&A API Specifications 18.3 Time Entry Import API

Note: This method should be called within the Commit Employee script section of the Time Entry Import
policy.

approveAmendedTimeSheets ()
Approves the timesheets for all amended periods that had time imported during this import.

Note: This method should be called within the Commit Cleanup script section of the Time Entry Import policy.

sendExceptionNotifications ()
Sends out notifications for any exceptions that were generated based on the time records that were
imported.

Note: This method should be called within the Commit Cleanup script section of the Time Entry Import policy.

printAvailableAPIParms ()
Prints a list of the parameters that are available for this API, along with the expected data types, to the log.

TimeImportControllerAPI
This API defines methods for creating TIME_ENTRY_DETAIL_IMPORT records and loading them into that table
from within a controller script. Throttling controls are provided to allow the script to control how many
different jobs the records will be divided between, and how many of those jobs can run simultaneously.
The following methods are available for TimeImportControllerAPI.

TimeImportControllerAPI (parms)
Create an instance of TimeImportControllerAPI.
Parameter Description
parms JavaScript object containing the configuration settings to use with this API

addRecord (record, type, validationFunction)


Adds a new record to the set of records being imported by the controller API, also allows consolidation of
time entry records while adding to the set.
Parameter Description
record JavaScript object with properties corresponding to the fields in
time_entry_detail_import that should be populated for this record
type determines whether the record being imported is a schedule or time entry
record. Valid options are either a Timesheet_or_schedule choice object, a
constant that evaluates to a valid Timesheet_or_schedule choice, or a
number that evaluates to a valid Timesheet_or_schedule choice. See Data
Dictionary for further details regarding valid options for choices.
validationFunction (optional) function that returns a JS array of error messages for the source
record being processed. This function should include the following
parameters:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 448


WT&A API Specifications 18.3 Time Entry Import API

(1) AssignmentInfo for the assignment of the record being processed


(2) Entry_type for the pay code of the record being processed
(3) The mapped data for the record

runTimeImportJobs (connection)
Commits the records to the database and runs the time entry and schedule import jobs that have been
defined to load the records from the time_entry_detail_import table into their final destinations.
Parameter Description
connection connection to the local database to use for committing records and running
additional jobs.

printAvailableAPIParms ()
Prints a list of the parameters that are available for this API, along with the expected data types.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 449


WT&A API Specifications 18.3 Time Off Request API

Time Off Request API


Overview and Capabilities
The Time Off Request API provides scripts running in WorkForce Time and Attendance the ability to perform
certain common operations against time off requests. These operations include creating new time off
requests, modifying the details of an existing time off request, changing the status of a time off request, and
looking up information about existing time off requests. The functionality provided by this API can either be
used within a script solely dedicated to that purpose, such as a script to import new time off requests, or it
can be used as part of a larger process to accomplish just a portion of the desired task.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The Distributed JavaScript Library TIME_OFF_REQUEST_API

Setup
No setup is necessary for the Time Off Request API. The distributed library is automatically available within
WorkForce Time and Attendance.

Use Cases
Creating a New Time Off Request
The Time Off Request API allows for the creation of a new time off request. This would typically be done
when an external system is serving as the system of record for time off request entry, in order to synchronize
the time off request data between the two systems.

Example: Creating a new time off request


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Define the details for the time off request. Each detail represents a single slice
// of time that should be included in the time off request. In this example, three
// slices of time will be included in the time off request.

var details = [
{
work_dt: convertWDate("2017-04-17"),
pay_code: "VAC"
},
{
work_dt: convertWDate("2017-04-18").

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 450


WT&A API Specifications 18.3 Time Off Request API

pay_code: "VAC"
},
{
work_dt: convertWDate("2017-04-19"),
pay_code: "VAC"
}
];

// Define the time off request to be created. The assignment ID could come from
// a source data file or some similar lookup
var timeOffRequest = {
asgnmt: "1234567890",
details: details,
comments: "I'm going to be in Florida for three days"
};

// Create the time off request


var torId = timeOffRequestApi.createTimeOffRequest(timeOffRequest);

// Log out the ID of the newly created time off request


log.info("The new time off request had ID: " + torId);

Note: The start and end date for the time off request will be determined by the earliest and latest date of the
details for the time off request

Finding an Existing Time Off Request


The Time Off Request API can be used to look up details for existing time off requests. This can be used when
determining if a particular time off request already exists, when needing to determine the attributes of an
existing time off request, or when wanting to change details of a time off request.

Example 1: Looking up a time off request by internal ID


The following example will find the details for an existing time off request by matching against the internal ID
assigned to the time off request by WorkForce. This ID may come from another internal WorkForce process.
includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the internal ID of the time off request
// to be looked up
var torId = getTimeOffRequestId();

// Look up the time off request data


var tor = timeOffRequestApi.getTimeOffRequest(torId);

log.info("Found time off request " + tor.time_off_request);


log.info("Start date of request = " + tor.start_date);
log.info("End date of request = " + tor.end_date);

// Do whatever needs to be done with the time off request

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 451


WT&A API Specifications 18.3 Time Off Request API

Example 2: Looking up a time off request by external ID


If a time off request originates in an external system, provided by the customer, then that time off request
can have an external ID specified that matches an ID in that customer’s external system that generated the
time off request. This allows WorkForce to find the matching time off request based on the ID provided by
the customer (as opposed to the internally-generated IDs, which are unlikely to be known by any of the
customer’s systems).
includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the external ID of the time off request
// to be looked up
var torId = getTimeOffRequestId();

// Look up the time off request data


var tor = timeOffRequestApi.getTorByExternalId(torId);

log.info("Found time off request " + tor.time_off_request);


log.info("Start date of request = " + tor.start_date);
log.info("End date of request = " + tor.end_date);

// Do whatever needs to be done with the time off request

Example 3: Looking up time off requests by status


The Time Off Request API can also find all time off requests with a given status. This can be useful for certain
operations, such as trying to generate a list of all outstanding pending time off requests.
includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Identify the statuses of the time off requests to look for


var statuses = ["PENDING"];

// Look up the time off request data


var tors = timeOffRequestApi.getTimeOffRequestsByStatus(statuses);

log.info("Found " + tors.length + " time off requests in a pending status");


for (var i = 0; i < tors.length; ++i) {
var tor = tors[i];
// Do whatever needs to be done with the time off request
}

Deleting Time Off Requests


The Time Off Request API can be used to delete time off requests. Time off requests that have been deleted
will no longer appear on the time off request status screen for the employee. If a time off request that is
deleted had already been approved, the corresponding time sheet or schedule records that were linked to
the time off request will be deleted as well.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 452


WT&A API Specifications 18.3 Time Off Request API

Example 1: Deleting a time off request by internal ID


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the internal ID of the time off request to be
// deleted
var torId = getTimeOffRequestId();

// Delete the time off request


timeOffRequestApi.deleteTimeOffRequest(torId);

Example 2: Deleting a time off request by external ID


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the external ID of the time off request to be
// deleted
var torId = getTimeOffRequestId();

// Delete the time off request


timeOffRequestApi.deleteTorByExternalId(torId);

Getting the Slice-Level Details for a Time Off Request


The Time Off Request API can be used to look up the individual slice details for a time off request. This allows
scripts to evaluate, act on, or report on the slices that make up a time off request

Example: Getting the details for a time off request


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the ID of the time off request


var torId = getTimeOffRequestId();

// Load the time off request data


var tor = timeOffRequestApi.getTimeOffRequest(torId);

// Get the details for the time off request


var details = tor.getDetails();

for (var i = 0; i < details.length; ++i) {


var detail = details[i];
log.info("Found detail for " + detail.work_dt + " with pay code " +
detail.pay_code);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 453


WT&A API Specifications 18.3 Time Off Request API

Updating the Details for a Time Off Request


The Time Off Request API can be used to change the slice-level details that apply for a time off request. After
updating the details, the time off request will remain in the same status it was in before the details were
updated. If the time off request had been in an approved status, the corresponding time_sheet_detail
and/or schedule_detail records will be updated to reflect the new details for the time off request.

Example: Updating a time off request’s details


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the ID of the time off request


var torId = getTimeOffRequestId();

// Load the time off request data


var tor = timeOffRequestApi.getTimeOffRequest(torId);

// Define the new details that should be used for the time off request
var details = [
{
work_dt: convertWDate("2017-05-11"),
pay_code: "SICK"
},
{
work_dt: convertWDate("2017-05-12"),
pay_code: "SICK"
}
];

// Update the details of the time off request


tor.updateDetails(details);

Note: If the work date of the earliest or latest detail in the time off request changes, the start and/or end
dates of the time off request will be automatically updated to reflect the range spanned by the details.

Changing the Status of a Time Off Request


The Time Off Request API can be used to change the status of a time off request, such as changing a pending
time off request to the approved status or to cancel a pending time off request. Unlike a deleted time off
request, a cancelled time off request will remain visible on the time off request status screen.

Example: Changing the status of a time off request


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the ID of the time off request


var torId = getTimeOffRequestId();

// Load the time off request data


var tor = timeOffRequestApi.getTimeOffRequest(torId);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 454


WT&A API Specifications 18.3 Time Off Request API

// Change the time off request's status to approved


tor.changeStatus("APPROVED", "Have fun down in Florida!");

Note: Time Off Requests cannot be changed from every status to every other status. For instance, an
approved time off request cannot be changed back to a pending status. The API enforces the same
rules regarding status changes that would be enforced by the time off request screens in the
application.

Changing the Assignment a Time Off Request Belongs To


The Time Off Request API can be used to change which assignment is the owner of the time off request. This
would be useful in the case of future time off requests that exist when a split assignment happens, allowing
the time off requests to be easily switched from the old assignment to the new assignment. If the time off
request is in an approved state when the owner is changed, the corresponding timesheet and/or schedule
records will be switched from the original assignment to the new one as well.

Example: Changing the owner of a time off request


includeDistributedPolicy("TIME_OFF_REQUEST_API");

// Create an instance of the API


var timeOffRequestApi = new TimeOffRequestAPI();

// Execute some process to determine the ID of the time off request


var torId = getTimeOffRequestId();

// Load the time off request data


var tor = timeOffRequestApi.getTimeOffRequest(torId);

// Look up the internal assignment ID of the new assignment the time


// off request should belong to
var asgnmtId = findLatestAsgnmtIdForSplitAssignment();

// Update the owner of the time off request


tor.changeOwner(asgnmtId);

Note: The Time Off Request API cannot be used to change which employee a time off request belongs to. If
the new assignment ID specified is for a different employee than the original assignment belonged to,
an error will be generated.

Troubleshooting
The job log of the script using the Time Off Request API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


No assignment specified An attempt was made to create a Ensure that an assignment ID is
new time off request without specified when creating a new time off
specifying an assignment. request

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 455


WT&A API Specifications 18.3 Time Off Request API

No user found for The assignment specified when Ensure that all assignments with time
assignment ASGNMT_ID creating a new time off request off requests being created have a
does not have a user record corresponding user record
associated with it.
Error creating time off There was an error creating the Read the accompanying error message
request: ERROR_MESSAGE time off request due to system-level and take action as necessary to resolve
validation of the time off request it
information provided.
No ACT Case with ID An ACT Case ID was specified when Ensure that all ACT Cases specified for
ACT_CASE_ID exists creating a new time off request, but time off requests exist
no ACT Case with that ID currently
exists.
ACT Case ACT_CASE_ID is The ACT Case ID specified when Ensure that the ACT Case specified for
not valid for employee with creating a new time off request all time off request matches the
ID EMPLOYEE_ID. It is belongs to a different employee employee that time off request will
assigned to a different than the employee than owns the belong to
employee, assignment specified for the time
OTHER_EMPLOYEE_ID off request.
Only intermittent cases can The ACT Case ID specified when Ensure that all ACT Cases specified for
be associated with time off creating a new time off request did time off requests match intermittent
requests. ACT Case not match an intermittent ACT Case ACT Cases.
ACT_CASE_ID is a
CASE_TYPE case
Unable to load time off A call was made to Ensure that a time off request ID is
request data: No internal ID getTimeOffRequest but no time off always specified when looking up time
specified request ID was specified off requests
Unable to load time off A call was made to Ensure that an external ID is always
request data: No external ID getTorByExternalId but no external specified when looking up time off
specified ID was specified requests by external ID
Unable to load time off A call was made to Ensure that at least one status is
request data: No status(es) getTimeOffRequestsByStatus by no always specified when looking up time
specified statuses were specified off requests by status
Unable to delete time off A call was made to Ensure that a time off request ID is
request: no time off request deleteTimeOffRequest but no time always specified when deleting a time
ID specified off request ID was specified off request
Unable to delete time off A call was made to Ensure than an external ID is always
request: no external ID deleteTorByExternalId but no specified when deleting time off
specified external ID was specified requests by external ID
No work date specified on A detail was specified when Ensure that all details specified for a
time off request detail creating a new time off request that time off request include a work date
did not include a work date value
No pay code specified on A detail was specified when Ensure that all details specified for a
time off request detail creating a new time off request that time off request include a pay code
did not include a pay code
No details specified for Time No details were specified when Ensure that at least one detail record is
Off Request creating a new time off request specified when creating a new time off
request

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 456


WT&A API Specifications 18.3 Time Off Request API

Unable to update TOR An attempt was made to update Ensue that at least one detail record is
details: no details specifiedthe details for a time off request specified when updating the details for
without any new details being a time off request
specified
Unable to change the owner An attempt was made to change Ensure that the time off request is in a
of a time off request with a the owner of a time off request status that allows for the owner to be
status of STATUS when that request was already in a changed before trying to change the
status that does not allow for the owner
owner to be changed
Time off requests can not be An attempt was made to change Ensure that only single or component
assigned to aggregate the owner of a time off request to assignments are targeted as the new
assignments an aggregate assignment owner for a time off request when
changing its owner
Cannot use changeOwner to An attempt was made to change Ensure that calls to changeOwner are
change the employee a time the owner of a time off request so only being used to change which
off request belongs to. that a different employee owns it assignment owns a time off request
Employee would have within a given employee’s assignments
changed from
ORIGINAL_EMPLOYEE to
NEW_EMPLOYEE
Table 88: Time Off Request API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.

TimeOffRequestAPI
Creates a new instance of the Time Off Request API

createTimeOffRequest(parms)
Creates a new time off request with the specified parameters, returning the ID of the newly created time off
request.
Available parameters are:
Parameter Name Description
asgnmt The assignment that the time off request belongs to
details Array of JS objects containing the details for the
time off request. Each detail object is expected to
have properties corresponding to the values for the
fields on the detail that should be created
externalId The ID from an external system to identify the time
off request. If no value is provided this ID will be
left blank
actCase The internal ACT Case ID for the ACT Case the time
off request should be associated with. If no value is
provided then the time off request will not be
associated with an ACT Case.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 457


WT&A API Specifications 18.3 Time Off Request API

comments Optional comments that should be associated with


the time off request
Table 89: Parameters available when creating a new time off request

getTimeOffRequest(id)
Returns the time off request data for the time off request with the specified internal time off request ID.

getTorByExternalId(id)
Returns the time off request data for the time off request with the specified external ID value.

getTimeOffRequestsByStatus(statuses, asgnmts)
Returns an array of data for all time off requests that are currently in one of the specified statuses. An array
of assignments can optionally be specified, in which case only time off requests belonging to one of the
specified assignments will be returned.

deleteTimeOffRequest(id)
Deletes the time off request (and any associated time records that belong to it) with the specified internal
time off request ID.

deleteTorByExternalId(id)
Deletes the time off request (and any associated time records that belong to it) with the specified external ID
value.

TORScriptable
JavaScript object representing the data for a time off request. These will be returned by any of the methods
of the TimeOffRequestAPI that return time off request data.

getDetails()
Returns an array containing the information for the detail records that make up this time off request.

updateDetails(newDetails)
Replaces the existing details for the time off request with the new details specified. If the date range covered
by the new details has a different beginning or ending date, then the corresponding dates on the time off
request itself will also be updated.

changeStatus(newStatus, comments)
Update the status of the time off request to the specified status. The indicated comments will be associated
with that status change.

changeOwner(asgnmtId)
Switches the assignment that the time off request belongs to the indicated assignment. Anytime records
associated with the time off request will be moved as well. If the new assignment belongs to a different
employee than the time off request was originally associated with, this will generate an error.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 458


WT&A API Specifications 18.3 Timesheet Exception API

Timesheet Exception API


Overview and Capabilities
This API lets you retrieve exception data from the WT&A database.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The TIMESHEET_EXCEPTION_API distributed JavaScript Library

Setup
No setup is necessary for the TIMESHEET_EXCEPTION_API. The distributed library is automatically available
in WT&A.

Use Cases
Get Time Sheet Exceptions
The following script example demonstrate how the time sheet exceptions can be retrieved by providing
allowed parameters.

Example 1: Find time sheet exceptions by provided parameters.


Retrieve all time sheet exceptions according to provided parameters.
includeDistributedPolicy("TIMESHEET_EXCEPTION_API");

var apiParams = { isDebug : false };

// create instance of API


var timesheetExceptionAPI = new TimesheetExceptionAPI(apiParams);

//Set desired parameters and remove rest. All parameters are optional.
var params = {
exceptionCodeSet: "FM_AS_EXCEPTIONS",
severity: "INFO_NO_ACTION",
exceptionSource: "TIME_SHEET_DETAIL_SPLIT",
placeholder: "LD1",
asOfDate: new WFSDate(2004, 08, 29),
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
1211617644),
asgnmtEffDate: new WFSDate(2012, 06, 30),
exceptionDate: new WFSDate(2004, 08, 30)
};

// get exceptions
var exceptions = timesheetExceptionAPI.getExceptions();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 459


WT&A API Specifications 18.3 Timesheet Exception API

log.info(exceptions.length);

Example 2: Find all time sheet exceptions from database.


Retrieve all time sheet exceptions from database.
includeDistributedPolicy("TIMESHEET_EXCEPTION_API");

var apiParams = { isDebug : false };

// create instance of API


var timesheetExceptionAPI = new TimesheetExceptionAPI(apiParams);

// get exceptions
var exceptions = timesheetExceptionAPI.getExceptions();
log.info(exceptions.length);

Get Time Sheet Exceptions between Date Range


The following script example demonstrate how the time sheet exceptions can be retrieved between a given
date range

Example 1: Find time sheet exceptions between given date range without optional
parameters.
Retrieve time sheet exceptions between a date range.
includeDistributedPolicy("TIMESHEET_EXCEPTION_API");

var apiParams = { isDebug : false };

// create instance of API


var timesheetExceptionAPI = new TimesheetExceptionAPI(apiParams);

//Set required parameters


var params = {
exceptionStartDate: new WFSDate(2008, 12, 11),
exceptionEndDate: new WFSDate(2008, 12, 11)
};

// get exceptions
var exceptions = timesheetExceptionAPI.getExceptionsByDateRange(params);
log.info(exceptions.length);

Example 2: Find time sheet exceptions between given date range with optional
parameters.
Retrieve time sheet exceptions between a date range with optional parameters.
includeDistributedPolicy("TIMESHEET_EXCEPTION_API");

var apiParams = { isDebug : false };

// create instance of API


var timesheetExceptionAPI = new TimesheetExceptionAPI(apiParams);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 460


WT&A API Specifications 18.3 Timesheet Exception API

//Set required parameters with desired parameters and remove rest.


var params = {
exceptionStartDate: new WFSDate(2004, 08, 01),
exceptionEndDate: new WFSDate(2004, 08, 30),
exceptionCodeSet: "FM_AS_EXCEPTIONS",
severity: "INFO_NO_ACTION",
exceptionSource: "TIME_SHEET_DETAIL_SPLIT",
placeholder: "LD1",
asOfDate: new WFSDate(2004, 08, 29),
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
1211617644),
asgnmtEffDate: new WFSDate(2012, 06, 30)
};

// get exceptions
var exceptions = timesheetExceptionAPI.getExceptionsByDateRange(params);
log.info(exceptions.length);

Troubleshooting
The job log of the script using the TIMESHEET_EXCEPTION_API will include informational messages, and in
the case of problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Cause Solution
Exception start date not Required start date parameter is Provide required parameter for
provided missing or null in the method method.
getExceptionsByDateRange
Exception end date not Required end date parameter is Provide required parameter for
provided missing or null in the method method.
getExceptionsByDateRange
Specified end date is before Specified end date is before start date Specified correct dates.
start date in the method
getExceptionsByDateRange
Table 90: Timesheet Exception API common error messages, causes, and solutions

API Reference
Knowledge of JavaScript programming is necessary to make best use of this section.

TimesheetExceptionAPI
The following methods are available for TimesheetExceptionAPI.

TimesheetExceptionAPI (params)
Constructor to create new instance of API. Takes an object as parameter which includes defined parameter in
the table.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 461


WT&A API Specifications 18.3 Timesheet Exception API

Parameter Description
isDebug True if debug content should be written to the log, false if not

getExceptions (params)
Retrieve time sheet exceptions based on parameters. This method has all optional parameters and retrieve
time sheet exceptions according to provided number of parameters, it retrieves all time sheet exceptions
from database if no parameter is provided. Takes an object as parameter which includes defined parameters
in the table.
Parameter Description
exceptionCodeSet Exception Codes for which Exceptions need to be retrieved
severity Retrieve exceptions for specified severity
exceptionSource Filter on exception source
placeholder Time sheet exception value Placeholder
asOfDate Filter on Employee Period Start and End date
matchCondition The condition to select the assignment
asgnmtEffDate The effective date to use for the retrieval of the assignment record
exceptionDate exceptionDate

getExceptionsByDateRange (params)
Retrieve time sheet exceptions based on date range. This method has some required and optional
parameters, optional parameters add additional criteria to get the desired time sheet exceptions. Takes an
object as parameter which includes defined parameters in the table.
Parameter Description
exceptionStartDate Filter on Exception Start date range
exceptionEndDate Filter on Exception End date range
exceptionCodeSet Exception Codes for which Exceptions need to be retrieved
severity Retrieve exceptions for specified severity
exceptionSource Filter on exception source
placeholder Time sheet exception value Placeholder
asOfDate Filter on Employee Period Start and End date
matchCondition The condition to select the assignment
asgnmtEffDate The effective date to use for the retrieval of the assignment record

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 462


WT&A API Specifications 18.3 Timesheet Operations API

Timesheet Operations API


Overview and Capabilities
The Timesheet Operations API provides scripts running in WorkForce Time and Attendance the ability to
perform certain common operations against timesheets. These operations include approving or unapproving
timesheets, creating new amended versions of timesheets, or calculating timesheets. Additionally, this API
also allows for Schedule Templates or Cycles to be assigned to the desired employee(s). The functionality
provided by this API can either be used within a script solely dedicated to that purpose, such as a script to
recalculate the current period for all timesheets, or it can be used as part of a larger process to accomplish
just a portion of the desired task.
Many of the operations available through the Timesheet Operations API make use of match conditions, which
allow the operation to affect all timesheets for the employees/assignments that meet the specified criteria.
The match conditions used to look up the desired data can be simple, standalone conditions
(employee.hr_status = 'A') or can be combined together to form much more complicated conditions
(asgnmt.policy_profile = "PROFILE_A" and (asgnmt.schedule_template = "TEMPLATE_A" or
asgnmt.schedule_template = "TEMPLATE_B")). This gives the script the flexibility to define whichever
conditions are necessary in order to identify the desired timesheets.
The Timesheet Operations API also includes functionality for retrieving the current state of a timesheet in
order to drive additional logic or to assist in troubleshooting issues related to the current state of a
timesheet.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
1. The TIMESHEET_OPERATIONS_API Distributed JavaScript library
a. This automatically includes the API_UTIL Distributed JavaScript library
2. The MatchCondition which defines a condition to select employee, assignment, or user records

Setup
No setup is necessary for the Timesheet Operations API. The distributed library is automatically available
within WorkForce Time and Attendance.

Use Cases
Determining Existing Timesheet Status
The Timesheet Operations API allows a script to lookup the current state of a timesheet. This is useful if
certain actions should only be taken when a timesheet is in a certain state (for instance, swipes should only
be posted to an unapproved timesheet). This allows the script to conditionally change its behavior based on

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 463


WT&A API Specifications 18.3 Timesheet Operations API

the state of the timesheet. It also gives the script an opportunity to change the state of the timesheet before
continuing with any further processing.

Example: Determining the status of a timesheet


includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select employee E675542


var condition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E675542");

// Define a date within the period that we're interested in


var asOfDate = WFSDate.today();

// Get the status of the timesheet for the period containing the as-of date
var status = api.getTimesheetStatus(condition, asOfDate);

log.info("Current approval level = " + status.approvalLevel);


log.info("Manager approval level = " + status.mgrApprovalLevel);
log.info("Is employee submitted? " + status.isEmployeeApproved);
log.info("Is amended timesheet? " + status.isAmendment);

// This will be either OPEN, APPROVED, LOCKED, or CLOSED


log.info("Current timesheet state = " + status.currentState);

Note: If the condition specified matches more than one assignment, an exception will be generated

Determining the Period Boundaries for an Arbitrary Date


The Timesheet Operations API can be used to determine the period begin and period end dates for a Policy
Profile for any specified date. The dates returned will be the period boundary dates for whichever period
includes the date that was specified.

Example: Determining boundary dates


includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the policy profile we're interested in


var policyProfile = "NON_UNION_NON_EXEMPT";

// Define the date that we're interested in knowing the period boundaries for
var asOfDate = new WFSDate(2016, 7, 21);

// Get the period boundary dates


var periodDates = api.getPeriodDates(policyProfile, asOfDate);

log.info("Period begin date = " + periodDates.ppBegin);


log.info("Period end date = " + periodDates.ppEnd);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 464


WT&A API Specifications 18.3 Timesheet Operations API

Approving Timesheets
The Timesheet Operations API can be used to assign a new approval to a timesheet or a set of timesheets.
This will act as though a manager with the indicated approval level had directly approved those timesheets.

Example 1: Approving timesheets based on a match condition:


The following example will assign an approval level of 5 to all timesheets in the EXEMPT policy profile. The
approvals will be generated as though the user with the login ID E971222 had approved the timesheets.
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the timesheets to approve


var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define a date within the period that should be approved


var asOfDate = WFSDate.today();

// Specify the login ID of the approver to use


var approver = "E971222";

// Define the approval level to be applied


var approvalLevel = 5;

// Approve the timesheets


api.approveTimesheet(condition, asOfDate, approver, approvalLevel);

Example 2: Approving timesheets based on an assignment group:


The following example will assign an approval level of 7 to all timesheets in the “.APPROVAL” assignment
group. The approvals will be generated as though the user with the login ID E645571 had approved the
timesheets.
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("APPROVAL_LOOKUP");
var description = ".APPROVAL";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define a date within the period that should be approved


var asOfDate = WFSDate.today();

// Specify the login ID of the approver to use


var approver = "E645571";

// Define the approval level to be applied


var approvalLevel = 7;

// Approve the timesheets


api.approveTimesheetForGroup(group, asOfDate, approver, approvalLevel);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 465


WT&A API Specifications 18.3 Timesheet Operations API

Note: The API cannot be used to reduce the approval level of a timesheet while leaving it in an approved state
(e.g. changing the approval level from 5 to 3). If the existing approval level for the timesheet is greater
than the specified approval level, an exception will be generated. In order to apply a lower approval
level, the timesheet must first be unapproved and then approved again using the new, lower approval
level.

Unapproving Timesheets
The Timesheet Operations API can be used to reset a timesheet’s approval level back to zero. This will return
the timesheet back to its original unapproved, unsubmitted state, allowing new time entries to be added to
it. One common scenario where this may be desired is to allow swipes to post if there is a chance the
employee or a manager may have already increased the approval level of the timesheet.

Example 1: Unapproving timesheets based on a match condition:


The following example will unapprove all timesheets in the EXEMPT policy profile.
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the timesheets to unapprove


var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define a date within the period that should be unapproved


var asOfDate = WFSDate.today();

// Unapprove the timesheets


api.unapproveTimesheet(condition, asOfDate);

Example 2: Unapproving timesheets based on an assignment group:


The following example will unapprove all timesheets in the “.UNAPPROVAL” assignment group.
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("APPROVAL_LOOKUP");
var description = ".UNAPPROVAL";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define a date within the period that should be unapproved


var asOfDate = WFSDate.today();

// Unapprove the timesheets


api.unapproveTimesheetForGroup(group, asOfDate);

Note: Timesheets that have already been locked or closed cannot be unapproved. Attempting to unapproved
a timesheet in one of these states will cause an exception to be generated.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 466


WT&A API Specifications 18.3 Timesheet Operations API

Amending a Timesheet
The Timesheet Operations API can be used to amend a timesheet. This functions just like clicking on the
“Amend” button on the timesheet, and puts a closed timesheet in a state where it can be modified again. As
with any other amendments, timesheets that are amended using this process will be included during the
current period’s end-of-period processing once they have been approved.

Example: Creating an amended timesheet


The following example will create an amended timesheet for employee E156247 for the period containing
the date 2016-08-11.
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the employee whose timesheet should be amended
var condition = new MatchCondition("employee", "display_employee",
MatchOperator.EQUALS, "E156247");

// Define a date within the period that should be amended


var asOfDate = new WFSDate(2016, 8, 11);

// Amend the timesheet


if (api.amendTimesheet(condition, asOfDate) ) {
log.info("Timesheet amended successfully!");
}
else {
log.error("Unable to amend timesheet");
}

Note: The condition specified to select the timesheet to amend must select only a single assignment. If more
than one assignment matches the specified condition, an exception will be generated.

Calculating Timesheets
The Timesheet Operations API includes support for calculating timesheets. Some common scenarios where
this functionality might be desirable are:
• Scripting a nightly calculate process, if WorkForce Time and Attendance’s native support for that is
insufficient
• Calculating a range of future periods (e.g. to ensure balances are populated in the database for reports)

Calculating the current period:


There are helper methods available for the common task of calculating the current period. These allow the
current period to be calculated without first needing to determine which period is the current one and what
it’s corresponding date range is.

Example 1: Calculating the current period based on a match condition


This example will calculate the current period timesheets for all assignments in the NONEXEMPT Policy
Profile:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 467


WT&A API Specifications 18.3 Timesheet Operations API

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the timesheets to calculate


var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "NONEXEMPT");

// Calculate the timesheets


api.calculateCurrentPeriod(condition);

Example 2: Calculating the current period based on an assignment group


This example will calculate the current period timesheets for all assignments in the assignment group
“.CALCULATE”:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("CALCULATION_LOOKUP");
var description = ".CALCULATE";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Calculate the timesheets


api.calculateCurrentPeriodForGroup(group);

Calculating an arbitrary date range:


The Timesheet Operations API can also calculate timesheets for an arbitrary date range. The date range can
be restricted to a single period, but it is not required to be. For a date range that spans multiple periods,
each of the periods that overlap with the date range will be calculated. The Cross-Period Calculation process
is used for calculating the timesheets, ensuring that all periods being processed will be evaluated only once
regardless of how many periods are spanned by the date range.

Example 3: Calculating an arbitrary date range based on a match condition


This example will calculate all timesheets between 2016-03-16 and 2016-09-30 for all assignments in the
NONEXEMPT Policy Profile:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the timesheets to calculate


var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "NONEXEMPT");

// Define the date range to be calculated


var startDate = new WFSDate(2016, 3, 16);
var endDate = new WFSDate(2016, 9, 30);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 468


WT&A API Specifications 18.3 Timesheet Operations API

// Calculate the timesheets


api.calculateTimesheets(condition, startDate, endDate);

Example 4: Calculating an arbitrary date range based on an assignment group


This example will calculate all timesheets between 2016-02-29 and 2016-11-11 for all assignments in the
“.CALCULATE” assignment group:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("CALCULATION_LOOKUP");
var description = ".CALCULATE";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the date range to be calculated


var startDate = new WFSDate(2016, 3, 16);
var endDate = new WFSDate(2016, 9, 30);

// Calculate the timesheets


api.calculateTimesheetsForGroup(group, startDate, endDate);

Assigning Schedule Templates


The Timesheet Operations API can be used to assign a schedule template to an assignment or to a set of
assignments. Schedule templates assigned in this fashion behave the same as schedule templates applied
using a manager override on the Assign Schedules screen, and will appear as overrides if viewed on that
screen.

Example 1: Assigning templates based on a match condition:


This example demonstrates assigning the schedule template “TEMPLATE_A” to all assignments with a
department ID value of “DEPT1”:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the assignments to apply the template to


var condition = new MatchCondition("asgnmt", "department_id",
MatchOperator.EQUALS, "DEPT1");

// Define the date that the template assignment is effective on


var asOfDate = WFSDate.today();

// Define the template to be assigned


var template = "TEMPLATE_A";

// Assign the template to the assignments


api.assignScheduleTemplate(condition, asOfDate, template);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 469


WT&A API Specifications 18.3 Timesheet Operations API

Example 2: Assigning templates to an assignment group:


This example demonstrates assigning the schedule template “TEMPLATE_B” to all assignments in the
assignment group “.TEMPLATE_ASSIGNMENTS”:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("TEMPLATE_LOOKUP");
var description = ".TEMPLATE_ASSIGNMENTS";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the date that the template assignment is effective on


var asOfDate = WFSDate.today();

// Define the template to be assigned


var template = "TEMPLATE_B";

// Assign the template to the assignments


api.assignScheduleTemplateForGroup(group, asOfDate, template);

Assigning Schedule Cycles


The Timesheet Operations API can be used to assign a schedule cycle to an assignment or to a set of
assignments. Schedule cycles assigned in this fashion behave the same as schedule cycles applied using a
manager override on the Assign Schedules screen, and will appear as overrides if viewed on that screen.

Example 1: Assigning cycles based on a match condition:


This example demonstrates assigning the schedule cycle “CYCLE_A” to all assignments with a department ID
value of “DEPT4”. The assignments will all start at the third occurrence of the schedule template
“TEMPLATE_A” within that schedule cycle:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the assignments to apply the template to


var condition = new MatchCondition("asgnmt", "department_id",
MatchOperator.EQUALS, "DEPT4");

// Define the date that the cycle assignment is effective on


var asOfDate = WFSDate.today();

// Define the cycle to be assigned


var cycle = "CYCLE_A";

// Lookup all occurrences of the template TEMPLATE_A in the cycle


var template = "TEMPLATE_A";
var sequenceNumbers = api.getSequenceNumbers(cycle, template);

// Use the third occurrence of the template as the starting point for the cycle

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 470


WT&A API Specifications 18.3 Timesheet Operations API

var sequenceNumber = sequenceNumbers[2];

// Assign the schedule cycle to the assignments


api.assignScheduleCycle(condition, asOfDate, cycle, sequenceNumber);

Example 2: Assigning cycles to an assignment group:


This example demonstrates assigning the schedule cycle “CYCLE_B” to all assignments in the assignment
group “.CYCLE_ASSIGNMENTS”. The assignments will all start at the first occurrence of the schedule
template “TEMPLATE_B” within that schedule cycle:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("CYCLE_LOOKUP");
var description = ".CYCLE_ASSIGNMENTS";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the date that the cycle assignment is effective on


var asOfDate = WFSDate.today();

// Define the cycle to be assigned


var cycle = "CYCLE_B";

// Lookup all occurrences of the template TEMPLATE_B in the cycle


var template = "TEMPLATE_B";
var sequenceNumbers = api.getSequenceNumbers(cycle, template);

// Use the first occurrence of the template as the starting point for the cycle
var sequenceNumber = sequenceNumbers[0];

// Assign the schedule cycle to the assignments


api.assignScheduleCycleForGroup(group, asOfDate, cycle, sequenceNumber);

Reinitializing Previously-Assigned Schedules


Schedule templates and cycles are only copied to the SCHEDULE_DETAIL table at the time they are applied or
when a period is first initialized. After that, any changes that happen to the policy definitions for the
schedule templates or cycles (e.g. adding additional details to a day, changing the template order) are not
automatically reflected in the schedules for assignments that are assigned to those templates or cycles.
This can often lead to schedules that do not accurately reflect the source templates or cycles, particularly if
the configuration is calculating future periods (as this would “lock in” the schedule data for those periods at a
much earlier point in time). The Timesheet Operations API includes support for reinitializing the schedule
data for an assignment or set of assignments so that the schedule information correctly reflects the latest
policy information as defined by the assigned schedule template or schedule cycle.

Example 1: Reinitializing schedules based on a match condition:


The following example demonstrates how to reinitialize the schedules for all assignments in the “EXEMPT”
Policy Profile:

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 471


WT&A API Specifications 18.3 Timesheet Operations API

includeDistributedPolicy("TIMESHEET_OPERATIONS_API");

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define the condition to select the assignments to reinitialize


var condition = new MatchCondition("asgnmt", "policy_profile",
MatchOperator.EQUALS, "EXEMPT");

// Define a date within the period to be reinitialized


var asOfDate = WFSDate.today();

// Reinitialize the schedules for the assignments


api.reinitializeSchedule(condition, asOfDate, true);

Example 2: Reinitializing schedules based on an assignment group:


The following example demonstrates how to reinitialize the schedules for all assignments in the
“.REINITIALIZE” assignment group:
includeDistributedPolicy("TIMESHEET_OPERATIONS_API");
includeDistributedPolicy("ASSIGNMENT_GROUP_API");

// Use the assignment group API to select an assignment group


var agAPI = new AssignmentGroupAPI("REINITIALIZATION");
var description = ".REINITIALIZE";
var group = agAPI.findAssignmentGroup(description);

// Create an instance of the API


var api = new TimesheetOpsAPI();

// Define a date within the period to reinitialize


var asOfDate = WFSDate.today();

// Reinitialize the schedules for the assignments


api.reinitializeScheduleForGroup(group, asOfDate, true);

Troubleshooting
The job log of the script using the Timesheet Operations API will contain information messages and, in the
case of problems, any error messages generated during processing. This job log should be reviewed if there
are any problems encountered while using the API.

Error Message Problem Solution


Input parameter A method was called on the API Review all method calls using the API
PARAMETER not provided that requires a certain parameter, to ensure that they include all of the
but no value was provided for that required parameters, and that the
parameter. values being supplied for those
parameters are all non-null.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 472


WT&A API Specifications 18.3 Timesheet Operations API

No Matching assignment The match condition specified for a Ensure that the match condition being
found for Amend operation call to amendTimesheet did not used correctly identifies a single
match any assignments. assignment that should be amended,
and then ensure that the
employee/assignment data for the
matching assignment is correct.
No Matching assignment(s) The match condition specified for a Ensure that the match condition being
found for Calculate current call to calculateCurrentPeriod did used correctly identifies one or more
period operation not match any assignments assignments that should be calculated,
and then ensure that the
employee/assignment data for the
matching assignments is correct.
Could not find any An assignment group ID was Ensure that the expected assignment
assignment group with specified for one of the methods group exists and that the right ID for
display_id GROUP_ID that operates on an assignment that group is being used by the script.
group, but no group with that ID
currently exists.
No Matching assignment The match condition specified for a Ensure that the match condition being
found for Get Timesheet call to getTimesheetStatus did not used correctly identifies a single
Status operation match any assignments assignment, and then sure that the
employee/assignment data for the
matching assignment is correct.
No Matching assignment(s) The match condition specified for a Ensure that the match condition being
found for Assign Schedule call to assignScheduleCycle did not used correctly identifies one or more
operation match any assignments, or the assignments that should have the
assignment group specified for a schedule cycle assigned, and then
call to ensure that the employee/assignment
assignScheduleCycleForGroup was data for the matching assignments is
empty correct, or verify that the correct
assignment group is specified and
contains a non-zero number of
assignments.
More than one assignment The match condition specified for a Ensure that the match condition being
exist that match the call to amendTimesheet matched used correctly identifies a single
condition more than one assignment. assignment that should be amended.
No Matching assignment(s) The match condition specified for a Ensure that the match condition being
found for Approve operation call to approveTimesheet didn’t used correctly identifies one or more
match any assignments or the assignments that should be approved
assignment group specified for a or verify that the correct assignment
call to approveTimesheetForGroup group is specified and contains a non-
was empty zero number of assignments.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 473


WT&A API Specifications 18.3 Timesheet Operations API

Assignment An editable timesheet does not Ensure that the correct assignment
ASSIGNMENT_ID does not already exist for the period and date are being used, and then
have editable timesheet containing the specified date. This make sure that the period being
defined for date: DATE generally means an approval event approved has been calculated before
is trying to be applied to a period attempting to apply the approval
that has never been calculated event.
before.
No Matching assignment(s) The match condition specified for a Ensure that the match condition being
found for Unapprove call to unapproveTimesheet didn’t used correctly identifies one or more
operation match any assignments or the assignments that should be
assignment group specified for a unapproved or verify that the correct
call to assignment group is specified and
unapproveTimesheetForGroup was contains a non-zero number of
empty assignments.
No Matching assignment(s) The match condition specified for a Ensure that the match condition being
found for Calculate call to calculateTimesheets didn’t used correctly identifies one or more
timesheet operation match any assignments or the assignments that should be calculated
assignment group specified for a or verify that the correct assignment
call to group is specified and contains a non-
calculateTimesheetsForGroup was zero number of assignments.
empty
Approval Level must be An approval level was specified to Ensure that an approval level between
greater than 0 and less than be applied that was either negative 0 and 98 is specified when approving
99 or greater than 98, which are not timesheets.
valid approval level values
Timesheet for assignment An approval level was specified that Ensure that the approval level being
ASSIGNMENT_ID has is lower than the existing approval provided is the same or higher than
already a higher approval level when approving a timesheet the approval level that already exists
level of value: for the timesheet when approving it.
APPROVAL_LEVEL
Timesheet for assignment An attempt was made to unapprove Ensure that the timesheets being
ASSIGNMENT_ID is already a timesheet that is currently in a unapproved are open for editing and
locked for date DATE locked state not currently in a locked state before
unapproving.
Timesheet for assignment An attempt was made to Ensure that the timesheets being
ASSIGNMENT_ID is already unapproved a timesheet that is unapproved are open for editing
closed for date DATE currently in a closed state before unapproving.
SEQUENCE_NUMBER is not The sequence number specified is Ensure that the sequence number
a valid sequence number for either too low or too high for the specified matches a valid sequence
Schedule cycle CYCLE_ID specified schedule cycle based on number for the schedule cycle.
the number of templates that
currently make up that cycle

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 474


WT&A API Specifications 18.3 Timesheet Operations API

No Matching assignment(s) The match condition specified for a


Ensure that the match condition being
found for Assign Template call to assignScheduleTemplate used correctly identifies one or more
operation didn’t match any assignments or assignments that should have the
the assignment group specified fortemplate assigned or verify that the
a call to correct assignment group is specified
assignScheduleTemplateForGroup and contains a non-zero number of
was empty assignments.
No Matching assignment(s) The match condition specified for a
Ensure that the match condition being
found for Reinitialize call to reinitializeSchedule didn’t
used correctly identifies one or more
schedule operation match any assignments or the assignments that should be
assignment group specified for a reinitialized or verify that the correct
call to reinitializeScheduleForGroup
assignment group is specified and
was empty contains a non-zero number of
assignments.
To suppress the error and continue
processing for other assignments, pass
continueOnError as true (third
parameter).
Change of prior open This warning message indicates that To allow retroactive changes when
periods is not permitted for your policy profile does not allow invoking assignScheduleTemplate,
policy profile x. Only current schedules from prior periods to be mark the “Allow retroactive schedule
and future periods will be modified. changes” checkbox in the Schedule
updated. Please update the Handling Policy for the policy profile
Schedule Handling Policy to mentioned in the warning message.
allow retroactive schedule
changes if prior open
schedules must be updated.
Table 91: Timesheet Operations API typical error messages, root problems, and solutions

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The Timesheet Operations API consists of the following component(s):
1. The MatchCondition, which defines a condition to select employee, assignment, or user records
a. This MatchCondition makes use of a MatchOperator which defines a comparison operation
to use in a condition for matching a specified value against the employee/assignment/user
data.
2. The TimesheetOpsAPI, which provides assorted methods for manipulating timesheets and retrieving
information about their status.
The following is a summary of the available methods and common uses:

MatchOperator
EQUALS
Only data where the value in the specified field exactly matches the indicated value will be matched by the
condition

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 475


WT&A API Specifications 18.3 Timesheet Operations API

NOT_EQUALS
Only data where the value in the specified field does not match the indicated value will be matched by the
condition

GREATER_THAN
Only data where the value in the specified field is greater than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “3” is greater than “20”.

GREATER_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is greater than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “3” is greater than
“20”.

LESS_THAN
Only data where the value in the specified field is less than the indicated value will be matched by the
condition. For string fields this is applied lexicographically, meaning that “20” is less than “3”.

LESS_THAN_OR_EQUALS
Only data where the value in the specified field exactly matches or is less than the indicated value will be
matched by the condition. For string fields this is applied lexicographically, meaning that “20” is less than
“3”.

IN
Only data where the value in the specified field exactly matches one of the values in the indicated array of
values will be matched by the condition.

NOT_IN
Only data where the value in the specified field does not match any of the values in the indicated array of
values will be matched by the condition.

LIKE
Only data where the value in the specified field matches the pattern defined by the indicated value will be
matched by the condition.

NOT_LIKE
Only data where the value in the specified field does not match the pattern defined by the indicated value
will be matched by the condition.

BETWEEN
Only data where the value in the specified falls between the two values defined by the indicated array of
values (inclusive of the two endpoints) will be matched by the condition. For string fields this is applied
lexicographically, meaning that “5” is between “37” and “62”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 476


WT&A API Specifications 18.3 Timesheet Operations API

MatchCondition
MatchCondition(table, field, operator, values, isNotOperator)
Creates a new MatchCondition for the indicated table/field combination that matches against the specified
value(s) using the indicated MatchOperator.
If the MatchOperator specified is IN or NOT_IN, then values is expected to be an array of all the different
values to be evaluated by the “in” operation. If the MatchOperator specified is BETWEEN, then values is
expected to be an array containing two values: the starting point and ending point of the range to be
evaluated by the “between” operation. For all other MatchOperators, values is expected to be a single
value.
The isNotOperator controls whether the results of the MatchCondition should be negated. If this is set to
true, then a MatchCondition that normally evaluates to false will instead evaluate to true, and a
MatchCondition that normally evaluates to true will instead evaluate to false. This allows for conditions that
don’t have an explicit MatchOperator defined, such as “not between”, to be defined.

and(condition)
Modifies the MatchCondition to return only the intersection of its original condition and the specified
condition.

or(condition)
Modifies the MatchCondition to return the union of its original condition and the specified condition.

TimesheetOpsAPI
Creates a new instance of the Timesheet Operations API

approveTimesheet(condition, asOfDate, approver, approvalLevel)


Approves the timesheets for the period containing the indicated as-of date for assignments matching the
specified condition. The specified approver and approval level will be used for all of the approvals that are
applied.

approveTimesheetForGroup(displayId, asOfDate, approver, approvalLevel)


Approves the timesheets for the period containing the indicated as-of date for all assignments belonging to
the assignment group with the specified display ID. The specified approver and approval level will be used
for all of the approvals that are applied.

unapproveTimesheet(condition, asOfDate)
Unapproves the timesheets for the period containing the indicated as-of date for assignments matching the
specified condition by resetting their approval level to zero.

unapproveTimesheetForGroup(displayId, asOfDate)
Unapproves the timesheets for the period containing the indicated as-of date for all assignments belonging
to the assignment group with the specified display ID by resetting their approval level to zero.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 477


WT&A API Specifications 18.3 Timesheet Operations API

amendTimesheet(condition, asOfDate)
Creates a new amended version of the timesheet for the period containing the indicated as-of date for the
assignment matching the specified condition.

calculateTimesheets(condition, startDate, endDate)


Calculates all timesheets that overlap with the indicated date range for all assignments matching the
specified condition.

calculateTimesheetsForGroup(displayId, startDate, endDate)


Calculates all timesheets that overlap with the indicated date range for all assignments belonging to the
assignment group with the specified display ID.

calculateCurrentPeriod(condition)
Calculates the current period timesheet for all assignments matching the specified condition.

calculateCurrentPeriodForGroup(displayId)
Calculates the current period timesheet for all assignments belonging to the assignment group with the
specified display ID.

getTimesheetStatus(condition, asOfDate)
Returns information about the timesheet for the period containing the indicated as-of date for the
assignment matching the specified condition. Information returned includes:
▪ approvalLevel: the current overall approval level of the timesheet
▪ mgrApprovalLevel: the current manager approval level of the timesheet
▪ isEmployeeApproved: true if the employee submitted the timesheet, false if not
▪ isAmendment: true if the timesheet is an amended timesheet, false if not
▪ currentState: one of OPEN, APPROVED, LOCKED, or CLOSED, based on the approval level

getCurrentPeriodDates(policyProfile)
Returns the beginning and ending dates of the current period for specified Policy Profile (string)

getPeriodDates(policyProfile, asOfDate)
Returns the beginning and ending dates for the period containing the indicated as-of date for the specified
Policy Profile. Information returned includes:
▪ ppBegin: the beginning date of the period containing the as-of date
▪ ppEnd: the ending date of the period containing the as-of date

assignScheduleTemplate(condition, asOfDate, template)


Assigns the specified schedule template, effective as of the indicated as-of date, to all assignments matching
the specified condition.

assignScheduleTemplateForGroup(displayId, asOfDate, template)


Assigns the specified schedule template, effective as of the indicated as-of date, to all assignments belonging
to the assignment group with the specified display ID.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 478


WT&A API Specifications 18.3 Timesheet Operations API

assignScheduleCycle(condition, asOfDate, cycle, sequenceNo)


Assigns the specified schedule cycle, effective as of the indicated as-of date, to all assignments matching the
specified condition. The assignments will begin at the indicated sequence number within the schedule cycle.

assignScheduleCycleForGroup(displayId, asOfDate, cycle, sequenceNo)


Assigns the specified schedule cycle, effective as of the indicated as-of date, to all assignments belonging to
the assignment group with the specified display ID. The assignments will begin at the indicated sequence
number within the schedule cycle.

getSequenceNumbers(cycle, template)
Returns an array of all of the different sequence numbers within the indicated schedule cycle where the
specified schedule template occurs. If the template does not occur within the schedule cycle, the array
returned will be empty.

reinitializeSchedule(condition, asOfDate, continueOnError)


Reapplies the currently-assigned schedule template or schedule cycle as an override for all assignments
matching the specified condition for the period containing the indicated as-of date. This will cause the
schedule information to be updated to reflect the latest policy information for the schedule templates/cycles.
To suppress the errors and continue processing for other assignments, pass continueOnError as true.

reinitializeScheduleForGroup(displayId, asOfDate, continueOnError)


Reapplies the currently-assigned schedule template or schedule cycle as an override for all assignments
belonging to the assignment group with the specified display ID for the period containing the indicated as-of
date. This will cause the schedule information to be updated to reflect the latest policy information for the
schedule templates/cycles. To suppress the errors and continue processing for other assignments, pass
continueOnError as true.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 479


WT&A API Specifications 18.3 Timesheet Output API

Timesheet Output API


Overview and Capabilities
The Timesheet Output API lets you access timesheet data from tables in a conforming manner.

Pre-requisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The TIMESHEET_OUTPUT_API Distributed JavaScript Library.
• The TimesheetOutputAPI Java class.
• The API_UTIL Distributed JavaScript Library.

Setup
No setup is necessary for the Timesheet Output API. The distributed library is automatically available in
WT&A.

Use Cases
Getting TSO data using Match Condition for assignment;
Version: INITIAL
Timesheet is not locked.
includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: true,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
startDate: new WFSDate(2008, 04, 21),
endDate: new WFSDate(2008, 04, 25),
version:"INITIAL"
};
var result = api.getTimesheetOutputListBetweenWorkDates(queryParms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 480


WT&A API Specifications 18.3 Timesheet Output API

Getting TSO data using Match Condition for assignment;


Version: OPEN
Timesheet is not locked.
includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: true,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:"OPEN"
};
var result = api.getTimesheetOutputListForPeriodAsOf(queryParms);

Getting TSO data using Match Condition for assignment;


Version: LATEST
Timesheet is locked.
includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: false,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:"LATEST"
};
var result = api.getTimesheetOutputListForPeriodAsOf(queryParms);

Getting TSO data using Match Condition for assignment;


Version: LATEST_CLOSED
Timesheet is locked.
includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: false,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 481


WT&A API Specifications 18.3 Timesheet Output API

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version:" LATEST_CLOSED"
};
var result = api.getTimesheetOutputListForPeriodAsOf(queryParms);

Getting TSO data for specific PayCodeSet


includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: true,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version: "LATEST_CLOSED",
payCodeSet: "INT_5184_TEST"
};
var result = api.getTimesheetOutputListForPeriodAsOf(queryParms);

Getting TSO data with specific TSO fields using


TimesheetMatchCondition
Filter down TSO records using TimesheetMatchCondition with specific TSO fields.
includeDistributedPolicy("TIMESHEET_OUTPUT_API");
var constructParms = {
runCalculate: true,
minApprovalLevel: 0
};
var api = new TimesheetOutputAPI(constructParms);

var matchConditionParam = {
table: TimesheetMatchTable.TIME_SHEET_OUTPUT,
field: "HOURS",
operator: MatchOperator.EQUALS,
values: ["3"]
};
var queryParms = {
matchCondition: new MatchCondition(MatchTable.ASGNMT, "ASGNMT", MatchOperator.EQUALS,
"1215736324"),
asgnmtEffDate: new WFSDate(2010, 05, 29),
asOfDate: new WFSDate(2008, 04, 26),
version: "LATEST_CLOSED",
payCodeSet: "INT_5184_TEST",
timesheetMatchCondition: new TimesheetMatchCondition(matchConditionParam)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 482


WT&A API Specifications 18.3 Timesheet Output API

};
var result = api.getTimesheetOutputListForPeriodAsOf(queryParms);

Troubleshooting
The job log of the script using the Timesheet Output API will include informational messages, and in the case
of problems, error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.
Error Message Problem Solution
Invalid Pay Code Set provided The API will throw an error if the Pass a valid PayCodeSet.
name of PayCodeSet is not valid.
Version invalid The API will throw an error if the Pass a valid version from the
version is not valid. following: OPEN, LATEST,
LATEST_CLOSED, INITIAL.

API Reference
Knowledge of the JavaScript programming is necessary to best make use of this section.

getTimesheetOutputListForPeriodAsOf ()
Performs a lookup on TSO table using provided match condition and returns matching rows as
ReadOnlyScriptables for the period the provided effective date is in. Takes an object as parameter, having the
following fields:
Parameter Description
matchCondition The condition to select the assignment. Condition can be from EMPLOYEE,
EMPLOYEE_MASTER, ASGNMT and/or ASGNMT_MASTER table.
asgnmtEffDate The effective date to use for the retrieval of the assignment record.
asOfDate The date to retrieve the period of timesheet.
version The version of time sheet for which to retrieve the TSO records. The 4
versions are INITIAL, LATEST, LATEST_CLOSED, OPEN.
payCodeSet (optional) The pay codes for which to retrieve the TSO records. If a payCodeSet is passed
containing zero paycodes then it will return zero records.
timesheetMatchCondition
The TimesheetMatchCondition for TSO table to put additional filter criteria.
(optional)

getTimesheetOutputListBetweenWorkDates ()
Performs a lookup on TSO table using provided match condition and returns matching rows as
ReadOnlyScriptables between the provided dates. Takes an object as parameter, having the following fields:
Parameter Description
matchCondition The condition to select the assignment. Condition can be from EMPLOYEE,
EMPLOYEE_MASTER, ASGNMT and/or ASGNMT_MASTER table.
asgnmtEffDate The effective date to use for the retrieval of the assignment record.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 483


WT&A API Specifications 18.3 Timesheet Output API

startDate The start date to use for calculation of timesheets.


endDate The end date to use for calculation of timesheets.
version The version of timesheet for which to retrieve the TSO records. The four
versions are INITIAL, LATEST, LATEST_CLOSED, OPEN.
payCodeSet (optional) The pay codes for which to retrieve the TSO records. If a payCodeSet is passed
containing zero paycodes then it will return zero records.
timesheetMatchCondition
The TimesheetMatchCondition for TSO table to put additional filter criteria.
(optional)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 484


WT&A API Specifications 18.3 XML Reader API

XML Reader API


Overview and capabilities
The XML Reader API lets you access records in an XML file and iterate through them using a ResultSet
interface.

Prerequisites
To use this API, you should know the following:

• Basic JavaScript coding

Components
The components of the XML Reader API are as follows:

• The XML_READER_API Distributed JavaScript library

Setup
No setup is necessary for the Xml Reader API. The distributed library is automatically available within
WT&A.

Use cases
Read a flat XML File into an XMLResultSet
// including the distributed API
includeDistributedPolicy('XML_READER_API');
// creating parameters object
var parameters = {"filePath":
"workforce/RegTests/ParserValidation/xmlreaderwriterapi_expected.xml", "fieldsAsAttributes":
true}
var xr = new XMLFlatFileReader(parameters);
// looping through all the records in XML
while (xr.next()) {
log.info(xr.getString("name"));
}

Read an irregular XML File into an XmlScriptable


// including the distributed API
includeDistributedPolicy('XML_READER_API');
// creating variable to store file path
Var filePath = "interface/incoming/somefile.xml"
// creating parameters object
var xmlScriptable = XMLReader.parseFromFile(filePath);
// access the data from the xmlScriptable (which serves as a root node)
// it may have additional nested xmlScriptables depending on the data in file

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 485


WT&A API Specifications 18.3 XML Reader API

var children = xmlScriptable.getValue(); // this can either have a string, or a list of xml
scriptables
children[0].getValue(); // and so on, until you reach the leaf node
xmlScriptable.getNamespaceIUri()

Troubleshooting
The job log of the script using the XML Reader API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.

Error Message Problem Solution


XML Parse error The XML is probably not well Make sure the XML is well formed.
formed.

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The XML Reader API consists of one public initializer component:
o XMLFlatFileReader. It contains the following public methods:
▪ next()
▪ getString(“fieldname”)
o XMLReader. It contains the following public static methods:
▪ parseFromFile

XMLFlatFileReader (filePath: string) -> XMLFlatFileReader


Creates a new instance of the XML File Reader API with the provided file path (that contains flat xml data)
and returns the instance that can be queried for the data.

next()
Sets the cursor to the next record in XMLReader object and returns true. Returns false if there is no next row.

getString(fieldName: string) -> string


Returns the value of the provided fieldname as string in current record. Throws an internal exception if
field does not exist.

XMLReader.parseFromFile(filePath: string) -> XmlScriptable


Returns an XML Scriptable parsed from the file.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 486


WT&A API Specifications 18.3 XML Writer API

XML Writer API


Overview and capabilities
The XML Writer API lets you write an XML flat file using a list of JS Objects. It also allows you to write an
irregular XML file nested to n-levels by using an XmlScriptable as input.

Prerequisites
To use this API, you should know the following:

• Basic JavaScript coding

Components
The components of the XML Writer API are as follows:

• The XML_WRITER_API Distributed JavaScript library

Setup
No setup is necessary for the XML Writer API. The distributed library is automatically available within
WT&A.

Use cases
Create and write a hierarchy of XmlScriptables into an XML File
// include distributed API
includeDistributedPolicy('XML_WRITER_API');
var filePath = "workforce/RegTests/ParserValidation/xmlreaderwriterapi_generated.xml";

// creating root node


var rootNode = new XmlScriptable("employees");
rootNode.setAttribute("xmlns", "https://workforcesoftware.com/schema/fake");
rootNode.setAttribute("xmlns:fns", "https://workforcesoftware.com/schema/fake1");

// creating an employee (1)


var employeeNode1 = new XmlScriptable("employee");
employeeNode1.setAttribute("name", "John");
employeeNode1.setAttribute("team", "interfaces");

// creating a nested element for the value of employee (1)


var employeeNode1Child = new XmlScriptable("nestedelement");
employeeNode1Child.setValue("nested element value");

// setting nested element as child of employee 1


employeeNode1.setValue("testing");
employeeNode1.addChild(employeeNode1Child);

// creating another employee (2)

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 487


WT&A API Specifications 18.3 XML Writer API

var employeeNode2 = new XmlScriptable("fns:employee");


employeeNode2.setAttribute("name", "Smith");
employeeNode2.setAttribute("contractual", "true");
employeeNode2.setValue("No nesting here");

// setting children for root node


rootNode.addChild(employeeNode1);
rootNode.addChild(employeeNode2);

// writing to file
XMLWriterAPI.writeXmlScriptable(rootNode, filePath);

Create and write a hierarchy of XmlScriptables into an encrypted XML


File
// include distributed API
includeDistributedPolicy('XML_WRITER_API');
var filePath = "workforce/RegTests/ParserValidation/xmlreaderwriterapi_generated.xml";
var alias = "foo";

// creating root node


var rootNode = new XmlScriptable("employees");
rootNode.setAttribute("xmlns", "https://workforcesoftware.com/schema/fake");
rootNode.setAttribute("xmlns:fns", "https://workforcesoftware.com/schema/fake1");

// creating an employee (1)


var employeeNode1 = new XmlScriptable("employee");
employeeNode1.setAttribute("name", "John");
employeeNode1.setAttribute("team", "interfaces");

// creating a nested element for the value of employee (1)


var employeeNode1Child = new XmlScriptable("nestedelement");
employeeNode1Child.setValue("nested element value");

// setting nested element as child of employee 1


employeeNode1.setValue("testing");
employeeNode1.addChild(employeeNode1Child);

// creating another employee (2)


var employeeNode2 = new XmlScriptable("fns:employee");
employeeNode2.setAttribute("name", "Smith");
employeeNode2.setAttribute("contractual", "true");
employeeNode2.setValue("No nesting here");

// setting children for root node


rootNode.addChild(employeeNode1);
rootNode.addChild(employeeNode2);

// writing to file
XMLWriterAPI.writeXmlScriptableEncrypted(rootNode, filePath, alias);

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 488


WT&A API Specifications 18.3 XML Writer API

Troubleshooting
The job log of the script using the XML Writer API will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.
Error Message Problem Solution
java.lang.IllegalArgumentExc No encryption alias is provided in Provide a valid encryption alias
eption: No encryption alias the method
provided writeXmlScriptableEncrypted
com.workforcesoftware.Util. An invalid alias is provided in the Provide a valid encryption alias
pgp.NoPublicKeyFound: A method
PGP key with the identifier writeXmlScriptableEncrypted
'VeryBadAlias' was not
found in the system

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The XML Writer API does not need to be initialized. It consists of the following component(s):
1. writeXmlScriptable(xmlScriptable: XmlScriptable, filePath: string, encoding: string), which writes the
provided xml scriptable object’s string representation to the provided filePath.
2. writeXmlScriptableEncrypted(xmlScriptable: XmlScriptable, filePath: string, encryptionAlias: string,
encoding: string), which writes the provided xml scriptable object’s string representation to the
provided filePath, and encrypting it to the provided alias.
3. XmlScriptable, which is a representation of a single XML Node/Element. It may or may not contain
other XmlScriptables as children (just like a normal xml node would). It can be initialized from
anywhere in JS using the following:
var varName = new XmlSriptable(“scriptableName”);

The following is a summary of the available methods and common uses:

addChild(XmlScriptable) -> Void


Adds a xml scriptable as child to this. This will remove any inner text if present.

getNodeName() -> String


Returns the name of the node for this object.

setValue(String) -> Void


Sets the value (inner content) of this scriptable as the provided string.

getValue() -> String


Returns the value or an array of XmlScriptables (whichever is applicable).

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 489


WT&A API Specifications 18.3 XML Writer API

toXmlString(indent: Boolean) -> String


Returns the string representation of this.

setAttribute(name: String, value: String) -> Void


Sets the value of the attribute with parameters provided. Will replace if an attribute with same name exists.

getAttribute(name: String) -> String


Returns the value of the attribute name if present. Otherwise returns an empty string.

getNamespace() -> String


Returns the namespace prefix if present. Null otherwise.

getNamespaceUri() -> String


Returns the namespace URI.

setNamespace (prefix: String, uri: String) -> Void


Sets/Changes the namespace prefix and Uri. If prefix provided is empty string (i.e. “”), it will remove the pre-
existing prefix from node. If Uri is not provided, it will search for the pre-existing Uri. If found, it will set the
prefix; If not found, it will throw exception that “prefix is not bound”.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 490


WT&A API Specifications 18.3 Appendix: API_UTIL

Appendix: API_UTIL
Overview and Capabilities
The API_UTIL provides different types of utilities common to multiple APIs that can be used in scripts, such as
String, Date, Database, Log, and EDAI (EmpCenter Data Access Interface).

Note: This document provides information only on the EDAI component of API_UTIL. For additional
information about API_UTIL, contact your WorkForce Software representative.

Prerequisites
To use this API, you should be familiar with the following functionality:
• Basic JavaScript coding

Components
This API consists of the following component(s):
• The API_UTIL distributed JavaScript Library

Setup
No setup is necessary for the API_UTIL. The distributed library is automatically available in WorkForce Time
and Attendance.

Use Cases
Access and modify timesheet slices
These script excerpts demonstrate how the filter can be applied to the list of timesheet slices to get specific
slices and then how to modify them if needed.

Example 1(a): Fetch and update timesheet slices


//This script is an example of inside calculation stage.
includeDistributedPolicy("API_UTIL");

// get timesheet slices


var timesheetSlices = timesheet.getSlices();

//create filter for specific slice(s)


var dayFilter = EDAIUtil.createTimeSheetDetailSplitFilter(
function(timesheetDetailSplit) {
return timesheetDetailSplit.work_dt.toString() == day.toString() ;
}
);

//Once you have list of slices then filter can applied to get filtered slices.
var daySlices = timesheetSlices.filter(dayFilter);

// Lets extract the day timesheet slice


var daySlice = daySlices[0];

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 491


WT&A API Specifications 18.3 Appendix: API_UTIL

if (daySlice != null) {
//update this timesheet slice
var copiedDaySlice = daySlice.copy();
copiedDaySlice.start_dttm = copiedDaySlice.start_dttm.addHours(1);
copiedDaySlice.end_dttm = copiedDaySlice.end_dttm.addHours(1.5);
copiedDaySlice.hours = 4.5;

timesheet.updateSlice(copiedDaySlice);
}

Example 1(b): Fetch and update timesheet slices


//This script is an example of inside calculation stage.
includeDistributedPolicy("API_UTIL");

// get timesheet slices


var timesheetSlices = timesheet.getSlices();

//create filter for specific slice(s)


var dayFilter = EDAIUtil.createTimeSheetDetailSplitFilter(
function(timesheetDetailSplit) {
return timesheetDetailSplit.work_dt.toString() == day.toString() ;
}
);

//Once you have list of slices then filter can applied to get filtered slices.
var daySlices = timesheetSlices.filter(dayFilter);

//create transformer to update slices


var sliceTransformer = EDAIUtil.createTimeSheetDetailSplitTransformer(
function(timesheetDetailSplit) {
timesheetDetailSplit.start_dttm = timesheetDetailSplit.start_dttm.addHours(1);
timesheetDetailSplit.end_dttm = timesheetDetailSplit.end_dttm.addHours(1);
}
);

var copiedDaySlices = daySlice.copy();


copiedDaySlices. Update(sliceTransformer);
timesheet.updateSlices(copiedDaySlices);
}

Access and modify schedule slices


These script excerpts demonstrate how the filter can be applied to the list of schedule slices to get specific
slices and then how to modify them if needed.

Example 2(a): Fetch and update schedule slices


//This script is an example of inside calculation stage.
includeDistributedPolicy("API_UTIL");

// get schedule slices


var schedule = period.getSchedule();
var scheduleSlices = schedule.getSlices();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 492


WT&A API Specifications 18.3 Appendix: API_UTIL

//create filter for specific slice(s)


var scheduleSlicesFilter = EDAIUtil.createScheduleDetailFilter(
function(scheduleDetail) {
return scheduleDetail.work_dt.toString() == day.toString() ;
}
);
//Once you have list of slices then filter can applied to get filtered slices.
var filteredScheduleSlices= scheduleSlices.filter(scheduleSlicesFilter);

// Lets extract the day schedule slice


var scheduleSlice = filteredScheduleSlices [0];

if (scheduleSlice != null) {
//update this schedule slice
var copiedScheduleSlice = scheduleSlice.copy();
copiedScheduleSlice.start_dttm = copiedScheduleSlice.start_dttm.addHours(1);
copiedScheduleSlice.end_dttm = copiedScheduleSlice.end_dttm.addHours(1.5);
copiedScheduleSlice.hours = 4.5;

schedule.updateSlice(copiedScheduleSlice);
}

Example 2(b): Fetch and update schedule slices


//This script is an example of inside calculation stage.
includeDistributedPolicy("API_UTIL");

// get schedule slices


var schedule = period.getSchedule();
var scheduleSlices = schedule.getSlices();

//create filter for specific slice(s)


var scheduleSlicesFilter = EDAIUtil.createScheduleDetailFilter(
function(scheduleDetail) {
return scheduleDetail.work_dt.toString() == day.toString() ;
}
);

//Once you have list of slices then filter can applied to get filtered slices.
var filteredScheduleSlices= scheduleSlices.filter(scheduleSlicesFilter);

//create transformer to update slices


var sliceTransformer = EDAIUtil.createScheduleDetailTransformer (
function(scheduleDetail) {
scheduleDetail.start_dttm = scheduleDetail.start_dttm.addHours(1);
scheduleDetail.end_dttm = scheduleDetail.end_dttm.addHours(1);
}
);

var copiedDaySlices = filteredScheduleSlices.copy();


copiedDaySlices. Update(sliceTransformer);
schedule.updateSlices(copiedDaySlices);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 493


WT&A API Specifications 18.3 Appendix: API_UTIL

Fetch filtered Timesheet Output records


This script excerpt demonstrates how the filter can be applied to the list of timeSheetOutput (TSO) records to
get specific records.
includeDistributedPolicy("API_UTIL");

// get timeSheetOutput records


var timeSheetOutputs = period.getTimesheetOutputs();

//create filter for specific record(s) of timesheetOutput


var timeSheetOutputFilter = EDAIUtil.createTimeSheetOutputFilter(
function(timeSheetOutput) {
return timeSheetOutput.work_dt.toString() == day.toString() && timeSheetOutput.pay_code
== "REG ;
}
);

//once you have list of records then filter can be applied to get filtered records
var filteredtimeSheetOutputs= timeSheetOutputs.filter(timeSheetOutputFilter);

Fetch filtered Assignment records


This script excerpt demonstrates how the filter can be applied to the list of assignment records to get specific
records.

includeDistributedPolicy("API_UTIL");

//get assignments records


var assignments = assignmentManager.findCurrentAssignments("a.asgnmt = " + getAssigmnent());

//create filter for assignments


var assignmentFilter = EDAIUtil.createAssignmentFilter(
function(assignment) {
return assignment.status_code1='A' && assignment.soft_terminated = 'F" ;
}
);

//once you have list of records then filter can be applied to get filtered assignments
var filteredAssignments = assignments.filter(assignmentFilter);

function getAssigmnent() {
// logic to get actual assignment relevant to this script
return "12318723";
}

Troubleshooting
The job log of the script using the API UTIL will include informational messages, and in the case of problems,
error messages. This job log should be reviewed if there are problems using the API.
The following table lists some common error messages, their causes, and the solution.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 494


WT&A API Specifications 18.3 Appendix: API_UTIL

Error Message Cause Solution


n/a

API Reference
Knowledge of JavaScript programming is necessary to best make use of this section.
The API_UTIL consists many components. This document only provides details on the following
component:
• The EDAIUtil, which defines EDAI utility functions for creating conforming transformation and
filter implementations.

Note: For information about other components of API_UTIL, contact your WorkForce Software representative.

EDAIUtil
The EmpCenter Data Access Interface (EDAI) is used to access employee, assignment, and timesheet data.
The following functions are available in EDAIUtil.

createAssignmentFilter (keepFunction)
Creates assignment filter implementation with the specified keep function.
Parameter Description
keepFunction Function that specifies assignment records from being filtered

createScheduleDetailFilter (keepFunction)
Creates schedule_detail filter implementation with the specified keep function.
Parameter Description
keepFunction Function that specifies schedule_detail records from being filtered

createTimeSheetDetailSplitFilter (keepFunction)
Creates time_sheet_detail_split filter implementation with the specified keep function.
Parameter Description
keepFunction Function that specifies time_sheet_detail_split records from being filtered

createTimeSheetOutputFilter (keepFunction)
Creates time_sheet_output filter implementation with the specified keep function.
Parameter Description
keepFunction Function that specifies time_sheet_output records from being filtered

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 495


WT&A API Specifications 18.3 Appendix: API_UTIL

createScheduleDetailTransformer (updateFunction)
Creates schedule_detail transformation implementation with the specified update function.
Parameter Description
updateFunction Function that specifies logic to update schedule_detail records

createTimeSheetDetailSplitTransformer (updateFunction)
Creates time_sheet_detail_split transformation implementation with the specified update function.
Parameter Description
updateFunction Function that specifies logic to update time_sheet_detail_split records

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 496


WT&A API Specifications 18.3 Appendix: JS_UTIL

Appendix: JS_UTIL
Overview and Capabilities
The JS_UTIL API provides different types of lookup tables and utility methods that can be used in scripts. You
can use the lookup table and effective-dated lookup table objects to hold data as key/value pairs. The
following types of utilities are also available:
• convert date/time
• get/convert time-zone
• trimming or padding a string
• rounding a number
• validating/renaming files
• archiving files

Note: JS_UTIL is the latest version of this API that should be used in scripts. Previously, it was named
EMPLOYEE_IMPORT_UTIL. Although EMPLOYEE_IMPORT_UTIL has been retained for backward
compatibility purposes, its code has been moved into JS_UTIL, and it now simply includes the JS_UTIL
distributed library.

Prerequisites
To use this API, you should know:
• Basic JavaScript coding.

Components
This API consists of the following component(s):
• JS_UTIL distributed JavaScript Library

Setup
No setup is necessary for JS_UTIL API. The distributed library is automatically available within WorkForce
Time and Attendance.

Use Cases
LookupTable
The following example shows how to use the LookupTable.
includeDistributedPolicy("JS_UTIL");

// creating LookupTable object


var map = new LookupTable();

// setting key value pairs in LookupTable


map.set("E00001", "Employee 01");
map.set("E00002", "Employee 02");
map.set("E00003", "Employee 03");

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 497


WT&A API Specifications 18.3 Appendix: JS_UTIL

// validating if LookupTable contains a key


map.containsKey("E00001"); //returns true

// fetching the value mapped against the key in LookupTable


map.get("E00001"); //returns "Employee 01"

var keyArray = ["E00004","E00005"];


var valueArray = ["Employee 04","Employee 05"]

// mapping the keys in key against the objects in valueArray


map.setAll(keyArray, valueArray);

// fetching the set of key contained in the LookupTable


map.getKeyArray(); //returns and array containing "E00001","E00002","E00003","E00004","E00005"

// clearing the key value pairs contained in the LookupTable


map.clear();

EffDatedLookupTable
The following example shows how to use the EffDatedLookupTable.
includeDistributedPolicy("JS_UTIL");

// creating EffDatedLookupTable object


var map = new EffDatedLookupTable();

var emp_01 = "E0001";


var emp_02 = "E0002";
var asgnmt_01 = "A0001";
var asgnmt_02 = "A0002";
var startDate1 = "2017-02-01";
var endDate1 = "2017-06-30";
var startDate2 = "2017-08-01";
var endDate2 = "2017-12-31";

// setting effective dated key-value pairs in EffDatedLookupTable


map.set(emp_01, asgnmt_01, startDate1, endDate1);
map.set(emp_01, asgnmt_02, startDate2, endDate2);
map.set(emp_02, asgnmt_01, startDate1, endDate1);
map.set(emp_02, asgnmt_02, startDate2, endDate2);

// validating if EffDatedLookupTable contains a key for asOfDate


map.containsKey(emp_01, "2017-03-15"); // returns true
map.containsKey(emp_02, "2017-07-24"); // returns false

// fetching the value mapped against the key for asOfDate in EffDatedLookupTable
var value = map.get(emp_01, "2017-02-01"); // returns asgnmt_01
if (value == asgnmt_01) {
log.info("Assignment: " + asgnmt_01 + " for Employee: " + emp_01 );
}
else {
log.error("Unexpected asgnmt value: " + value);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 498


WT&A API Specifications 18.3 Appendix: JS_UTIL

value = map.get(emp_02, "2018-01-01"); // returns null


value = map.get("E0003", "2018-01-01"); // returns null

Utility Functions
The following example shows how to use the different utility functions defined in JS_UTIL.
includeDistributedPolicy("JS_UTIL");

// Returns WDate object of specified date string


var date = convertWDate("2018-01-01", "yyyy-MM-dd");
log.info("WDate: " + date);

// Returns WDateTime object of specified date-time string


var dateTime = convertWDateTime("2018-01-02 10:20:30", "yyyy-MM-dd HH:mm:ss");
log.info("WDateTime: " + dateTime);

// Returns WTime object of specified time string


var time = convertWTime("04:35:08", "HH:mm:ss");
log.info("WTime: " + time);

// Returns source date-time in local time zone


var localTime = convertDateTimeZone(convertWDateTime("2018-01-15 11:22:33"), "MST", "EST");
log.info("Local time: " + localTime);

// Returns first timezone name for Java for specified offset


var offset = 3;
var daylightSavingTime = false;
var timeZone = getTZName(offset, daylightSavingTime);

if (timeZone != "Africa/Addis_Ababa") {
log.error("Incorrect timezone name: " + timeZone);
}

var string = " WorkForceSoftware " ;


// trims white spaces
var trimmed = Trim(string);
// trims white spaces at the left of string
var leftTrimmed = LTrim(string);
// trims white spaces at the right of string
var rightTrimmed = RTrim(leftTrimmed);

if (trimmed == rightTrimmed) { // returns true


log.info("String trims successfully as " + trimmed);
}

// Returns maximum value


var maxValue = max(10, 20, 30);
// Returns minimum value
var minValue = min(30, 40, 50);

if (maxValue == minValue) { // returns true


log.info("Both values are equal: " + maxValue);
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 499


WT&A API Specifications 18.3 Appendix: JS_UTIL

log.info("Must be True: " + isBlank(""));


log.info("Must be False: " + isBlank("WFS"));

var value = null;


if (isUndefined(value)) { // returns true as value is null
value = "string";
if(!isUndefined(value)){
log.info("Value has been defined as " + value);
}
}

var validStatuses = ["A", "L", "T"];


var status = "A";
// Checks if status value contains in the specified array
if (inArray(validStatuses, status)) { // returns true
log.info(status + " is a valid status");
}

// Rounds number to two decimal precision


var num = roundNumber(4.5678, 2);
if (num == 4.57) { // returns true
log.info("Precised number: " + num);
}

// Rounds specified number to nearest quarter value


var number = 17.3;
var roundedNumber = roundNumberToQuarter(number);
log.info(number + " rounded to nearest quarter as " + roundedNumber);

The following example provides a way of creating and using connection scriptable with the help of a method
available in JS_UTIL distributed library.
includeDistributedPolicy("JS_UTIL");

// The policy name of the "DB Connection Info" policy to the source data
var DB_CONNECTION_POLICY = "EMPCENTER_CONNECTION_1";
var connectionScriptable;
var sql;

try {
// Returns a connection scriptable to the corresponding database
connectionScriptable = createSourceConnection(DB_CONNECTION_POLICY);
var query = "Select TOP(10) DISPLAY_EMPLOYEE, FIRST_NAME from EMPLOYEE";
// Creates a Sql scriptable
sql = new Sql(connectionScriptable, query);
while (sql.next()) {
log.info("EmpId: " + sql.DISPLAY_EMPLOYEE + " First Name: " + sql.FIRST_NAME);
}
}
catch (e) {
log.error("Error while execution: " + e);
}
finally {
if (connectionScriptable) {
connectionScriptable.closeStatements();
connectionScriptable.close();
}

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 500


WT&A API Specifications 18.3 Appendix: JS_UTIL

if (sql) {
sql.close();
}
}

The following example shows how to use methods related to file processing.
includeDistributedPolicy("JS_UTIL");

var filePath = "workforce/interface/incoming/";


var fileName = "data.csv";

// Creates a file object


var file = new java.io.File(filePath + fileName);
// Checks if specified file exists in specified directory
if (!fileExists(file)) {
log.error("File not found");
}

// Returns a list of all the files/directories in the specified folder


var fileList = listItemsInDirectory(filePath, true);
log.info("Directory " + filePath + " contains " + fileList.length + " item(s).");
for (var i = 0; i < fileList.length; i++) {
log.info((i + 1) + " " + fileList[i]);
}

// Archives the specified file in the specified folder. The original file will no longer
exist.
var archivedPath = filePath + "Archive/";
if (archiveFile(file, archivedPath)) {
log.info("Successfully archived " + file.getName() + " in " + archivedPath);
}
else {
log.info("Archiving failed for " + file.getName());
}

// Creates two different file objects for comparison of their modification date.
var file1 = new java.io.File(filePath + "File1.csv");
var file2 = new java.io.File(filePath + "File2.csv");
var difference = compareFilesByModificationDate(file1, file2);

if (difference < 0) {
log.info(file2.getName() + " is modified later.");
}
else if (difference > 0) {
log.info(file1.getName() + " is modified later.");
}
else {
log.info("Same modification date.");
}

// Renames specified file and returns boolean to represent success or failure.


var newFileName = "renamed_" + file1.getName();

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 501


WT&A API Specifications 18.3 Appendix: JS_UTIL

if (renameFile(file1, filePath, newFileName)) {


log.info("Successfully renamed as " + newFileName);
}
else {
log.info("File renaming failed for " + file1.getName());
}

Troubleshooting
The job log of the script using JS_UTIL distributed library will contain information messages and, in the case of
problems, any error messages generated during processing. This job log should be reviewed if there are any
problems encountered while using the API.
Error Message Cause Solution
Directory <directoryPath> does {IOException} If file denoted by Provide valid directory path
not exist abstract directory path in
listItemsInDirectory does not
exist or is not a directory
Unable to rename file: file Unable to rename file: file Provide appropriate file name and
doesn’t exist doesn’t exist directory path
Unparseable WDate: <date> ParseException Provide appropriate date string in
convertWDate
Can’t parse <date> in these ParseException Provide appropriate date and
formats format string in
convertWDateTime/convertWTime

API Reference
LookupTable
The LookupTable is a map which contains key value pairs and has the following methods available:

set(key, object)
Sets the value of object against the key in the lookup table, object can be an instance of an array, string or
primitive.
Parameter Description
key Object or String
object Object or String

containsKey(key)
Checks the lookup table to determine if it contains the key and returns a Boolean.
Parameter Description
key Object or String

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 502


WT&A API Specifications 18.3 Appendix: JS_UTIL

get(key)
Returns the object mapped against the key in the lookup table.
Parameter Description
key Object or String

setAll(keys, objects)
Sets the value of objects against the array of keys provided in the lookup table. If the object is an instance of
an array, then each key in the keys array is mapped against the value in the objects array of the same index.
Parameter Description
keys Array
objects Array, Object or String

getKeyArray()
Returns a list of keys contained in the lookup table.

clear()
Clears the data contained in the lookup table.

EffDatedLookupTable
The EffDatedLookupTable has the following methods available:

set(key, value, startDate, endDate)


Sets an effective dated record in the EffDatedLookupTable against the key.
Parameter Description
key Object or String
value Object or String
startDate String or WFSDate
endDate String or WFSDate

get(key, asOfDate)
Returns a value mapped against the key on asOfDate in the EffDatedLookupTable, or null if no key is found.
Parameter Description
key Object or String
asOfDate String or WFSDate

containsKey(key, asOfDate)
Returns a Boolean true if the EffDatedLookupTable contains the key on asOfDate, false otherwise.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 503


WT&A API Specifications 18.3 Appendix: JS_UTIL

Parameter Description
key Object or String
asOfDate String or WFSDate

Utility Functions
isValidISO4217CurrencyCode(currencyCode)
Returns as Boolean after validating the string currencyCode is a valid ISO 4217 3-letter currency code.
Parameter Description
currencyCode Currency code to be validated

convertWDate(date, format)
Converts and returns the date string into the WDate object, using the specified date format string. If the date
format is not provided, then the standard date format yyyy-MM-dd is used.
Parameter Description
date Date string to be converted
format String date format

convertWDateTime(date, format)
Converts and returns the date-time string into the WDateTime object, using the specified date-time format
string. If the date-time format is not provided, then the standard date format yyyy-MM-dd HH:mm:ss is used.
Parameter Description
date Date-time string to be converted
format String date-time format

convertWTime(date, format)
Converts and returns the time string into the WTime object, using the specified time format string. If the time
format is not provided, then the standard date format HH:mm:ss is used.
Parameter Description
date Time string to be converted
format String time format

convertDateTimeZone(sourceDateTime, source, local)


Converts and returns the sourceDateTime WDateTime object converted to local time zone.
Parameter Description
sourceDateTime WDateTime object to convert
source Policy ID of source timezone

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 504


WT&A API Specifications 18.3 Appendix: JS_UTIL

Parameter Description
local Policy ID of local timezone

getTZName(offset, useDST)
Gets first timezone name for Java for the given timezone offset measured in hours.
Parameter Description
offset Size of offset in hours
useDST Boolean value to represent whether Daylight Savings Time
should be considered

LTrim(s)
Trims white space that is left-justified.
Parameter Description
s String to be trimmed

RTrim(s)
Trims white space that is right-justified.
Parameter Description
s String to be trimmed

Trim(s)
Trims white space present in the string.
Parameter Description
s String to be trimmed

padStringLeft(str, padChar, length)


Pads the string str from left by adding characters padChar to the start of the string. Returns a padded string
of the specified length.
Parameter Description
str String to be padded
padChar Character that is to be added to the string
length Final length of string after padding

padStringRight(str, padChar, length)


Pads and return the string str from right by adding characters padChar to the end of the string. Returns a
padded string of the specified length.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 505


WT&A API Specifications 18.3 Appendix: JS_UTIL

Parameter Description
str String to be padded
padChar Character that is to be added to the string
length Final length of string after padding

max()
Returns the greatest of the specified values, eliminating null elements from consideration.

min()
Returns the least of the specified values, eliminating null elements from consideration.

isBlank(str)
Returns a Boolean value after validating if the specified string is empty or null.
Parameter Description
str String to be evaluated

isUndefined(arg)
Returns true if arg is undefined or null, false otherwise.
Parameter Description
arg Object to be evaluated

inArray(array, value)
Returns true if value is present in the provided array, false otherwise.
Parameter Description
array Array
value Object of specified array type

createSourceConnection(id)
Creates and returns a Database Connection Info policy.
Parameter Description
id Policy ID of Db_connection_info policy

roundNumber(num, dec)
Returns a number after rounding using the provided number to specify the decimal precision.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 506


WT&A API Specifications 18.3 Appendix: JS_UTIL

Parameter Description
num Number to round
dec Decimal precision number

roundNumberToQuarter(value)
Rounds the provided value to nearest quarter value.
Parameter Description
value Number to round

roundToArbitraryInterval(value, interval, roundUpPointInInterval)


Rounds the provided value asymmetrically, specifying the point in the interval at which to start rounding up.
Parameter Description
value Number to round
interval Value will be rounded to a number evenly divisible by this
interval
roundUpPointInInterval Fraction of total to round up from, the default value is an
interval divided by 2.0

fileExists(file)
Returns true if a file exists and is a file (i.e., not a directory). False otherwise.
Parameter Description
file java.io.File object

listItemsInDirectory(directoryPath, includeDirectories)
Returns a list of all the files/directories contained in the specified folder.
Parameter Description
directoryPath Path to the directory whose files will be listed
includeDirectories If this Boolean flag is set to true, directories inside the
specified directory will be included. If set to false, only files
will be returned.

archiveFile(file, archivePath)
Archives the specified file. Archiving means that the timestamp is appended to the beginning of the file
name. Then the file is moved to the location specified by the archivePath. The original file will no longer exist.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 507


WT&A API Specifications 18.3 Appendix: JS_UTIL

Parameter Description
file java.io.File object to archive
archivePath The directory the file should be archived in

renameFile(file, newFilePath, newFileName)


Renames the specified file and returns a Boolean to represent success or failure.
Parameter Description
file java.io.File object
newFilePath New file path
newFileName New file name to rename

compareFilesByModificationDate(file1, file2)
Compares specified file objects based on their last modification date. Returns 1 if file1 is modified later than
file2, -1 if file1 is modified earlier, or 0 if both files have the same modification date-time. Both files are
java.io.File objects.

getCurrentLoggedInUser()
Using current run time context, returns current logged-in user.

WorkForce Software | info@workforcesoftware.com | workforcesoftware.com 508

You might also like