Dayalan Punniyamoorthy Blog

Showing posts with label Comments. Show all posts
Showing posts with label Comments. Show all posts

Sunday, May 31, 2026

Groovy Rules to Support the Copying of Relational Data, Comments, Attachments, and Supporting Details !

The Oracle Fusion Cloud EPM April 2026 (26.04) release introduces a powerful new Groovy capability that addresses one of the most common automation gaps in EPM Planning and FreeForm applications — the ability to programmatically copy relational and Essbase data, comments, attachments, and supporting details using Groovy business rules.

 

Prior to this enhancement, copying data between scenarios, versions, or periods — especially when it included relational artifacts like cell-level comments, file attachments, and supporting detail — required manual processes or was limited to UI-based copy operations. With this release, Oracle introduces the CopyDataRequest class in the Groovy Rules Java API, giving developers full programmatic control over data copy operations, including all associated relational content.

This is a significant step forward for organizations that rely on automated month-end, quarter-end, or annual planning workflows where preserving the full context of data — not just the numbers — is critical.

 

What Problem Does This Solve?

In typical EPM Planning and FreeForm environments, data exists at multiple layers:

Data Layer

Description

Essbase (Numeric) Data

The core financial or operational data stored in Essbase cubes

Relational Data

Metadata and structural information stored in the relational database

Cell Comments

User-entered notes attached to specific data intersections

Cell Attachments

Files (documents, spreadsheets, images) attached to specific cells

Supporting Details

Line-item breakdowns that roll up into a cell value

Before this enhancement, Groovy rules could manipulate Essbase data programmatically, but copying the full data package — including comments, attachments, and supporting details — required either manual UI operations or complex workarounds. This created challenges in several common scenarios:

  • Seeding budget data from actuals — Comments explaining actual variances were lost during the copy
  • Version management — Copying from a working version to a final version stripped supporting detail
  • Period rollover — Rolling forward a forecast lost the context behind the numbers
  • Scenario planning — Duplicating a base scenario for what-if analysis excluded attachments and notes

 

The New CopyDataRequest Class

The April 2026 release introduces the CopyDataRequest class in the Cloud EPM Groovy Rules Java API. This class provides a fluent, builder-pattern API for defining and executing data copy operations that include all relational artifacts.

Key Methods

Method

Description

setCopySupportingDetail(boolean)

Enables or disables copying of supporting detail line items

setCopyComments(boolean)

Enables or disables copying of cell-level comments

setCopyAttachments(boolean)

Enables or disables copying of cell-level file attachments

addSourceAndTarget(String, String)

Defines a source-to-target member mapping for the copy operation

addFixedMembers(Dimension, String...)

Specifies fixed members or member expressions to constrain the copy scope

copyData()

Executes the copy operation

Important Constraints

  • A single CopyDataRequest object can only be used one time. For multiple copy operations, create a new request object for each iteration.
  • The copy operation respects the existing security model — users must have appropriate access to both source and target intersections.
  • Both Essbase data and relational data are copied in a single, unified operation.

 

Applicable EPM Modules

This enhancement applies to the following Oracle Cloud EPM business processes: [docs.oracle.com]

Module

Supported

Planning

Yes

FreeForm

Yes

 

Code Examples

Example 1: Basic Data Copy with All Relational Artifacts

This example copies data from Current/FY26 to Budget/FY27, including supporting details, comments, and attachments:

Application app = operation.application
Cube cube = app.getCube("Plan2")

CopyDataRequest request = cube.createCopyDataRequest()

    .setCopySupportingDetail(true)
    .setCopyComments(true)
    .setCopyAttachments(true)

request = request

    .addSourceAndTarget("Current", "Budget")
    .addSourceAndTarget("FY26", "FY27")
    .addFixedMembers(app.getDimension("Employee"), "ILvl0Descendants(Employee)")
    .addFixedMembers(app.getDimension("Account"), "Grade", "Salary", "Bonus",
        "Employee Phone", "Employee Email", "Reporting Manager")
    .addFixedMembers(app.getDimension("Currency"), "USD")
    .addFixedMembers(app.getDimension("Version"), "BU Version_1")
    .addFixedMembers(app.getDimension("Entity"), "No Entity")
    .addFixedMembers(app.getDimension("Period"), "BegBalance")

request.copyData()

 

Breaking Down the Code

Step 1 — Get Application and Cube References

Application app = operation.application

Cube cube = app.getCube("Plan2")


This retrieves the current application context and the specific cube (plan type) where the data resides.

 

Step 2 — Create the CopyDataRequest and Set Options


CopyDataRequest request = cube.createCopyDataRequest()

.setCopySupportingDetail(true)

.setCopyComments(true)

.setCopyAttachments(true)


The fluent builder pattern allows chaining of configuration methods. Setting each flag to true ensures that all relational data types are included in the copy.

 

Step 3 — Define Source-to-Target Mappings


request = request

.addSourceAndTarget("Current", "Budget")

.addSourceAndTarget("FY26", "FY27")


Multiple source-to-target pairs can be chained. In this case, the Scenario dimension maps Current to Budget, and the Year dimension maps FY16 to FY17.

 

Step 4 — Constrain the Scope with Fixed Members

.addFixedMembers(app.getDimension("Employee"), "ILvl0Descendants(Employee)")

.addFixedMembers(app.getDimension("Account"), "Grade", "Salary", "Bonus", ...)


Fixed members define the dimensional scope of the copy. You can use individual member names or Essbase member selection functions like ILvl0Descendants().

 

Step 5 — Execute the Copy


request.copyData()


This triggers the actual data copy operation.

  

Example 2: Iterative Copy to Multiple Versions

