Tuesday, 5 May 2026

Oracle Cloud 25B: Enabling Approvals for Employee External Bank Account Creation and Modification

Oracle Cloud 25B: Enabling Approvals for Employee External Bank Account Creation and Modification

Introduction

A long-standing control gap in Oracle HCM and Payroll has been the lack of approval workflows for employee bank account changes. Organizations have consistently raised concerns about allowing employees to create or modify external bank accounts without validation or oversight.

With Oracle Cloud 25B, Oracle has introduced the ability to enforce approvals specifically for Employee External Bank Account creation and modification, adding a critical governance layer to payroll processing.

Business Context

Employee external bank accounts directly impact salary disbursement. Any incorrect or unauthorized change can lead to:

  • Payments being routed to incorrect accounts
  • Payroll failures and rework
  • Increased risk of fraud
  • Compliance and audit challenges

This enhancement introduces a structured approval mechanism to mitigate these risks within the application itself.

What’s Delivered in 25B

The solution is built using three core components:

  1. Feature Opt-In for Payments
  2. Controlled Lookup Enablement
  3. Spreadsheet-Based Approval Rules

This functionality applies specifically to:

  • Creation of external bank accounts
  • Modification of external bank accounts

Step 1: Enable Feature Opt-In

Navigate to:

Setup and Maintenance > Financials > Payments > Edit Features

Enable:

Employee Bank Account Ownership Verification Workflow

This step activates the underlying approval framework.


Step 2: Enable Controlled Lookup

Navigate to:

Setup and Maintenance > Manage Standard Lookups

Search for:

ORA_ERP_CONTROLLED_CONFIG

Enable the following lookup:

  • Lookup Code: IBY_37070344
  • Meaning: Enable Bank Account Approval
  • Status: Enabled

This lookup acts as the trigger for approval processing.



Step 3: Configure Approval Rules

Navigate to:

Manage User-Defined Rules for Employee Bank Account Approvals

Download:

ExternalBankAccountApprovalRulesTemplate.xlsm

Important

Ensure the following privilege is assigned:

IBY_MANAGE_BANK_ACCOUNT_APPROVALS_PRIV

Without this privilege, users will not be able to configure approval rules using the task Manage User-Defined Rules for Employee Bank Account Approvals.

Step 4: Define Approval Logic

Approval rules are defined using the Excel template.

In this implementation example, a two-level approval was configured:

  1. Account Owner approval using username
  2. Approval by users with the role KP_PAYROLL_ADMIN_VIEW_ALL_DATA

If multiple users have this role, any one of them can approve the notification.

After defining the rules in Excel:

  1. Click Generate Rule File
  2. A ZIP file will be generated
  3. Upload the ZIP file back into Manage User-Defined Rules for Employee Bank Account Approvals











End-to-End Flow

  1. Employee creates or updates an external bank account
  2. System evaluates feature opt-in and lookup configuration
  3. Approval rules are applied
  4. Request is routed to approver or approvers
  5. Upon approval, the bank account is created or updated

Basic Testing of Configuration

After completing the setup, perform a simple validation to confirm the configuration is working.

Test Steps

  1. Login as an employee
  2. Navigate to Me > Pay > Payment Methods
  3. Add a new external bank account or update an existing one
  4. Submit the transaction





Expected Result

  • The change should not be applied immediately
  • An approval request should be triggered
  • The request should appear in the approver’s worklist or notifications


Approval Validation

  1. Login as the approver
  2. Open the approval notification
  3. Approve the request

Result: The bank account should be successfully created or updated.

What This Confirms

  • Feature opt-in is enabled correctly
  • Lookup configuration is active
  • Approval rules are functioning
  • Workflow routing is working as expected

Key Observations

Scope of Approval

This feature applies only to:

  • External bank account creation
  • External bank account modification

It does not apply to other payment method configurations such as allocation or percentage splits.

Configuration Model

This feature is not configured like standard HCM approval transactions.

It does not use:

  • Transaction Design Studio
  • Standard BPM rule configuration

Instead, it relies on:

  • Feature opt-in
  • Controlled lookup
  • Spreadsheet-based rule definition

Implementation Considerations

Payroll Timing

Bank account changes are applied only after approval. Approval timelines must align with payroll processing cutoffs to avoid delays.

Limitations and Considerations

While this feature addresses a critical control gap, there are important limitations to consider.

Limited Rule Authoring Model

Approval rules are defined using a spreadsheet template rather than the standard BPM rule UI.

This results in:

  • Static, template-driven rules
  • Limited flexibility compared to dynamic BPM configurations
  • No support for advanced conditional expressions

No Support for AOR-Based Routing

Unlike other HCM approvals, this feature does not support routing based on Areas of Responsibility (AOR).

This means:

  • Approval cannot dynamically route based on HR or payroll responsibility
  • Routing must be predefined in the template

Limited Support for Complex Approval Scenarios

Compared to other HCM transactions, the following are not supported:

  • Dynamic multi-stage approvals
  • Parallel approval flows
  • Rule chaining or advanced escalation logic

Approval flows are generally linear.

Dependency on Template Maintenance

Since rules are managed through a spreadsheet:

  • Any change requires re-download and re-upload
  • Version control must be managed externally
  • There is a higher risk of manual errors

Limited Debugging Capability

Troubleshooting approval issues is less intuitive due to:

  • Lack of visual rule builder
  • Limited runtime diagnostics
  • Errors often identified only during upload or execution

Practical Recommendations

  • Start with simple approval rules, such as manager-based or payroll-admin-based routing
  • Avoid overly complex logic
  • Maintain proper documentation of rule logic
  • Establish governance for template updates
  • Validate the approval flow before enabling in production

Compliance and Audit

This feature strengthens:

  • Audit traceability
  • Internal controls
  • Fraud prevention

User Communication

Employees should be informed that:

  • Bank account changes require approval
  • Changes are not immediate
  • Approval must be completed before the change becomes effective

Conclusion

Oracle Cloud 25B introduces an essential control for managing employee external bank account changes.

By combining feature enablement, controlled configuration, and approval rules, organizations can significantly improve governance over payroll-critical data.

This is a practical enhancement that should be enabled and validated as part of any payroll implementation.

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