available since 17.0
It is possible to control which folders are expanded or collapsed in the line items view of Quotes, Agreements & Promotions, Rebate Agreements, and Sales Compensation documents directly from header logic by using the Groovy API methods openFolder(lineId) and closeFolder(lineId) on the document processor.
These methods change only the view state (which folders are open) and have no impact on calculation results.
Scope and Availability
The methods are implemented on the header logic processors used in line-item-based documents:
-
Quotes (Quoting – Backend)
-
Agreements & Promotions (Agreements & Promotions – Backend)
-
Rebate Agreements (Rebates – Backend)
-
Sales Compensation (Sales Compensation – Backend)
They can be called from both:
-
Pre-phase header logic (before line calculations)
-
Post-phase header logic (after line calculations)
Behavior
openFolder(lineId)
-
Opens the folder with the given line item ID.
-
If the folder is nested under one or more closed parent folders, all parent folders are opened as well so that the target folder becomes visible.
-
Does not open any folders nested inside the target folder (only the folder itself and its ancestors are opened).
closeFolder(lineId)
-
Closes the folder with the given line item ID.
-
Collapses only that folder, with the same behavior as when the user manually collapses a folder via the UI (nested folders remain in their current open/closed state, but are no longer visible while the parent is collapsed).
Common Rules
-
The methods are view-only: opening or closing a folder does not mark the folder as changed and does not affect calculations or results.
-
The methods are only valid for folder line items. It is not possible to call
openFolder()orcloseFolder()on a line item that is not a folder. -
The behavior is consistent with the folder expand/collapse actions in the document UI.
Usage in Header Logic
In header logic, you typically work with a document processor instance such as:
-
quoteProcessorin Quotes -
agreementProcessorin Agreements & Promotions -
rebateAgreementProcessorin Rebate Agreements -
compensationPlanProcessorin Sales Compensation
The openFolder and closeFolder methods are exposed on these processor objects and accept a folder line ID as a String parameter.
Method Signatures (conceptual)
processor.openFolder(String lineId)
processor.closeFolder(String lineId)
Basic Example: Open and Close Specific Folders (Quotes)
The following example shows how to ensure that a specific folder is always open and another folder is always closed when a Quote is calculated.
// Header Logic – Quote
// IDs of folders in the quote line tree
def importantFolderId = "kmXPzPR7TOEHAYJ" // Folder to open
def obsoleteFolderId = "nH0ofVBhajMwtGb" // Folder to close
if (quoteProcessor.isPrePhase()) {
// Ensure key information is visible before line calculation
quoteProcessor.openFolder(importantFolderId)
quoteProcessor.closeFolder(obsoleteFolderId)
}
if (quoteProcessor.isPostPhase()) {
// Optional: enforce the same view after calculation as well
// quoteProcessor.openFolder(importantFolderId)
// quoteProcessor.closeFolder(obsoleteFolderId)
}
Notes:
-
importantFolderIdandobsoleteFolderIdmust be IDs of folder line items. -
The code can be used in pre-phase, post-phase, or both, depending on when you want the folder state to be enforced.
Nested Folders Example
When a folder is nested inside one or more closed parent folders, calling openFolder() on the nested folder opens all its closed ancestors so that the nested folder is visible.
// Header Logic – Quote (nested folders example)
// Folder structure:
// ROOT
// └─ Folder A (closed)
// └─ Folder B (closed)
// └─ Folder C (target folder, closed)
// ID of Folder C in the quote line tree
def nestedFolderId = "jl4SbUmlxrZA2ak"
if (quoteProcessor.isPrePhase()) {
// This will open Folder C and all its closed parent folders (A and B)
quoteProcessor.openFolder(nestedFolderId)
}
After this code runs:
-
Folder C is open.
-
Any closed parent folders (A, B, etc.) are also opened to make Folder C visible.
-
Folders nested inside Folder C, if any, remain in their previous open/closed state.
Example: Highlighting Important Folders Based on Conditions
You can combine openFolder() and closeFolder() with your own conditions to surface important sections of the line structure (for example, folders that contain special offers or exceptions).
// Header Logic – Quote
// Example: Always open the "Special Discounts" folder
// and close the "Archived Items" folder when a specific header flag is enabled.
def specialDiscountsFolderId = "FOLDER_SPECIAL_DISCOUNTS"
def archivedItemsFolderId = "FOLDER_ARCHIVED_ITEMS"
boolean highlightDiscounts = (api.input("HighlightDiscounts") == true)
if (quoteProcessor.isPrePhase() && highlightDiscounts) {
quoteProcessor.openFolder(specialDiscountsFolderId)
quoteProcessor.closeFolder(archivedItemsFolderId)
}
In this scenario:
-
Users with the
HighlightDiscountsheader flag enabled immediately see the Special Discounts folder. -
Less relevant content (for example, archived items) can be collapsed to keep the line tree focused.
Usage in Other Documents
The same concept applies in other line-item-based documents whose header logic exposes a processor object, for example:
// Header Logic – Agreement
def keyTermsFolderId = "FOLDER_KEY_TERMS"
if (agreementProcessor.isPrePhase()) {
agreementProcessor.openFolder(keyTermsFolderId)
}
// Header Logic – Rebate Agreement
def eligibilityFolderId = "FOLDER_ELIGIBILITY"
if (rebateAgreementProcessor.isPostPhase()) {
rebateAgreementProcessor.openFolder(eligibilityFolderId)
}
// Header Logic – Sales Compensation
def bonusRulesFolderId = "FOLDER_BONUS_RULES"
if (compensationPlanProcessor.isPrePhase()) {
compensationPlanProcessor.openFolder(bonusRulesFolderId)
}
The exact processor variable name depends on the document type and existing header logic conventions, but usage of openFolder() and closeFolder() is the same.
Limitations and Recommendations
Limitation: Folder-only operations
-
Use these methods only with folder line IDs. They are not intended for regular line items (leaf rows).
Limitation: View-only effect
-
Opening or closing folders:
-
Does not mark the folder as changed.
-
Does not recalculate line items.
-
Does not influence pricing logic or totals.
-
Recommendations:
-
Use
openFolder()andcloseFolder()primarily to:-
Surface key sections that users should review first.
-
Hide or collapse less relevant folders by default.
-
-
Prefer placing the logic in pre-phase when you want to influence the initial layout when the document loads, and in post-phase when you need to adjust the view after calculations based on results or flags set during calculation.
Summary
-
openFolder(lineId)andcloseFolder(lineId)are new header logic Groovy API methods that control folder expansion in the line items view, without affecting calculations. -
Opening a nested folder also opens all its closed parent folders but does not open folders nested inside it.
-
Methods are available for header logic in Quotes, Agreements & Promotions, Rebate Agreements, and Sales Compensation and can be used in both pre-phase and post-phase logic.
-
Calls are valid only for folder line items and are intended to improve usability and focus of complex line trees.