This example copies last year's Actual data from the Final version to all level-0 versions in this year's Budget:

Application app = operation.application
Cube cube = app.getCube("Plan2")

List<Member> versions = app.getDimension("Version")

    .getEvaluatedMembers("ILvl0Descendants(Version)", cube)
versions.remove(app.getDimension("Version").getMember("Final"))

versions.each { version ->

    CopyDataRequest request = cube.createCopyDataRequest()
        .setCopySupportingDetail(true)
        .setCopyComments(true)
        .setCopyAttachments(true)

    request = request

        .addSourceAndTarget("Actual", "Budget")
        .addSourceAndTarget("&LastYear", "&ThisYear")
        .addSourceAndTarget("Final", version)

    request.addFixedMembers(app.getDimension("Employee"),

        "ILvl0Descendants(Employee)")
    request.addFixedMembers(app.getDimension("Account"),
        "Grade", "Salary", "Bonus", "Employee Phone",
        "Employee Email", "Reporting Manager")
    request.addFixedMembers(app.getDimension("Currency"), "USD")
    request.addFixedMembers(app.getDimension("Entity"), "No Entity")
    request.addFixedMembers(app.getDimension("Period"), "BegBalance")

    request.copyData()

}


Key Points in This Example

  • Substitution Variables (&LastYear, &ThisYear) can be used in source-to-target mappings, enabling dynamic year-based copy operations
  • A new CopyDataRequest is created inside the loop for each version, since each request object can only be used once
  • Member objects (not just strings) can be passed as target values, as shown with the version variable

 

Example 3: Using Runtime Prompts (RTPs) with Member References

This example demonstrates using Runtime Prompt variables and explicit member references:

/*RTPS: {MyEmployees}*/
Application app = operation.application
Cube cube = app.getCube("Plan2")

Member salaryMember = app.getDimension("Account").getMember("Salary")

CopyDataRequest request = cube.createCopyDataRequest()

    .setCopySupportingDetail(false)
    .setCopyComments(false)
    .setCopyAttachments(false)

// Use RTP variable and member reference for targeted copy

request = request
    .addSourceAndTarget("Actual", "Budget")
    .addFixedMembers(app.getDimension("Employee"), rtps.MyEmployees)
    .addFixedMembers(app.getDimension("Account"), salaryMember)

request.copyData()

Key Points

  • The RTPS comment line (/*RTPS: {MyEmployees}*/) is mandatory when using Runtime Prompt variables — this is one of the most common Groovy validation errors flagged by the Groovy Script Validator
  • Individual relational data types can be selectively excluded by setting flags to false
  • Member objects retrieved via getMember() can be used directly in addFixedMembers()


  Practical Use Cases

1. Automated Budget Seeding

Copy actual data from the completed fiscal year into the new budget cycle, preserving all comments and supporting details that explain the actuals. This eliminates the need for manual re-entry of contextual information during the budget preparation process.

2. Forecast Rolling

Automate monthly forecast rolling by copying the current forecast period forward, including all supporting detail line items and analyst comments. This ensures continuity and auditability across forecast cycles.

3. Version Snapshotting

Create point-in-time snapshots of planning data by copying from a working version to an archive version, including all attachments and supporting documentation. This is critical for regulatory compliance and audit readiness.

4. Scenario Duplication

Duplicate a base planning scenario into multiple what-if scenarios, preserving the full context of the original plan including all relational artifacts. This enables faster scenario analysis without losing the analytical context behind the numbers.

5. Month-End / Period-End Automation

Integrate this capability into existing month-end automation scripts to create a fully automated data management pipeline that handles not just numeric data but the complete data package.

 

 

Integration with the Groovy Engine Update

It is important to note that this feature arrives alongside the announcement of a mandatory Groovy engine update planned for May 2026 (26.05). The new Groovy engine introduces stricter validation rules, which means existing Groovy business rules may need to be updated.

Recommended Actions

  1. Run the Groovy Script Validator in your test environment immediately
  2. Review the validation report and fix any flagged scripts
  3. When writing new CopyDataRequest scripts, ensure compliance with the new validation rules:
    • Use explicit data types instead of def
    • Always include the RTPS comment line
    • Add the "d" suffix to floating-point numbers
    • Remove empty generic type declarations
  4. Test thoroughly before the 26.05 update is applied

 

Technical Considerations

Performance

  • Large-scale copy operations that include supporting details and attachments will take longer than data-only copies
  • Consider breaking large copy operations into smaller batches using fixed member constraints
  • Monitor job execution times and adjust scope as needed

Security

  • The copy operation respects the application's security model
  • Users executing the Groovy rule must have read access to source intersections and write access to target intersections
  • Service Administrator or Power User roles are typically required

Error Handling

  • Wrap copy operations in try-catch blocks for robust error handling
  • Log the source and target mappings before execution for troubleshooting
  • Validate member existence before creating the request to avoid runtime errors

 

Conclusion

The Groovy Rules to Support the Copying of Relational Data, Comments, Attachments, and Supporting Details in Oracle EPM Cloud April 2026 (26.04) fills a critical gap in EPM automation. By providing a clean, programmatic API for copying the complete data package — not just numeric values — Oracle is enabling organizations to build truly end-to-end automated workflows for budgeting, forecasting, and financial close processes.

For EPM developers and administrators, the new CopyDataRequest class offers a powerful, flexible, and well-designed API that integrates seamlessly into existing Groovy business rules. Combined with Runtime Prompts, substitution variables, and member selection functions, it provides the tools needed to automate even the most complex data management scenarios while preserving the full context and auditability of financial data.

This is a feature that planning teams have been waiting for — and it delivers exactly what is needed to take EPM automation to the next level.

Happy Days on the cloud!