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.



Original Generated

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"));