Using BRApi vs Api
Using BRApi vs Api
BRApis are a versatile Class used across all Business Rules (BR) / Service Types, engines, and APIs in OneStream with purposeful functions. While not an engine, BRApis enables communication and function orchestration across engines and APIs.
- A common use of BRApi is to source data from an external data source utilizing a Connector BR.
An API is specific to the executing engine, such as the Finance Engine, and provides functions specific to the type of Business Rule / Service Type being written.
- For example, Finance Engine API functions are designed to facilitate multi-dimensional “cube” calculations and enable complex financial data analysis and processing.
When an API can be implemented, use the API instead of the equivalent BRApi, as the BRApi opens a connection to the application, whereas the API does not. For additional information related to the Finance Engine, please refer to the Finance Usage Guide.
Code Examples
- C# API, Finance Business Rule
- VB API, Finance Business Rule
case var @case when @case == FinanceFunctionType.Calculate:
{
// Base Entities - all C#'s if they have data
// Parent Entities - all C#'s EXCEPT Local (no parent adjustments)
if (!(api.Entity.HasChildren() && api.Cons.IsLocalCurrencyForEntity()))
{
#region Clear Plug Accounts
// If the Cons member is Elimination
if (api.Pov.Cons.MemberId == DimConstants.Elimination)
{
var plugAccountList = new List<string>();
string plugAcctName = string.Empty;
// Get a list of all base Account members
List<Member> balSheetBaseAcctList = api.Members.GetBaseMembers(api.Pov.AccountDim.DimPk, api.Members.GetMemberId(DimType.Account.Id, "BalanceSheet"));
// Loop over all base Accounts and if they have a Plug Account assigned, add that Plug Account to the list
foreach (Member baseAcct in balSheetBaseAcctList)
{
plugAcctName = api.Account.GetPlugAccount(baseAcct.MemberId).Name;
if (!string.IsNullOrWhiteSpace(plugAcctName) && plugAccountList.Contains(plugAcctName) == false)
{
plugAccountList.Add(plugAcctName);
}
} // baseAcct
// Clear the Plug Accounts when they have data with the CF UD6 members
api.Data.ClearCalculatedData(true, true, true, true, "A#" + string.Join(",A#", plugAccountList.Distinct()), default, default, default, default, default, default, default, default, "U6#Total_CF.Base");
}
}
}
Case Is = FinanceFunctionType.Calculate
'Base Entities - all C#'s if they have data
'Parent Entities - all C#'s EXCEPT Local (no parent adjustments)
If Not (api.Entity.HasChildren() AndAlso api.Cons.IsLocalCurrencyForEntity()) Then
#Region "Clear Plug Accounts"
'If the Cons member is Elimination
If api.Pov.Cons.MemberId = DimConstants.Elimination Then
Dim plugAccountList As New List(Of String)
Dim plugAcctName As String = String.Empty
'Get a list of all base Account members
Dim balSheetBaseAcctList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.AccountDim.DimPk,api.Members.GetMemberId(DimType.Account.Id, "BalanceSheet"))
'Loop over all base Accounts and if they have a Plug Account assigned, add that Plug Account to the list
For Each baseAcct As Member In balSheetBaseAcctList
plugAcctName = api.Account.GetPlugAccount(baseAcct.MemberId).Name
If (Not String.IsNullOrWhiteSpace(plugAcctName)) AndAlso plugAccountList.Contains(plugAcctName) = False Then
plugAccountList.Add(plugAcctName)
End If
Next 'baseAcct
'Clear the Plug Accounts when they have data with the CF UD6 members
api.Data.ClearCalculatedData(True,True,True,True,"A#" & String.Join(",A#",plugAccountList.Distinct()),,,,,,,,,"U6#Total_CF.Base")
End If
- C# API, Finance Core Service Type
- VB API, Finance Core Service Type
namespace Workspace.__WsNamespacePrefix.__WsAssemblyName
{
public class svcFinanceCore : IWsasFinanceCoreV800
{
public void Calculate(SessionInfo si, BRGlobals brGlobals, FinanceRulesApi api, FinanceRulesArgs args)
{
try
{
// Base Entities - all C#'s if they have data
// Parent Entities - all C#'s EXCEPT Local (no parent adjustments)
if (!(api.Entity.HasChildren() && api.Cons.IsLocalCurrencyForEntity()))
{
#region Clear Plug Accounts
#region Calculate CF
} // If (Not (api.Entity.HasChildren() AndAlso api.Cons.IsLocalCurrencyForEntity())) Then
}
catch (Exception ex)
{
throw new XFException(si, ex);
}
}
Namespace Workspace.__WsNamespacePrefix.__WsAssemblyName
Public Class svcFinanceCore
Implements IWsasFinanceCoreV800
Public Sub Calculate(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) Implements IWsasFinanceCoreV800.Calculate
Try
'Base Entities - all C#'s if they have data
'Parent Entities - all C#'s EXCEPT Local (no parent adjustments)
If Not (api.Entity.HasChildren() AndAlso api.Cons.IsLocalCurrencyForEntity()) Then
#Region "Clear Plug Accounts"
'If the Cons member is Elimination
If api.Pov.Cons.MemberId = DimConstants.Elimination Then
Dim plugAccountList As New List(Of String)
Dim plugAcctName As String = String.Empty
'Get a list of all base Account members
Dim balSheetBaseAcctList As List(Of Member) = api.Members.GetBaseMembers(api.Pov.AccountDim.DimPk,api.Members.GetMemberId(DimType.Account.Id, "BalanceSheet"))
'Loop over all base Accounts and if they have a Plug Account assigned, add that Plug Account to the list
For Each baseAcct As Member In balSheetBaseAcctList
plugAcctName = api.Account.GetPlugAccount(baseAcct.MemberId).Name
If (Not String.IsNullOrWhiteSpace(plugAcctName)) AndAlso plugAccountList.Contains(plugAcctName) = False Then
plugAccountList.Add(plugAcctName)
End If
Next 'baseAcct
'Clear the Plug Accounts when they have data with the CF UD6 members
api.Data.ClearCalculatedData(True,True,True,True,"A#" & String.Join(",A#",plugAccountList.Distinct()),,,,,,,,,"U6#Total_CF.Base")
End If
#End Region
#Region "Calculate CF"
'Data buffer with all BS accounts which have a CF mapping in the Text1 field
Dim sourceDataBuffer As DataBuffer = api.data.GetDataBufferUsingFormula("RemoveZeros(FilterMembers(U6#None,[A#BalanceSheet.Base.Where(Text1 Contains 'CF_')]))",,False)
If sourceDataBuffer.DataBufferCells.Count > 0 Then
Dim resultDataBuffer As New DataBuffer 'Data buffer for calculated results
Dim acctText1 As String = String.Empty
Dim acctFlowFields As List(Of String)
Dim flowcfAcctSign As List(Of String)
Dim flowMember As String = String.Empty
Dim cfAcct As String = String.Empty
Dim sign As String = String.Empty
Dim flowMemberID As Integer
Dim cfAcctID As Integer
For Each sourceCell As DataBufferCell In sourceDataBuffer.DataBufferCells.Values
If (Not sourceCell.CellStatus.IsNoData) Then
acctText1 = api.Account.Text(sourceCell.DataBufferCellPk.AccountId,1) 'Text 1 of the Account
If (Not String.IsNullOrWhiteSpace(acctText1)) Then 'If the Account text field is NOT blank
'Split the Account text field based on the delimiter for each new mapping
'Example: RF_PPE_Additions:CF_PurchaseOfPPE;-1|RF_PPE_Disposals:CF_ProceedsFromSaleOfPPE;-1|RF_PPE_GLSale:CF_GainLossAssetSales;-1|FX:CF_FX;-1
acctFlowFields = StringHelper.SplitString(acctText1, "|", StageConstants.ParserDefaults.DefaultQuoteCharacter)
For x As Integer = 1 To acctFlowFields.Count 'Loop over each of the mappings
'Split the individual mapping by the delimiter to separate the source Flow member and the CF member;sign
flowcfAcctSign = StringHelper.SplitString(acctFlowFields(x - 1), ":", StageConstants.ParserDefaults.DefaultQuoteCharacter)
flowMember = flowcfAcctSign(0) 'Flow member is the first field after split (zero based list)
cfAcct = flowcfAcctSign(1) 'CF member is the second field after split (zero based list)
sign = flowcfAcctSign(2) 'Sign is the third field after split (zero based list)
flowMemberID = api.Members.GetMemberId(DimType.Flow.Id, flowMember) 'Flow member ID
'If the flow we are processing is a base member of the source flow member
If api.Members.IsBase(api.Pov.FlowDim.DimPk, flowMemberID, sourceCell.DataBufferCellPk.FlowId) Then
cfAcctID = api.Members.GetMemberId(DimType.UD6.Id, cfAcct) 'CF member ID
'Build the Destination Cell
Dim resultCell As New DataBufferCell(sourceCell)
'Account stays the same
'Flow stays the same
'Origin stays the same
resultCell.DataBufferCellPk.ICId = DimConstants.None
resultCell.DataBufferCellPk.UD1Id = DimConstants.None
resultCell.DataBufferCellPk.UD2Id = DimConstants.None
resultCell.DataBufferCellPk.UD3Id = DimConstants.None
resultCell.DataBufferCellPk.UD4Id = DimConstants.None
resultCell.DataBufferCellPk.UD5Id = DimConstants.None
resultCell.DataBufferCellPk.UD6Id = cfAcctID 'Set the UD6 to the CF member of the mapping
' 'UD7 stays the same
resultCell.DataBufferCellPk.UD8Id = DimConstants.None
resultCell.CellAmount = sourceCell.CellAmount * sign 'Multiply the source cell amount by the sign of the mapping
resultDataBuffer.SetCell(si, resultCell, True) 'Add the cell to the data buffer and accumulate if the cell already exists
End If
Next 'For x = 1 To acctFlowFields.Count
End If 'If (Not String.IsNullOrWhiteSpace(acctText1)) Then
End If 'If (Not sourceCell.CellStatus.IsNoData) Then
Next 'For Each sourceCell As DataBufferCell In sourceDataBuffer.DataBufferCells.Values
'Set the data buffer
Dim destinationInfo As ExpressionDestinationInfo = api.Data.GetExpressionDestinationInfo("")
api.Data.SetDataBuffer(resultDataBuffer, destinationInfo)
End If 'If sourceDataBuffer IsNot Nothing AndAlso sourceDataBuffer.DataBufferCells.Count > 0 Then
#End Region
End If 'If (Not (api.Entity.HasChildren() AndAlso api.Cons.IsLocalCurrencyForEntity())) Then
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Sub
Public Sub Translate(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) Implements IWsasFinanceCoreV800.Translate
Try
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Sub
Public Sub ConsolidateShare(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) Implements IWsasFinanceCoreV800.ConsolidateShare
Try
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Sub
Public Sub ConsolidateElimination(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) Implements IWsasFinanceCoreV800.ConsolidateElimination
Try
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Sub
Public Function GetCustomFxRate(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) As FxRateResult Implements IWsasFinanceCoreV800.GetCustomFxRate
Try
Return Nothing
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Function
Public Function GetConditionalInputResult(ByVal si As SessionInfo, ByVal brGlobals As BRGlobals, ByVal api As FinanceRulesApi, ByVal args As FinanceRulesArgs) As ConditionalInputResultType Implements IWsasFinanceCoreV800.GetConditionalInputResult
Try
Return ConditionalInputResultType.Default
Catch ex As Exception
Throw New XFException(si, ex)
End Try
End Function
End Class
End Namespace
- C# BRApi, Connector Business Rule
- VB BRApi, Connector Business Rule
// 3. Get the Drill Back Type (Options)
// If the user is a member of group, TechTalkDrillBack, or in the Administrators group, Drill Back is enabled
case var case2 when case2 == ConnectorActionTypes.GetDrillBackTypes:
{
if (BRApi.Security.Authorization.IsUserInGroup(si, si.UserName, "TechTalkDrillBack", true))
{
switch (true)
{
// Define Drill Back Types (Options) presented to the end user when Drill Back occurs
case object _ when strDataSourceName.XFEqualsIgnoreCase("HoustonRevMgmt"):
{
return getDrillBackTypeList(si, globals, api, args);
}
}
}
else
{
return null;
}
break;
}
'3. Get the Drill Back Type (Options)
'If the user is a member of group, TechTalkDrillBack, or in the Administrators group, Drill Back is enabled
Case Is = ConnectorActionTypes.GetDrillBackTypes
If BRApi.Security.Authorization.IsUserInGroup(si,si.UserName,"TechTalkDrillBack",True)
Select Case True
'Define Drill Back Types (Options) presented to the end user when Drill Back occurs
Case strDataSourceName.XFEqualsIgnoreCase("HoustonRevMgmt")
Return Me.getDrillBackTypeList(si, globals, api, args)
End Select
Else
Return Nothing
End If