Following the post showing the method of running BIP SQL reports from Visual Builder Extension described here, we have built a generic solution that allows running any Fusion SaaS related SQL queries without the need of creating a dedicated report, custom object and groovy functions.
Implement Fusion SaaS attachment category selection in a VBCS screen. There is no published Fusion SaaS REST API that allows fetching attachment categories relevant for a specific attachment entity (Sales Order for example).
The data below can be fetched by the SQL statement below, this post will describe a way to achieve it by building a generic solution for this and other similar cases.select cat.category_name, cat.user_name from FND_DOCUMENT_ENTITIES fde, FND_DOC_CATEGORIES_TO_ENTITIES dce, fnd_document_categories_vl cat where fde.table_name = 'DOO_HEADERS_ALL' and fde.document_entity_id = dce.document_entity_id and dce.category_id = cat.category_id
select 1,2,3,4,5 from dual will generate the following result [ { "COL1":"1", "COL2":"2", "COL3":"3", "COL4":"4", "COL5":"5" } ] Select dbms_xmlgen.getxmltype( :p_sql).transform(XMLType('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="text" encoding="UTF-8"/><xsl:strip-space elements="*"/><xsl:template match="/"><xsl:text>[</xsl:text><xsl:for-each select="ROWSET/ROW"><xsl:if test="position() > 1"><xsl:text>,</xsl:text></xsl:if><xsl:text>{</xsl:text><xsl:for-each select="*"><xsl:if test="position() > 1"><xsl:text>,</xsl:text></xsl:if><xsl:text>"COL</xsl:text><xsl:value-of select="position()"/><xsl:text>": "</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text></xsl:for-each><xsl:text>}</xsl:text></xsl:for-each><xsl:text>]</xsl:text></xsl:template></xsl:stylesheet>')) result from dual 

def res = new java.util.ArrayList<java.util.Map<java.lang.String,java.lang.String>>()
def params = [:]
params.sqlText = sqlText
def report_data = adf.webServices.RunSqlReport.getResults(params)
for (r in report_data)
{
def rec = r as Map
res.add(rec)
}
return res
class vbEnter extends ActionChain {
/**
* @param {Object} context
*/
async run(context) {
const { $page, $flow, $application, $extension } = context;
const callGetRestUtil = await Actions.callRest(context, {
endpoint: 'site_AccountSiteExtension:crm/getall_RestUtil_c',
uriParams: {
limit: '1',
onlyData: true,
fields: 'Id',
},
});
if (callGetRestUtil.ok) {
const getCategoriesReportDataResponse = await Actions.callRest(context, {
endpoint: 'site_AccountSiteExtension:crm/do_getReportData_RestUtil_c',
uriParams: {
'RestUtil__c_Id': callGetRestUtil.body.items[0].Id,
},
body: {
sqlText: 'select cat.category_name, cat.user_name from FND_DOCUMENT_ENTITIES fde, FND_DOC_CATEGORIES_TO_ENTITIES dce, fnd_document_categories_vl cat where fde.table_name = \'DOO_HEADERS_ALL\' and fde.document_entity_id = dce.document_entity_id and dce.category_id = cat.category_id',
},
contentType: 'application/vnd.oracle.adf.action+json',
});
if (getCategoriesReportDataResponse.ok) {
$page.variables.categoryListADP.data = getCategoriesReportDataResponse.body.result;
$page.variables.categoriesLoaded = true;
} else {
await Actions.fireNotificationEvent(context, {
summary: 'Error',
message: getCategoriesReportDataResponse.statusText,
});
}
} else {
await Actions.fireNotificationEvent(context, {
summary: 'Error',
message: callGetRestUtil.statusText,
});
}
}
}
return vbEnter;
});