Monday, 23 March 2026

Loading Oracle Cloud Time and Labor Time Entries via REST API using PL/SQL (UTL_HTTP)

Loading Oracle Cloud Time and Labor Time Entries via REST API using PL/SQL (UTL_HTTP)

Oracle Cloud HCM Time and Labor integrations are commonly built using Python, OCI Integration, or other middleware tools. However, there are situations where a lightweight, database-driven approach is useful, especially for rapid prototyping, controlled batch processing, or small-volume integrations.

In this example, the REST API is invoked directly from a local Oracle Express Edition database running on a personal system. The solution uses a custom staging table, PL/SQL procedures, UTL_HTTP, and an Oracle wallet for secure HTTPS communication. The example focuses on loading time entries through the REST API flow and not a separate time event integration model.

Important Note: This REST API supports creation of complete time entries that include both start time and stop time (or measured duration). It leverages the same configuration used for standard time entry in Oracle Time and Labor and does not require any additional setup.

However, if the business requirement involves capturing partial time events (such as only start time or only stop time), a different REST endpoint (/hcmRestApi/resources/11.13.18.05/timeRecordEventRequests/) must be used. This approach requires additional configurations, including event definitions and device-related attributes.

This approach is particularly useful for

  • One time – time entries load for payroll parallel run testing, time parallel run testing
  • Rapid prototyping
  • Small-scale integrations
  • Controlled batch processing from staging tables
  • Enter the time entries in custom application/UI and then load into OTL with more controlled way.

Solution Overview

The design follows a simple but effective pattern:

  1. Insert time entry records into a custom staging table.
  2. Read unprocessed rows from the staging table.
  3. Construct the REST payload in PL/SQL.
  4. Call Oracle Cloud HCM REST API using UTL_HTTP.
  5. Capture response details and update the processing status.

Step 1: Create the staging table

The staging table stores inbound time entry data and maintains processing metadata such as status, request identifiers, API response, and error message.

CREATE TABLE xx_time_entry_stg (
    id                     NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    reporter_id            VARCHAR2(100)   NOT NULL,
    start_time             VARCHAR2(50)    NOT NULL,
    stop_time              VARCHAR2(50)    NOT NULL,
    payroll_time_type      VARCHAR2(200)   NOT NULL,
    comment_txt            VARCHAR2(1000),
    process_status         VARCHAR2(30)    DEFAULT 'NEW',
    request_id             NUMBER,
    event_id               NUMBER,
    response_clob          CLOB,
    error_message          VARCHAR2(4000),
    created_on             DATE            DEFAULT SYSDATE,
    updated_on             DATE
);

This structure provides a strong foundation for traceability and troubleshooting:

  • process_status tracks whether a row is NEW, PROCESSING, SUCCESS, or ERROR.
  • response_clob stores the full REST API response for audit and debugging.
  • error_message stores a summarized failure reason.
  • request_id and event_id help connect the database record to the HCM transaction.

Step 2: Insert sample time entry data

A sample record can be inserted into the staging table before processing.In this example we are using 4 days’ time entries for 1 employee.

INSERT INTO xx_time_entry_stg (
    reporter_id,
    start_time,
    stop_time,
    payroll_time_type,
    comment_txt
) VALUES (
    '1129',
    '2026-03-16T08:00:00.000-04:00',
    '2026-03-16T17:00:00.000-04:00',
    'XX Regular Hours US',
    'Loaded from custom table-1'
);
INSERT INTO xx_time_entry_stg (
    reporter_id,
    start_time,
    stop_time,
    payroll_time_type,
    comment_txt
) VALUES (
    '1129',
    '2026-03-17T08:00:00.000-04:00',
    '2026-03-17T17:00:00.000-04:00',
    'XX Regular Hours US',
    'Loaded from custom table-1'
);
INSERT INTO xx_time_entry_stg (
    reporter_id,
    start_time,
    stop_time,
    payroll_time_type,
    comment_txt
) VALUES (
    '1129',
    '2026-03-18T08:00:00.000-04:00',
    '2026-03-18T17:00:00.000-04:00',
    'XX Regular Hours US',
    'Loaded from custom table-1'
);
INSERT INTO xx_time_entry_stg (
    reporter_id,
    start_time,
    stop_time,
    payroll_time_type,
    comment_txt
) VALUES (
    '1129',
    '2026-03-19T08:00:00.000-04:00',
    '2026-03-19T17:00:00.000-04:00',
    'XX Regular Hours US',
    'Loaded from custom table-1'
);
COMMIT;

The timestamp values are provided in ISO 8601 format with timezone offset, which is important for Oracle Cloud HCM REST requests.

Step 3: Build the PL/SQL procedure that loads one time entry

The main procedure reads a staging row, constructs the JSON payload, invokes the REST API, reads the response, and updates the row status.

CREATE OR REPLACE PROCEDURE xx_load_one_time_entry (
    p_id                IN NUMBER,
    p_host              IN VARCHAR2,
    p_username          IN VARCHAR2,
    p_password          IN VARCHAR2,
    p_wallet_path       IN VARCHAR2,
    p_wallet_password   IN VARCHAR2
) AS
    l_url              VARCHAR2(2000);
    l_req              UTL_HTTP.req;
    l_resp             UTL_HTTP.resp;
    l_buffer           VARCHAR2(32767);
    l_response_clob    CLOB;
    l_payload          CLOB;

    l_reporter_id      xx_time_entry_stg.reporter_id%TYPE;
    l_start_time       xx_time_entry_stg.start_time%TYPE;
    l_stop_time        xx_time_entry_stg.stop_time%TYPE;
    l_payroll_type     xx_time_entry_stg.payroll_time_type%TYPE;
    l_comment_txt      xx_time_entry_stg.comment_txt%TYPE;

    l_request_id       NUMBER;
    l_event_id         NUMBER;
    l_event_status     VARCHAR2(100);
    l_status_code      PLS_INTEGER;
    l_reason_phrase    VARCHAR2(256);
    l_error_message    VARCHAR2(4000);
