############################# GivingTypes Python Script ############################# .. seealso:: :doc:`View the entire code file` This report displays three tables for three different date ranges: Year to Date, Last 30 Days, and Last 365 Days. The rows in each table show different Types of Contributions such as: Online, Recurring, Mobile, Offering plate, Mission Trips, Bank Drafts, Stock, and Non-Tax Deductible. The rows add up to a Total row at the bottom of each table. There are three columns in each table for three different sets of Funds: All Funds, Main Fund, and Other. Before this report can run, the :doc:`GivingTypesDataPython` must run to collect and cache the data. Once done, the report can be run multiple times by multiple users and this pre-collected data allows each run to be fast. Explanation of the Code ==================================== .. literalinclude:: Files/Content/GivingTypesData.py :lines: 1-3 :linenos: | ``Line 1`` limits only those users with the role Finance to run this script. | ``Line 3`` allows the code to use .NET DateTime functionality | Initialize ==================================== .. literalinclude:: Files/Content/GivingTypes.py :lines: 3-29 :lineno-start: 5 :linenos: This code initializes the following global variables. IsAdmin Allows the final report to have two versions: one for Admins who have links to special validation reports and the other for non-Admins without the links. .. seealso:: :func:`model.UserIsInRole`. Shell The main HTML template used to wrap the report. This fetches the text content from the file. .. seealso:: :func:`model.TextContent`. TablePattern The main HTML table template for the three date range tables in the report. Sql This SQL script generates the data used to populate the figures in the rows and columns of the report. LookupData A DynamicData object which holds the name/value pairs of the Sql above. .. seealso:: :func:`q.SqlNameValues`. Base A DynamicData object which will hold the common SearchParameters for every Contribution Type, including the date range. RowOrder An array of names which defines the order in which the various RowTypes (contribution categories) appear in the report tables. DateRanges An array of arrays which define the order of the date ranges, and their labels, uses for each table. Utility Functions ====================== .. literalinclude:: Files/Content/GivingTypes.py :lines: 31-38 :lineno-start: 31 :linenos: There are two utility functions defined: the first is `Percent` to compute a percentage of total and the second is `FormatNumber` which inserts commas and a number of decimal places of precision for display in the report. Both functions take measures take care to prevent errors avoiding divide by zero and returning an empty string when the result is zero. BuildRow ============ .. literalinclude:: Files/Content/GivingTypes.py :lines: 40-66 :lineno-start: 40 :linenos: The `BuildRow` function constructs an individual row for the report using the `rowType` and `dateRange` values passed into the function. The function uses the `LookupData` dictionary to find the appropriate numbers for the row. On ``Line 47``, the `rowType` name is converted to a suitable label for the row using a builtin function to insert spaces for the report's display. .. seealso:: :func:`model.SpaceCamelCase`. ``Lines 48-49`` avoids displaying rows with no values to display. ``Lines 50-54`` create a template for the HTML table row using named replacement sections. Note that a multi-line string is used, made possible with the triple quotes ``'''``. ``Lines 55-64`` creates an expanded version of the row tempate for Admins with links to validation reports. ``Line 65`` delivers the populated row using the format function to do the named replacements. Note that the Python `format` function works for both the expanded row or for the simpler row, even though the simpler row has fewer replacements. This is possible because unused named arguments are ignored. BuildTotalRow ============== .. literalinclude:: Files/Content/GivingTypes.py :lines: 68-83 :lineno-start: 68 :linenos: The `BuildTotalRow` function works in a similar way to the `BuildRow` function but for the final Total row for the table for a particular dateRange. BuildTableRows =============== .. literalinclude:: Files/Content/GivingTypes.py :lines: 85-91 :lineno-start: 85 :linenos: The `BuildTableRows` function constructs all of the rows for a table for a particular dateRange. The function loops rowType through the RowOrder array constructing each row to append to the `rows` variable. The function returns all rows ready for insertion to the table for a particular dateRange. BuildTables ============ .. literalinclude:: Files/Content/GivingTypes.py :lines: 93-98 :lineno-start: 93 :linenos: The `BuildTables` function loops through each dateRange in the DateRanges array, fetching all the rows with `BuildTableRows` using the DateRange name (``dateRange[0]``). Then, using the `TablePattern`, constructs the final table using the label (``dateRange[1]``) and the rows previously created. The function appends all the tables together and returns that result. Print the report ================ .. literalinclude:: Files/Content/GivingTypes.py :lines: 100 :lineno-start: 100 :linenos: ``Line 100`` inserts the three tables returned by the `BuildTables` function into the Shell and prints the final report.