1 The PDF Document
The GLEIF balance sheet 2017
is a financial statement prepared for the Global Legal Entity
Identifier Foundation. This document reports the fundation's assets, liabilities and shareholders'
equity for the year 2017, compared to the year 2016.
2 The source code
Copy
/** * Function to generate the Balance Sheet in PDF format * * @param {date} pDateFecCierre Date of the last day of the period * @returns {pdf} */ function printBalance(pDateFecCierre){ /** * LOCAL FUNCTION: __isNumberNullFormat * * Local function to format a numeric value or return an empty string * when is null. * * @param {*} pNumber Numeric value * @param {*} pTabla Table being worked on * * @returns Returns the received value formatted and without decimals */ function __isNumberNullFormat(pNumber, pTable, pStrRegion) { return (pNumber == null ? "" : pTable.format(pNumber, pStrRegion, "%,.0f")); } /** * Define global values */ const COLOR_BLACK = "#000"; const COLOR_BLUE = "#44a8e3"; const COLOR_LEAD = "#efefef"; const DEFAULT_PADDING = "4pt, 0pt, 4pt, 0pt"; const DEFAULT_MARGIN = "0pt, 2pt, 0pt, 2pt"; const DEFAULT_FONT = "Noto Sans"; /** * Defines the balance sheet period */ var mIntPeriodo = new Ax.util.Date(pDateFecCierre).getFullYear(); /**========================================================================= * Getting data * ========================================================================= */ /** * Define the temporary tables to store and group the example data */ var mTmpTableGroups = Ax.db.getTempTableName("tmp_group"); var mTmpTableDetails = Ax.db.getTempTableName("tmp_details"); Ax.db.execute(`DROP TABLE IF EXISTS ${mTmpTableGroups}`); Ax.db.execute(`DROP TABLE IF EXISTS ${mTmpTableDetails}`); /** * Create tables for groups and details */ Ax.db.execute(` CREATE TEMP TABLE ${mTmpTableGroups} ( group smallint, desc char(50), tp smallint, notes char(4) ) WITH NO LOG; CREATE TEMP TABLE ${mTmpTableDetails} ( orden smallint, group smallint, assets char(50), notes char(4), import1 decimal(16,6), import2 decimal(16,6) ) WITH NO LOG; `); /** * Inserts example data into the temporary tables */ Ax.db.execute(` -- Group registration, to group the data INSERT INTO ${mTmpTableGroups} VALUES (1,'Current assets', 1, '4.4'); INSERT INTO ${mTmpTableGroups} VALUES (2,'Non-current assets', 1, NULL); INSERT INTO ${mTmpTableGroups} VALUES (3,'Liabilities and equity', 2, NULL); INSERT INTO ${mTmpTableGroups} VALUES (4,'Current liabilities', 2, NULL); INSERT INTO ${mTmpTableGroups} VALUES (5,'Non-current liabilities', 2, NULL); INSERT INTO ${mTmpTableGroups} VALUES (6,'Organizational capital', 2, '4.11'); -- Data record with the second value as group index INSERT INTO ${mTmpTableDetails} VALUES (1, 1 , 'Receivables from LEI issuer feeds', '4.1', 4889942, 1409636); INSERT INTO ${mTmpTableDetails} VALUES (2, 1 , 'Current financial assets', '4.2', 5217, 5203); INSERT INTO ${mTmpTableDetails} VALUES (3, 1 , 'Other assets', '4.3', 177236, 470701); INSERT INTO ${mTmpTableDetails} VALUES (4, 1 , 'Cash and cash equivalents', '4.4', 3323743, 5071643); INSERT INTO ${mTmpTableDetails} VALUES (1, 2 , 'Intangible fixed assets', '4.5', 397337, 146079); INSERT INTO ${mTmpTableDetails} VALUES (2, 2 , 'Tangible fixed assets', '4.6', 365818, 468347); INSERT INTO ${mTmpTableDetails} VALUES (3, 2 , 'Financial assets', '4.2', 123990, 108979); INSERT INTO ${mTmpTableDetails} VALUES (1, 4 , 'Payables due to vendors', '4.7', 808738, 853295); INSERT INTO ${mTmpTableDetails} VALUES (2, 4 , 'Liabilities due to Board Directors', '6.1', 29678, 74868); INSERT INTO ${mTmpTableDetails} VALUES (3, 4 , 'Deferred revenue', '4.8', 3958284, 2885533); INSERT INTO ${mTmpTableDetails} VALUES (4, 4 , 'Other financial liabilities', '4.9', 146650, 218892); INSERT INTO ${mTmpTableDetails} VALUES (5, 4 , 'Other payables', '4.10', 1172911, 671199); INSERT INTO ${mTmpTableDetails} VALUES (1, 5 , 'Provision for pension costs', '3.2', 22371, 39249); INSERT INTO ${mTmpTableDetails} VALUES (2, 5 , 'Payables due to vendors', '4.7', 74362, 100308); INSERT INTO ${mTmpTableDetails} VALUES (3, 5 , 'Financial liabilities', '4.9', 8098, 10892); INSERT INTO ${mTmpTableDetails} VALUES (4, 5 , 'Deferred subsidies', '3.5', 109098, 170552); INSERT INTO ${mTmpTableDetails} VALUES (1, 6 , 'Paid-in Foundation capital', NULL, 55927, 55927); INSERT INTO ${mTmpTableDetails} VALUES (2, 6 , 'Other reserves', NULL, 29514, -14912); INSERT INTO ${mTmpTableDetails} VALUES (3, 6 , 'Retained surplus', NULL, 2867652, 2614785); `); /** * Obtains data from tables with group structure */ var mRsTable = Ax.db.executeQuery(` ( SELECT g.tp, g.group, d.orden, d.assets desc, d.notes, d.import1, d.import2 FROM ${mTmpTableGroups} g INNER JOIN ${mTmpTableDetails} d ON g.group = d.group ) UNION ALL ( SELECT g.tp, g.group, 99 orden, g.desc, g.notes, SUM(d.import1) import1, SUM(d.import2) import2 FROM ${mTmpTableGroups} g LEFT JOIN ${mTmpTableDetails} d ON g.group = d.group GROUP BY 1, 2, 3, 4, 5 ) UNION ALL ( SELECT g.tp, 100 group, 100 orden, '' desc, '' notes, SUM(d.import1) import1, SUM(d.import2) import2 FROM ${mTmpTableGroups} g LEFT JOIN ${mTmpTableDetails} d ON g.group = d.group GROUP BY 1, 2, 3, 4, 5 ) ORDER BY 1, 2, 3 `); /**========================================================================= * Document development using SinglePageTemplate * ========================================================================= * * Define the page format */ var template = new Ax.fop.SinglePageTemplate("A4"); template.setRoot((root) => { // root.setDebug("*"); root.getSimplePageMaster().getRegionBefore().setExtent(2.0); root.getSimplePageMaster().getRegionAfter().setExtent(1.0); root.getSimplePageMaster().getRegionStart().setExtent(1.0); root.getSimplePageMaster() .getRegionEnd() .setExtent(1.0) .setReferenceOrientation(0); root.getSimplePageMaster().setMargins(0.5, 0.5, 1.0, 1.0); }); template.setEnd((end) => { /** * Defines a block to display the numbering and assigns the required * format to it */ var pagenumber = end.addBlock() .setFontFamily(DEFAULT_FONT) .setFontSize(9) .setTextAlign("start") .setFontWeight("bold"); /** * Assigns the page number and an internal left-hand spacing */ pagenumber.addInline() .putPageNumber() .setPaddingLeft(5); }); template.setBefore((before) => { /** * Defines a block to display the page header and assigns the text * "GLEIF Annual Report 2017" with the required formatting */ var header = before.addBlock() .setFontSize(7) .setFontFamily(DEFAULT_FONT); header.addBlock() .setTextAlign("right") .setBorderRightStyle("solid") .setBorderRightWidth("1pt") .addInline() .addText("GLEIF") .setColor(COLOR_BLUE) .setFontWeight("bold") .addInline() .addText(`Annual Report ${mIntPeriodo}`) .setColor(COLOR_BLACK) .setFontWeight("normal") .setPaddingRight("10pt"); /** * Define a block to display the balance sheet title and assign the * title text including the balance sheet period. */ var title = before .addBlock() .setFontSize(12) .setPaddingBottom("10pt") .setPaddingTop("20pt"); title.addInline() .addText("Balance Sheet") .setFontWeight("bold") .setColor(COLOR_BLUE) .addInline() .addText(`for the Period from January 1 to December 31, ${mIntPeriodo}`) .setColor(COLOR_BLUE) .setFontWeight("normal"); }); template.setBody((body) => { /** * Defines a table to work with grouped balance sheet data */ var tabla = body.addTable(); /** * Assign formats for the table, including a 3 pt top border. */ tabla.setFontFamily(DEFAULT_FONT) .setFontSize(9) .setBorderTopStyle("solid") .setBorderTopWidth("3pt"); /** * Define 7 columns in the work table, 4 for data and 3 for separations * with specific widths, formats and alignments. */ tabla.addColumn("Assets").setColumnWidth(6.5); tabla.addColumn().setColumnWidth(0.2); tabla.addColumn("Notes").setColumnWidth(2); tabla.addColumn().setColumnWidth(0.2); tabla.addColumn(`Dec. 31, ${mIntPeriodo}`) .setBackgroundColor(COLOR_LEAD) .setAlign("right"); tabla.addColumn().setColumnWidth(0.2); tabla.addColumn(`Dec. 31, ${mIntPeriodo -1}`) .setAlign("right"); /** * Gets the table header to assign spaces to it */ tabla.getHeader() .getColumns() .forEach((col) => { col.getCell() .setPaddingBottom(15) .setPaddingTop(5); }); /** * Add a row in the body, to represent the type of currency * and each cell is assigned a specific format. */ tabla.getBody() .addRow("", "", "", "", "US$", "", "US$") .forEach((cell) => { if (cell.getColumnIndex() % 2 == 0) { cell.setColor(COLOR_BLUE) .setBorderTopStyle("solid") .setPadding("5pt, 0pt, 5pt, 0pt") } }); /** * Run the RS of the data */ for (var mRow of mRsTable) { /** * For each record a row is added to the work table with * the corresponding data. * The value of the amounts are formatted */ tabla.getBody() .addRow( mRow.get("desc"), "", mRow.get("notes"), "", __isNumberNullFormat(mRow.get("import1"), tabla, "US"), "", __isNumberNullFormat(mRow.get("import2"), tabla, "US") ) /** * For each cell of the inserted row a format is assigned */ .forEach((cell) => { /** * If the modulus of the index is 0, we are in a data column * and not a separation column, so it is assigned edges. */ if (cell.getColumnIndex() % 2 == 0) { cell.setPadding(DEFAULT_PADDING) .setMargin(DEFAULT_MARGIN) .setBorderTopStyle("solid") .setBorderBottomStyle("solid"); } /** * Rows with an index greater than 3 (numerical values) * are given a right alignment. */ if (cell.getColumnIndex() > 3) { cell.setTextAlign("right"); } /** * Records with "order" equal to 99 or 100 correspond to * subtotals of the work table, so they have a different * format. */ if (mRow.get("orden") == 99 || mRow.get("orden") == 100) { /** * All columns, except "Notes", have a "bold" font. */ if (cell.getColumnIndex() != 2) { cell.setFontWeight("bold"); } /** * All subtotals (index greater than 3), and with a * value other than null, have a border with greater * thickness and spacing. */ if ( cell.getColumnIndex() > 3 && cell.getColumnIndex() % 2 == 0 && mRow.get("import1") != null ) { cell.setBorderTopStyle("solid") .setBorderTopWidth("2pt") .setMargin("0, 0, 10pt, 0"); } } }); } }); /** * Gets the template of the created FOP */ var fop = template.toFOP(); /** * Create and return PDF */ return new Ax.fop.Processor().transform(fop); }; /** * Execute the function to get the PDF template */ return printBalance(new Ax.util.Date("31-12-2017"));