BEGIN
    SELECT reporter_id,
           start_time,
           stop_time,
           payroll_time_type,
           NVL(comment_txt, 'Loaded from custom table')
    INTO   l_reporter_id,
           l_start_time,
           l_stop_time,
           l_payroll_type,
           l_comment_txt
    FROM   xx_time_entry_stg
    WHERE  id = p_id
    FOR UPDATE;

    UPDATE xx_time_entry_stg
       SET process_status = 'PROCESSING',
           updated_on     = SYSDATE,
           error_message  = NULL
     WHERE id = p_id;

    l_url := 'https://' || p_host || '/hcmRestApi/resources/11.13.18.05/timeRecordEventRequests';

    l_payload :=
           '{'
        || '\"processInline\":\"Y\",'
        || '\"processMode\":\"TIME_SAVE\",'
        || '\"timeRecordEvent\":['
        ||   '{'
        ||     '\"startTime\":\"' || REPLACE(REPLACE(l_start_time, '\', '\\'), '\"', '\\\"') || '\",'
        ||     '\"stopTime\":\"' || REPLACE(REPLACE(l_stop_time, '\', '\\'), '\"', '\\\"') || '\",'
        ||     '\"reporterIdType\":\"PERSON\",'
        ||     '\"reporterId\":\"' || REPLACE(REPLACE(l_reporter_id, '\', '\\'), '\"', '\\\"') || '\",'
        ||     '\"comment\":\"' || REPLACE(REPLACE(l_comment_txt, '\', '\\'), '\"', '\\\"') || '\",'
        ||     '\"operationType\":\"ADD\",'
        ||     '\"timeRecordEventAttribute\":['
        ||       '{'
        ||         '\"attributeName\":\"PayrollTimeType\",'
        ||         '\"attributeValue\":\"' || REPLACE(REPLACE(l_payroll_type, '\', '\\'), '\"', '\\\"') || '\"'
        ||       '}'
        ||     ']'
        ||   '}'
        || ']'
        || '}';

    UTL_HTTP.set_detailed_excp_support(TRUE);
    UTL_HTTP.set_response_error_check(FALSE);
    UTL_HTTP.set_wallet(p_wallet_path, p_wallet_password);

    l_req := UTL_HTTP.begin_request(l_url, 'POST', 'HTTP/1.1');

    UTL_HTTP.set_authentication(l_req, p_username, p_password, 'Basic', FALSE);
    UTL_HTTP.set_header(l_req, 'Content-Type', 'application/json');
    UTL_HTTP.set_header(l_req, 'Accept', 'application/json');
    UTL_HTTP.set_header(l_req, 'Content-Length', TO_CHAR(DBMS_LOB.getlength(l_payload)));
    UTL_HTTP.write_text(l_req, l_payload);

    l_resp := UTL_HTTP.get_response(l_req);
    l_status_code   := l_resp.status_code;
    l_reason_phrase := l_resp.reason_phrase;

    DBMS_LOB.createtemporary(l_response_clob, TRUE);

    BEGIN
        LOOP
            UTL_HTTP.read_text(l_resp, l_buffer, 32767);
            DBMS_LOB.writeappend(l_response_clob, LENGTH(l_buffer), l_buffer);
        END LOOP;
    EXCEPTION
        WHEN UTL_HTTP.end_of_body THEN
            NULL;
    END;

    UTL_HTTP.end_response(l_resp);

    BEGIN
        SELECT JSON_VALUE(l_response_clob, '$.timeRecordEventRequestId' RETURNING NUMBER),
               JSON_VALUE(l_response_clob, '$.timeRecordEvent[0].timeRecordEventId' RETURNING NUMBER),
               JSON_VALUE(l_response_clob, '$.timeRecordEvent[0].eventStatus' RETURNING VARCHAR2(100))
          INTO l_request_id, l_event_id, l_event_status
          FROM dual;
    EXCEPTION
        WHEN OTHERS THEN
            l_request_id   := NULL;
            l_event_id     := NULL;
            l_event_status := NULL;
    END;

    IF l_status_code BETWEEN 200 AND 299
       AND l_event_status = 'COMPLETE'
    THEN
        UPDATE xx_time_entry_stg
           SET process_status = 'SUCCESS',
               request_id     = l_request_id,
               event_id       = l_event_id,
               response_clob  = l_response_clob,
               updated_on     = SYSDATE,
               error_message  = NULL
         WHERE id = p_id;
    ELSE
        l_error_message :=
            SUBSTR(
                'HTTP ' || l_status_code || ' ' || l_reason_phrase || ' | ' ||
                DBMS_LOB.SUBSTR(l_response_clob, 3000, 1),
                1,
                4000
            );

        UPDATE xx_time_entry_stg
           SET process_status = 'ERROR',
               request_id     = l_request_id,
               event_id       = l_event_id,
               response_clob  = l_response_clob,
               updated_on     = SYSDATE,
               error_message  = l_error_message
         WHERE id = p_id;
    END IF;

    COMMIT;

EXCEPTION
    WHEN OTHERS THEN
        BEGIN
            UTL_HTTP.end_response(l_resp);
        EXCEPTION
            WHEN OTHERS THEN
                NULL;
        END;

        l_error_message :=
            SUBSTR(
                SQLERRM || ' | ' || UTL_HTTP.get_detailed_sqlerrm,
                1,
                4000
            );

        UPDATE xx_time_entry_stg
           SET process_status = 'ERROR',
               updated_on     = SYSDATE,
               error_message  = l_error_message
         WHERE id = p_id;

        COMMIT;
        RAISE;
END;
/

How the procedure works

  • It selects a specific staging row by ID and locks it using FOR UPDATE.
  • It updates the row to PROCESSING before the API call starts.
  • It constructs the JSON payload dynamically in PL/SQL.
  • It uses UTL_HTTP to send the HTTPS POST request.
  • It reads the REST response into a CLOB.
  • It parses the response using JSON_VALUE.
  • It marks the row as SUCCESS only when the HTTP status is successful and the returned event status is COMPLETE.
  • Otherwise, it stores the failure details and marks the record as ERROR.

REST payload design

The payload uses processInline = "Y" and processMode = "TIME_SAVE". This is important because the integration is being used to save a time entry through the REST API processing flow. You can change processMode = "TIME_SUBMIT"or "TIME_ENTER" depending on your requirement. The payload also passes:

  • startTime - start time of the time entry
  • stopTime - stop time of the time entry
  • reporterIdType - PERSON
  • reporterId - Person Number
  • comment - any custom optional comment
  • operationType - ADD
  • PayrollTimeType - Time type defined in the layout component set(element name not the display name)

This makes the example practical for a common Time and Labor requirement where the integration needs to create a time entry with a payroll time type.

Important implementation details

1. Wallet configuration for HTTPS

The call uses UTL_HTTP.set_wallet so the local Oracle database can trust the SSL certificate presented by Oracle Cloud. Without a properly configured wallet, HTTPS requests typically fail.

2. Content-Length header

The code explicitly sets the Content-Length header using DBMS_LOB.getlength(l_payload). This is a very important detail because missing this header can result in HTTP 411 Length Required errors.

3. JSON escaping

The code carefully escapes backslashes and double quotes when building the payload. This is important because comments and other text values can break the JSON structure if they are not escaped correctly.

4. Detailed exception support

UTL_HTTP.set_detailed_excp_support(TRUE) makes troubleshooting easier by exposing more detailed network and HTTP diagnostics.

5. Response parsing

The API response is stored in a CLOB and parsed for:

  • timeRecordEventRequestId
  • timeRecordEventId
  • eventStatus

This gives the solution both technical traceability and business-level visibility into the outcome.

Step 4: Batch procedure for multiple entries

To process all new staging rows, a batch procedure loops through records with status NEW and calls the single-row loader for each entry.

CREATE OR REPLACE PROCEDURE xx_load_time_entries_batch (
    p_host              IN VARCHAR2,
    p_username          IN VARCHAR2,
    p_password          IN VARCHAR2,
    p_wallet_path       IN VARCHAR2,
    p_wallet_password   IN VARCHAR2
) AS
BEGIN
    FOR r IN (
        SELECT id
        FROM xx_time_entry_stg
        WHERE process_status = 'NEW'
        ORDER BY id
    ) LOOP
        BEGIN
            xx_load_one_time_entry(
                p_id              => r.id,
                p_host            => p_host,
                p_username        => p_username,
                p_password        => p_password,
                p_wallet_path     => p_wallet_path,
                p_wallet_password => p_wallet_password
            );
        EXCEPTION
            WHEN OTHERS THEN
                NULL;
        END;
    END LOOP;
END;
/

This design keeps the processing model simple. Each row is handled independently, which makes error isolation easier. One failed row does not stop the remaining rows from being attempted.

Step 5: Execute the batch load

The batch procedure can be executed with the Oracle Cloud host, credentials, and wallet details.

BEGIN
    xx_load_time_entries_batch(
        p_host            => 'your-test-instance.fa.us6.oraclecloud.com',
        p_username        => 'your_username',
        p_password        => 'your_password',
        p_wallet_path     => 'file:c:\wallet',
        p_wallet_password => 'your_wallet_password'
    );
END;
/

After execution, the staging table can be queried to confirm whether each record completed successfully or failed with an error.

SELECT *
FROM xx_time_entry_stg
ORDER BY id;

Testing the solution

A good test cycle for this approach is:

  1. Record inserted in staging table
  2. Run the batch procedure
  3. Status transitions:
    • NEW → PROCESSING → SUCCESS / ERROR
  4. Response captured in response_clob
  5. Review the failed records if any
  6. Validate time entries from the front-end(You don’t have to run any job/any scheduled process to see the entries in the front-end)



This gives a clean and repeatable way to validate the integration end to end.

Common issues and troubleshooting

Issue Possible Cause Typical Fix
ORA-29273 HTTP request failed Check wallet setup, ACLs, hostname, SSL trust, and network connectivity
ORA-28759 Failure to open wallet file Verify wallet path, database service account permissions, and wallet contents
HTTP 411 Length Required Missing Content-Length header Explicitly set Content-Length before writing the payload
Invalid JSON or API rejection Malformed payload or unescaped text Escape values correctly and validate the payload structure

Strengths of this pattern

  • Simple and easy to understand
  • Fully database-driven
  • Good audit trail through staging and stored responses
  • Useful for low-volume or controlled integrations
  • No separate middleware is required for the basic flow

Practical limitations

  • It is not the best pattern for very high transaction volumes.
  • Basic authentication may not be the preferred production-grade option in all environments.
  • Sequential row-by-row processing can become a bottleneck at scale.
  • Credential handling must be hardened before production use.

Recommendations for production hardening

  • Move credentials out of anonymous execution blocks and store them securely.
  • Add a retry strategy for transient failures.
  • Introduce better logging for request payloads, response codes, and execution timestamps.
  • Add validation logic before calling the REST API.
  • Consider parallel processing for larger data volumes.
  • Review whether OAuth-based authentication is required in the target environment.

Key takeaway

This example shows how Oracle Database can act as a lightweight integration layer for Oracle Cloud HCM Time and Labor. By combining a staging table, PL/SQL, UTL_HTTP, and wallet-based HTTPS configuration, it is possible to load time entries directly from a local Oracle XE environment while still preserving auditability and control.

For teams that want a compact and database-centric integration option, this is a practical pattern worth considering.

Disclaimer

This example is intended for demonstration and learning purposes. Additional controls, security hardening, validation, and operational considerations may be required before adopting the pattern in a production environment.

Wednesday, 18 March 2026

End-to-End Guide to Enterprise Shifts, Work Pattern Types and Work Pattern Template Rules in Oracle HCM

End-to-End Guide to Enterprise Shifts, Work Pattern Types and Work Pattern Template Rules in Oracle HCM

Excerpt:
This article demonstrates how to configure Enterprise Shifts, Work Pattern Types, Work Pattern Templates, and Template Rules in Oracle HCM Cloud. Using a practical example, we assign a work pattern at the Legal Employer level while excluding workers with manual exceptions, and explain how the Process Events job evaluates and applies these rules.

Oracle HCM Cloud Workforce Scheduling provides a structured way to standardize employee schedules across large populations. Instead of assigning schedules manually, organizations can define reusable components and automate assignment using rules.

This blog walks through an end-to-end configuration using:

  • Enterprise Shifts
  • Work Pattern Types
  • Work Pattern Templates
  • Work Pattern Template Rules at the Legal Employer level
  • Process Events job

Business Requirement

All employees under a specific Legal Employer should receive a standard work pattern:

  • 08:00 AM to 05:00 PM - 60 mins unpaid break

However, employees with manual scheduling exceptions must be excluded. For example, employees manually assigned to 01:00 PM to 10:00 PM - 60 mins unpaid break should not be overwritten by the rule-based assignment.

Step 1: Create Enterprise Shifts

Enterprise Shifts act as reusable building blocks for scheduling.

Navigation
My Client Groups > Workforce Scheduling > Shifts
Click the Add button.

Configuration Field 1st Shift 2nd Shift
Shift Name 08:00 AM to 05:00 PM - 60 mins unpaid break 01:00 PM to 10:00 PM - 60 mins unpaid break
Duration 8 8
Work Minutes 0 0
Start Time 08:00 AM 01:00 PM
End Time 05:00 PM 10:00 PM
Unpaid Break Duration 60 Minutes 60 Minutes






Key Insight

  • 9-hour span
  • 8 paid hours after break deduction

Step 2: Create Work Pattern Types

Work Pattern Types define how shifts are structured.

Navigation
Setup and Maintenance > Workforce Scheduling > Work Pattern Types

Configuration Field Values for the 1st Work Pattern Values for the 2nd Work Pattern
Shift Period Type Start and end times Start and end times
Name 08:00 AM to 05:00 PM - 60 mins unpaid break 01:00 PM to 10:00 PM - 60 mins unpaid break
Country United States United States
Status Active Active
Break Name 60 mins unpaid break 60 mins unpaid break
Break Duration 60 Minutes 60 Minutes
Break Type Any time during shift Any time during shift
Nature of Break Unpaid Unpaid






Because this setup uses exact start and end times, a start/end-based work pattern type is the right choice.

Step 3: Create Work Pattern Templates

Templates define recurring schedules that can be assigned to groups.

Navigation
My Client Groups > Workforce Scheduling > Work Pattern Templates

a) Template Name: 08:00 AM to 05:00 PM - 60 mins unpaid break

Work Pattern Type: Fixed Start-End Pattern
Cycle Length: 1 Week

DayShift
Monday08:00 AM to 05:00 PM - 60 mins unpaid break
Tuesday08:00 AM to 05:00 PM - 60 mins unpaid break
Wednesday08:00 AM to 05:00 PM - 60 mins unpaid break
Thursday08:00 AM to 05:00 PM - 60 mins unpaid break
Friday08:00 AM to 05:00 PM - 60 mins unpaid break
SaturdayOff
SundayOff




b) Template Name: 01:00 PM to 10:00 PM - 60 mins unpaid break

Work Pattern Type: Fixed Start-End Pattern
Cycle Length: 1 Week

DayShift
Monday01:00 PM to 10:00 PM - 60 mins unpaid break
Tuesday01:00 PM to 10:00 PM - 60 mins unpaid break
Wednesday01:00 PM to 10:00 PM - 60 mins unpaid break
Thursday01:00 PM to 10:00 PM - 60 mins unpaid break
Friday01:00 PM to 10:00 PM - 60 mins unpaid break
SaturdayOff
SundayOff




Step 4: Define Work Pattern Template Rule

This is where automation happens.

We will create the work pattern template rule for 08:00 AM to 05:00 PM - 60 mins unpaid break.

Navigation
My Client Groups > Workforce Scheduling > Work Pattern Templates > Assign






Example Rule Logic

Include Criteria

  • Legal Employer = ABC Corporation
  • Oracle Work Pattern Source <> 'Manually Assigned'

This rule ensures that all eligible workers under the legal employer receive the standard day pattern, while workers already maintained manually are excluded from automated reassignment.

Step 5: Run Process Events

This is the critical activation step.

Navigation
Tools > Scheduled Processes

Process Name: Process Events

Parameters

  • Effective Date: 3/18/2026
  • Events to Process: Workforce Scheduling


The log files provide details about how many employees were processed and how the rule evaluation was applied.



How Process Events Works

Think of Process Events as the engine that applies your Workforce Scheduling rules.

What it does

  1. Detects HCM changes, such as new hires, transfers, legal employer changes, and assignment updates.
  2. Evaluates template rules by checking legal employer eligibility and excluding manually assigned work patterns.
  3. Generates scheduling assignments by assigning the template to eligible workers and skipping excluded workers.

Currently, Oracle supports multiple Workforce Scheduling events, and Process Events is the process that reacts to those changes and applies the configured logic.

End-to-End Flow Summary

  1. Create shift → 08:00 AM to 05:00 PM
  2. Create pattern type → Start-End based
  3. Create template → Weekly recurring schedule
  4. Define rule → Legal Employer based
  5. Run Process Events → Apply logic

Testing the Solution

Scenario 1: New Hire

  • Legal Employer = ABC
  • No manual exception
  • Run Process Events
  • Expected: work pattern assigned

After Position Change and running Process Events -



Scenario 2: Position Change and Missing Work Pattern

  • Legal Employer = ABC
  • Manual Exception = No
  • Run Process Events
  • Expected: work pattern assigned

Before Position Change -



After Position Change and running Process Events -



Scenario 3: Position Change and Manually Assigned

  • Legal Employer = ABC
  • Manual Exception = Yes
  • Run Process Events
  • Expected: No work pattern change

Before Position Change -



After Position Change and running Process Events -





Scenario 4: Job Change and Existing Work Pattern

  • Legal Employer = ABC
  • Manual Exception = Yes
  • Run Process Events
  • Expected: No work pattern change

Before the position change -



After Position Change and running Process Events -


Troubleshooting

Issue: Template not applied

  • Verify rule criteria.
  • Check worker attributes.
  • Run Process Events.

Issue: New hires not assigned pattern

  • Ensure Process Events is scheduled regularly, such as daily or hourly.

Final Thoughts

A well-designed Workforce Scheduling setup in Oracle HCM Cloud should use Enterprise Shifts as reusable units, Templates for scalability, Rules for automation, and Process Events for execution.

In this example, applying scheduling at the Legal Employer level with controlled exclusions ensures both standardization across the workforce and flexibility for exceptions.

Author Note

This blog reflects a practical implementation pattern for Workforce Scheduling in Oracle HCM Cloud. Always validate configurations in your own environment and align rule design with your organization's data governance strategy.

Sunday, 15 March 2026

Use Case: Managing Different Public Holiday Schedules for Different Segments of the Workforce

Use Case: Managing Different Public Holiday Schedules for Different Segments of the Workforce

Organizations with diverse operational models often require different public holiday schedules for different segments of the workforce. For example, corporate office employees may observe the full set of public holidays, while manufacturing facilities may operate on reduced holiday schedules to maintain production continuity.

Oracle Fusion Cloud HCM 25D Organization Calendar Events enables organizations to manage holidays and organizational events centrally through configurable calendars. However, when implementing this feature for different worker populations, it is important to understand the current design constraints of the feature.

This use case illustrates how an organization can configure separate public holiday calendars for US manufacturing and US non-manufacturing employees. :contentReference[oaicite:0]{index=0}


Business Requirement

A company operates multiple work locations across the United States with two major workforce populations:

1. Non-Manufacturing Employees

  • Corporate offices
  • Administrative staff
  • Sales and support teams

2. Manufacturing Employees

  • Factory workers
  • Production teams
  • Plant operations staff

The organization follows a standard US public holiday calendar for most employees. However, manufacturing plants operate on a modified holiday schedule due to production requirements.

Non-Manufacturing Employees

Corporate employees observe the full US public holiday schedule:

  • New Year’s Day (1/1/2026)
  • MLK Day (1/19/2026)
  • Presidents’ Day (2/26/2026)
  • Memorial Day (5/25/2026)
  • Juneteenth (6/19/2026)
  • Independence Day (7/4/2026)
  • Labor Day (9/7/2026)
  • Veterans Day (11/11/2026)
  • Thanksgiving Day (11/26/2026)
  • Christmas Day (12/25/2026)
  • Winter Break 1 (12/26/2026)
  • Winter Break 2 (12/27/2026)
  • Winter Break 3 (12/28/2026)
  • Winter Break 4 (12/29/2026)
  • Winter Break 5 (12/30/2026)
  • Winter Break 6 (12/31/2026)

Manufacturing Employees

Manufacturing plants observe only a subset of these holidays:

  • New Year’s Day (1/1/2026)
  • MLK Day (1/19/2026)
  • Presidents’ Day (2/26/2026)
  • Memorial Day (5/25/2026)
  • Juneteenth (6/19/2026)
  • Independence Day (7/4/2026)
  • Labor Day (9/7/2026)
  • Veterans Day (11/11/2026)
  • Thanksgiving Day (11/26/2026)
  • Christmas Day (12/25/2026)

Winter Break holidays (12/26/2026 – 12/31/2026) are not observed because the plant continues production during those periods.

The organization therefore requires:

  • A US Corporate Holiday Calendar for non-manufacturing employees
  • A US Manufacturing Holiday Calendar for plant employees

Configuration Approach

To implement this requirement using Organization Calendar Events, the organization configures:

  1. Define Organization Calendar Events
  2. Create Separate Organization Calendars
  3. Create Calendar Rules
  4. Assign Calendars to Workers

Step 1: Define Organization Calendar Events

First, administrators define the public holiday events that will be used across calendars.

Examples include:

  • New Year’s Day
  • MLK Day

Navigation:

Setup and Maintenance → Calendar Events

Create all 16 calendar events as defined earlier.





Important Note:

If you do not see the Redwood page for Calendar Events, enable the following profile option:

ORA_ANC_VBCS_ORG_CAL_EVENT_ENABLED = Y

Navigation:

Setup and Maintenance → Manage Administrator Profile Values

Step 2: Create Separate Holiday Calendars

US Non-Manufacturing Holiday Calendar

This calendar contains the full set of US public holidays observed by corporate employees.

It is assigned to workers in corporate offices and administrative roles through the work location.



US Manufacturing Holiday Calendar

This calendar contains only the holidays applicable to plant operations.

It excludes holidays during which manufacturing plants remain operational.

For example, events such as Winter Break 1 to 6 are omitted.





Step 3: Create Calendar Rules

Calendars are assigned to workers using Calendar Rules.

Worker Population Assigned Calendar
US Corporate Employees US Non-Manufacturing Holiday Calendar
Manufacturing Plant Employees US Manufacturing Holiday Calendar

One or more calendar rules can be created using person and assignment attributes.

Once assigned, workers inherit the events defined in their respective calendar.















Step 4: Assign Calendars to Workers

To ensure that the correct workers are assigned to the appropriate calendars, Oracle Fusion uses the Evaluate Group Membership scheduled process.

This process evaluates the rules associated with each calendar and updates the membership of the underlying HCM Groups.

Because worker eligibility may change due to updates in calendar attributes, the process must run regularly.

It is recommended to schedule the process to run as frequently as worker data changes within the organization.

Scheduling the Evaluate Group Membership Process

Navigation:

Tools → Scheduled Processes

Steps:

  1. Click Schedule New Process
  2. Search for Evaluate Group Membership
  3. Schedule it to run periodically

Running a Targeted Refresh for Calendar Rules

If administrators need to refresh membership for a specific calendar rule:

  • Enter the specific rule name
  • Or search using:
%ANC_CALENDAR_RULES

This lists all calendar rules associated with Organization Calendar Events.





Important Note About Calendar HCM Groups

The HCM Groups used by Organization Calendar Events are maintained internally by the application.

Because of this:

  • These groups cannot be viewed or edited directly from the Define HCM Groups page
  • Membership is controlled automatically by the Evaluate Group Membership process

You can query the membership using SQL:

select 
per.person_number,
ppn.last_name,
ppn.first_name,
grp.group_name,
mem.effective_start_date,
mem.effective_end_date
from hwm_grp_members_f mem,
hwm_grps_vl grp,
per_all_people_f per,
per_person_names_f ppn
where grp.grp_id = mem.grp_id
and per.person_id = mem.member_id
and per.person_id = ppn.person_id
and ppn.name_type = 'GLOBAL'
and trunc(sysdate) between mem.effective_start_date and mem.effective_end_date
and trunc(sysdate) between ppn.effective_start_date and ppn.effective_end_date
and trunc(sysdate) between per.effective_start_date and per.effective_end_date

Testing the Solution

Corporate employees follow the full US public holiday calendar including winter break holidays.




Manufacturing employees follow the plant-specific holiday calendar without winter break holidays.





Business Benefits

  • Maintain Production Continuity
    Manufacturing plants can operate during certain holidays without impacting corporate scheduling.
  • Provide Accurate Workforce Scheduling
    The scheduling engine automatically respects the correct holiday calendar for each worker.
  • Reduce Administrative Effort
    Holiday schedules are managed centrally instead of being manually applied by managers.

Summary

The Organization Calendar Events feature in Oracle Fusion Cloud HCM 25D provides a centralized way to manage holidays and organizational events across different workforce populations.

In this case:

  • Corporate employees follow a US Non-Manufacturing Holiday Calendar
  • Manufacturing employees follow a US Manufacturing Holiday Calendar

Although the feature enables flexible calendar definitions, organizations must design implementations carefully due to the current limitation that calendars can only be defined using Geography or Organization hierarchies.

With proper configuration, the feature provides a scalable solution for managing holiday schedules across diverse operational environments.

Wednesday, 11 March 2026

How to Restrict Global Assignment EFF Values by Employee Legislation in Oracle Fusion HCM

How to Restrict Global Assignment EFF Values by Employee Legislation in Oracle Fusion HCM

In global Oracle Fusion HCM implementations, one of the more common configuration challenges is supporting local business requirements without fragmenting the overall design. A field may be global in nature, but the values available for that field often need to vary by country or legislation.

A typical example is a custom field on the Global Assignment Extensible Flexfield (EFF). The business may want one common field for all employees, but the list of available values should differ depending on whether the worker belongs to the US, India, Canada, Great Britain, or another legislation.

The good news is that Oracle Fusion HCM supports this requirement quite elegantly through configuration. By combining a custom lookup, a table-validated value set, and a Global Assignment EFF segment, you can create a clean, scalable, and metadata-driven solution.

In this article, I’ll walk through a practical design pattern for restricting Assignment EFF values based on employee legislation.

Business Requirement

Let’s assume the business wants to add a custom Assignment EFF field called Eligibility Type. This field should behave differently depending on the employee’s legislation.

For example:

  • an employee with India legislation should see values relevant to India
  • an employee with Great Britain legislation should see UK-specific values
  • an employee with US legislation should see US-specific values
  • some values should remain available to all employees regardless of country

This is a common global design problem: one field, different valid values by legislation.

Instead of creating separate fields or separate contexts by country, we can keep the design centralized and let the value filtering happen dynamically at runtime.

Solution Overview

The solution has three building blocks:

  1. create a custom lookup type to store all possible values
  2. create a table-validated value set that filters those values based on legislation
  3. assign that value set to a Global Assignment EFF segment

The key idea is straightforward: all possible values are maintained in a single lookup, and the Tag field is used to identify country applicability. The value set then reads those values and decides which ones should be displayed based on the employee’s legislation code.

This approach keeps the design simple, maintainable, and easy to extend later.

Step 1: Create a Custom Lookup Type

The first step is to create a custom lookup that will act as the source for the field values.

Navigation
Setup and Maintenance → Manage Common Lookups

Create the following lookup type:

Field Value
Lookup Type XX_CUSTOM_ELIGIBILITY
Meaning XX_CUSTOM_ELIGIBILITY
Description XX_CUSTOM_ELIGIBILITY
Module Global Human Resources

Once the lookup type is created, add the lookup codes that will represent the values shown in the EFF.

Sample Lookup Codes

Lookup Code Meaning Start Date Tag
GRND_FATHER Grandfathered in 1/1/1951 +IN
HAZARD_ALLOWANCE Hazard Allowance 1/1/1951 +GB
ONCALL On Call 1/1/1951 +US,+CA,+IN
STIPEND_INCENTIVE Stipend Incentive 1/1/1951 (blank)

Using the Tag Column to Drive Legislation Logic

The Tag column is central to this pattern.

In this configuration:

  • +IN means the value is available only for India
  • +GB means the value is available only for Great Britain
  • +US,+CA,+IN means the value is available for multiple legislations
  • a blank tag means the value is available globally

This gives you a very practical mechanism for managing legislation-specific behavior without overcomplicating the EFF structure itself.

It also makes future maintenance easier. If the business wants to add a new value or expand eligibility to another legislation, the update can often be handled directly in the lookup.



Step 2: Create a Table-Validated Value Set

The next step is to create a value set that reads the lookup values and filters them using the legislation code of the employee.

Navigation
Setup and Maintenance → Manage Value Sets

Create the value set with the following definition:

Field Value
Value Set Code XX_CUSTOM_ELIGIBILITY_VS
Description XX_CUSTOM_ELIGIBILITY_VS
Module Global Human Resources
Validation Type Table
Value Data Type Character

Table Validation Details

Field Value
From Clause fnd_lookup_values
Value Column Name meaning
Description Column Name meaning
ID Column Name meaning

Where Clause

LOOKUP_TYPE = 'XX_CUSTOM_ELIGIBILITY'
AND (
  DECODE(
    TAG,
    NULL, 'Y',
    DECODE(
      SUBSTR(TAG,1,1),
      '+', DECODE(SIGN(INSTR(TAG, :{PARAMETER.LEGISLATION_CODE_VALUE})), 1, 'Y', 'N'),
      '-', DECODE(SIGN(INSTR(TAG, :{PARAMETER.LEGISLATION_CODE_VALUE})), 1, 'N', 'Y'),
      'Y'
    )
  ) = 'Y'
)
AND LANGUAGE = 'US'

This is the heart of the solution.

How the Value Set Logic Works

At runtime, the value set checks the TAG value for each lookup row.

The logic works like this:

  • if the TAG is null, the value is treated as global and shown to everyone
  • if the TAG starts with +, the value is shown only if the employee’s legislation code exists in the tag
  • if the TAG starts with -, the value is hidden if the employee’s legislation code exists in the tag

This creates a flexible filtering mechanism while keeping the actual list of values centrally managed.

From a design perspective, this is a strong pattern because it separates value maintenance in the lookup, filtering logic in the value set, and user entry in the EFF.




Step 3: Create the Global Assignment EFF Context and Segment

Once the lookup and value set are ready, the next step is to create the Global Assignment EFF segment that uses this value set.

Navigation
Setup and Maintenance → Manage Extensible Flexfields

Search for the Assignment Extensible Flexfield and create a new context and segment.

High-Level Steps

  1. open the Assignment EFF
  2. create a new context
  3. add a new segment
  4. assign the value set XX_CUSTOM_ELIGIBILITY_VS
  5. save and deploy the flexfield

The segment should be a character-based field configured to display as a list of values.












Important Detail: Legislation Code Parameter

The most important part of this configuration is the parameter referenced in the value set:

:{PARAMETER.LEGISLATION_CODE_VALUE}

This parameter must receive the employee’s legislation code at runtime. That is what enables the value set to determine which rows should be displayed.

If this parameter is not mapped correctly, the LOV may not behave as expected. In most cases, the issue will show up as one of the following:

  • all values are displayed
  • no values are displayed
  • values appear inconsistently for different employees

Because of that, parameter mapping is usually the first thing to verify during testing.

Testing the Configuration

Once the EFF is deployed, test the setup with employees from different legislations.

Based on the sample configuration above, the expected results are:

Employee Legislation Values Displayed
US On Call, Stipend Incentive
IN Grandfathered in, On Call, Stipend Incentive
CA On Call, Stipend Incentive
GB Hazard Allowance, Stipend Incentive

This confirms that the same field can support different value sets depending on employee context, without requiring country-specific duplication in the flexfield design.

US Employee



India Employee




Canada Employee






GB Employee - redwood UI






Why This Design Works Well

What makes this approach especially useful in global implementations is its balance between flexibility and simplicity.

Rather than designing multiple country-specific fields or managing complex configurations in several places, you keep the setup centralized:

  • the lookup stores all available values
  • the Tag defines country applicability
  • the value set handles runtime filtering
  • the EFF consumes the filtered result

This makes the solution easier to maintain, easier to explain, and easier to extend over time.

It also aligns well with a broader Oracle HCM design principle: whenever possible, solve requirements through configurable metadata rather than proliferating structures.

Final Thoughts

For global Oracle Fusion HCM implementations, legislation-sensitive value restriction is a requirement that comes up often. The combination of a custom lookup, country-tagged values, a table-validated value set, and a Global Assignment EFF provides a neat and reusable way to address it.

It keeps the configuration centralized, supports local variation, and avoids unnecessary duplication in your flexfield design.

If you are working on a global HCM rollout and need different LOV values for the same field across legislations, this is a pattern well worth keeping in your implementation toolkit.

Key Takeaways

  • a single Assignment EFF field can support different values by legislation
  • the lookup Tag column is a simple way to define country applicability
  • a table-validated value set can dynamically filter values at runtime
  • this pattern is scalable, maintainable, and well suited for global HCM implementations

Tuesday, 10 March 2026

How to Configure Context-Sensitive Descriptive Flexfields (DFF) for Absence Types in Oracle Fusion HCM


How to Configure Context-Sensitive Descriptive Flexfields (DFF) for Absence Types in Oracle Fusion HCM

Introduction

Organizations frequently need to capture different information depending on the absence type selected by an employee.

Absence Type Additional Information Required
Paid Time Off Paid Time Off Attribute
Sick Leave Sick Leave Attribute

Instead of customizing the application, Oracle Fusion Absence Management provides this capability through Context-Sensitive Descriptive Flexfields (DFF). This configuration allows the system to automatically display relevant fields depending on the selected absence type.

Solution Overview

This solution uses the Absence Recording Descriptive Flexfield (DFF) available in Oracle Fusion Absence Management.

  1. Access the Absence Recording DFF
  2. Configure the Context
  3. Create contexts and context sensitive segments
  4. Deploy the flexfield

(1) Access the Absence Recording DFF

Navigate to:

Setup and Maintenance → Manage Descriptive Flexfields

Search for Absence Recording DFF and click the Edit icon.









Step 2 – Configure the Context

Parameter Value
Default Type Parameter
Default Value Absence Type
Derivation Value Absence Type
Display Type Hidden

This ensures the context is automatically derived from the absence type.


Step 3 – Define Context and Context Sensitive Segments

Create Contexts for Each Absence Type

Next, click the Manage Contexts button to view existing contexts or create new ones.

On the Manage Contexts page, click the “+” (Add) icon to create a new context.

When creating a context:

  • You can enter any value for the Display Name

  • The Context Code must be the absence_type_id

The system uses this value to determine which set of fields should be displayed for the selected absence type.

Retrieve the Absence Type ID

To obtain the absence_type_id, run the following SQL query:

SELECT *
FROM ANC_ABSENCE_TYPES_F_TL
WHERE language = 'US'
AND name IN ('Paid Time Off','Sick Leave');

This query retrieves the IDs for the required absence types. Use the corresponding absence_type_id as the Context Code when creating the context.

Once the context is created, you can define context-specific segments that should appear when that absence type is selected.

Paid Time Off

  • Paid Time Off Attribute




Let's define another context and related segments

Sick Leave

  • Sick Leave Attribute




Step 4 – Deploy the Flexfield

Save the configuration and click Deploy Flexfield. Ensure deployment status shows successful compilation.


Testing the Configuration

Navigate to:

My Client Groups → Absence → Absences and Entitlements

Create a new absence request and verify the fields appear dynamically based on absence type.









Best Practices

  • Use Global Segments only for fields applicable to all absence types
  • Ensure context code matches absence_type_id
  • Keep Context Segment hidden
  • Always deploy flexfields after configuration

Conclusion

Using Context-Sensitive Descriptive Flexfields in Oracle Fusion Absence Management, organizations can dynamically capture absence-specific information without customization. This improves data accuracy, user experience, and system flexibility.

Loading Oracle Cloud Time and Labor Time Entries via REST API using PL/SQL (UTL_HTTP)

Loading Oracle Cloud Time and Labor Time Entries via REST API using PL/SQL (UTL_HTTP) Oracle Cloud HCM Time and Labor integrations are com...