Convert a static report to a functional FA report
Overview
In this tutorial, you will turn the previously created static report into a dynamic report template you can use with FA to generate a report for a selected portfolio.
Note
This tutorial assumes you have completed the previous tutorial and continues where it left off.
Steps
Step 1 - Apply tags to make the report available as a report in FA
In order for FA to recognize a report defined in jsreport and make it available, the report template needs to be tagged with the report
tag.
Click on the report template Sample Report.
Click on select ... under the Tags section.
Choose
report
andparam-portfolioId
tags and click Ok.
Once the report template has a tag, it will be available as a report in FA.
However, the sample report data is not available to it and the report itself will not work yet. The next step is to dynamically fetch the data for a selected portfolio.
Step 2 - Calling the GraphQL API to dynamically create the data set used in the report
When generating a report in FA, the GraphQL token information is passed as a parameter. This information is required by the report to make a call to FA’s GraphQL API, from which it can fetch data from FA. In order for this to work, the report requires JavaScript logic that is called when the report is instantiated. This logic would make a call to the API and make the data available to the report in a similar manner as the sample data.
First, create a script file by right-clicking the sample report's folder and choosing New Entity -> script. Call the script file logic.js.
The next step is to link the JavaScript file to the report template:
Most of the the JavaScript code is run in the function beforeRender()
, which means it is run before the report and its template is rendered. Its job is to use the Axios library to make a GraphQL API call back to FA using the portfolio ID given from FA as a parameter.
Copy the content of the following JavaScript into the logic.js file:
const axios = require('axios') async function beforeRender(req, res) { let params = req.data.params; // If query is expecting a list of portfolio ids, use the following //var ids = params["param-portfolioId"].map( v => Number(v)); // if query is expecting a single long portfolio id, use the following var ids = Number(params["param-portfolioId"]) await axios({ url: params["param-graphqlUri"], method: 'post', headers: { Authorization: 'Bearer ' + params["param-userAccessToken"] }, data: { query: ` query PortfolioOverview($portfolioId: Long ) { portfolio(id: $portfolioId) { client: primaryContact { name } portfolioName: name portfolioReport: portfolioReport( calculateExpectedAmountBasedOpenTradeOrders: true) { marketValue: positionMarketValue cashBalance: accountBalance netAssetValue: marketValue investments: portfolioReportItems { security { name securityCode } amount amountAfterOpenTradeOrders purchaseValue:purchaseTradeAmount positionValue: marketTradeAmount changePercent: valueChangeRelative } } } } `, variables: { portfolioId: ids } } }).then((result) => { req.data = result.data }); }
There are three parameters that are passed from FA to jsreport when the report is called. Two of them are always passed:
userAccessToken
- token of the user calling the report (the API call is made on behalf of that user)graphqlUri
- internal address to the FA’s GraphQL API
The rest of the parameters are controlled by the tags. Since we chose a tag called param-portfolioId
, the report window asks the user to select a portfolio and passes that portfolio’s ID along with the parameters called params. That parameter is then used in the GraphQL call as a variable.
Step 3 - Testing the report in FA
In order to test the report, you need to go to FA and run the report against a portfolio.
As a result, jsreport will generate a PDF report using the template you built and return back a PDF file:
Conclusion
This tutorial series walked you through, step by step, how to create a simple dynamic report. All the relevant steps were included although this approach is not necessarily in all aspects the best possible way to create a report. For example, it is a better practice to store the data from FA under a variable instead of directly under req.data (e.g. it would be better to store under req.data.result1). By doing that, you can manage multiple datasets if needed.