######################################## GivingTypesData Python Script ######################################## .. seealso:: :doc:`View the entire file of code` Automate this Script ===================== To get this script to run every morning automatically, you can put it into the `MorningBatch` Python script. Open the existing or create a new Python script called `MorningBatch`. Add the following line of code. .. code:: python model.CallScript("GivingTypesData") Save the script. It will run the next morning between 4:30 AM and 5:30 AM. Of course, you can always manually run this script whenever you want. .. seealso:: :func:`model.CallScript` Explanation of the Code ==================================== The goal of this code is to create ContributionTags that categorize contributions into various Type categories such as: Online, Recurring, Mobile, Offering plate, Mission Trips, Bank Drafts, Stock, and Non-Tax Deductible. These categories should not overlap; a Priority scheme is used to decide the single category for a contribution that may fit into more than one Type. This way, the total of Types should reconcile with the sum of contributions. The code further divides each category into three different date ranges and three different fund sets. The final report contains three tables for the three date ranges. Each row in a table represents a summary of a different Type of contributions with three columns for different fund sets. These Contribution Tags become a snapshot, produced at least once a day during the morning batch, allowing the final report to render swiftly. .. 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/GivingTypesData.py :lines: 5-19 :lineno-start: 5 :linenos: This code initializes global variables: MaxDate The the last date for any contribution to be reported on. The current date is used. NameOfChurch Used later to execute particular, church specific lines of code. .. seealso:: :func:`Setting` GivingTypesData A DynamicData object which will contain all of the SearchParameters and store them in a file with the run date. ValidationReportList An array (list) of lines of HTML used to display a validation report at the end of the script. Priority `Priority` tracks the creation order as the various SearchParameters build ContributionTags. Base A DynamicData object which will hold the common SearchParameters for every Contribution Type, including the date range. .. seealso:: :func:`model.DynamicData` ``Lines 13-15`` set the date range used for the Base to the Last 365 days. This range is inclusive of any contribution in the other date ranges since they are shorter. ``Lines 16-19`` sets the ``Base.FromAmount`` to 0 to exclude negative contributions. If your church needs negative contributions because of historical data that used negative contributions for reversals, then change the name of the church to your church (found in the Settings on the Admin menu). CreateDateRangeTags ==================================== .. literalinclude:: Files/Content/GivingTypesData.py :lines: 21-33 :lineno-start: 21 :linenos: ``Lines 21-33`` define a function called `CreateDateRangeTags`. A DynamicData instance called `SearchParameters` is created and defines the date ranges. The search parameter ``NonTaxDed = -1`` allows all contributions to be returned for each date range. This is required since the default is Tax-Deductible. The function creates the three date range ContributionTags, modifying the MinDate for each range. ``GtrYtd`` (year to date), ``Gtr30`` (last 30 days), and ``Gtr365`` (last 365 days). A call to ``CreateContributionTag`` passes the name of the tag and SearchParameters as arguments. .. seealso:: :func:`model.CreateContributionTag` NextPriority ==================================== .. literalinclude:: Files/Content/GivingTypesData.py :lines: 35-38 :lineno-start: 35 :linenos: ``Lines 35-38`` define a function called `NextPriority` which increments a global variable named `Priority` in the function call. `Priority` prevents a single contribution from falling into more than one contribution Type category on the final report. Lower numbers take priority over higher numbers within a fund set column. ``Line 36`` allows the global variable `Priority` to be assigned to within the function. Normally in Python functions all variables are local to the function and although global variables can be read and used within a function, they cannot be assigned to. CreateTag ================================ .. literalinclude:: Files/Content/GivingTypesData.py :lines: 40-48 :lineno-start: 40 :linenos: ``Lines 40-48`` define a function called `CreateTag` which creates a ContributionTag controlled by the `searchParameters` passed into the function. ``Line 41`` constructs `TagName` using the prefix ``Gt``, the `fundSet`, and the `typeCategory`. The fundSet is one of: ``AllFunds``, ``MainFund``, and ``Other`` defining the three main columns of the report. ``Line 42`` constructs `NamePriority` from `TagName` and Priority uniquely identifying a unique set of SearchParameters. When adding to the same tag with a different search, the TagName stays the same, but the NamePriority is unique because Priority is unique for each search section. So a single TypeCategory can contain more than one Priority when multiple searches are used to construct and then add to the RowType tag. The last two lines of the function save information to the ValidationReportList which is displayed on-screen when a manual run is complete. CreateTags ============================== .. literalinclude:: Files/Content/GivingTypesData.py :lines: 50 :lineno-start: 50 :linenos: ``Lines 50-173`` define a function called `CreateTags`. Plural because this function creates all of the tags needed for a given `fundSet` which defines a column in the report. The singular function `CreateTag` is called in multipe sections. Before we move on to the various sections, the following will help you understand what what we mean by section in this function. Within the `CreateTags` function, there are multiple sections separated by blank lines. Each section will either create a new tag or add to an existing tag. A section starts with an assignment to `RowType` which is associated with a row in the final report. Then the `SearchParameters` for the `RowType` are built. Finally, the section ends with a call to `CreateTag`. Some sections are preceded with the comment, ``# church specific``. If this comment is present, then there may not be any results for this `RowType` for your church. As such, the section can be deleted or modified for your church. The order of execution of the various sections is significant. Some contributions can fit into the SearchParameters for different sections. However, it is important, in the final report, that a given contribution appear in only one row. The lower priority numbers take precedence over higher numbers for a given column's FundSet. For example, if a contribution matches the SearchParameters in both priority 103 and 104 for two different RowTypes, then in the final report, the gift will only show up in Priority 103 for the first RowType and not in 104 the latter RowType. This way, the sum of the individual lines will match the Total line. You should take care to decide which RowType is more important to associate with a contribution and place the section for the more important RowType ahead of another possible RowType. The row order for dispay on the final report is controlled independantly from this priority ordering scheme. .. literalinclude:: Files/Content/GivingTypesData.py :lines: 51-55 :lineno-start: 51 :linenos: **Mobile** ``Lines 51-55`` create a tag called `Mobile` which includes contributions coming from the TouchPoint Mobile app (``SearchParameters.Source = 1``). Note ``Line 52`` which is used at the begining of each search section. The call to ``model.DynamicData(Base)`` creates a new set of search parameters using ``Base`` as the starting point. Note the call to `NextPriority` on ``Line 53``. Each search section calls this function to increment the Priority which is what makes it unique to each search. **MissionTrip** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 57-69 :lineno-start: 57 :linenos: ``Lines 57-61`` create a tag called `MissionTrip`. It uses the contribution description starting with ``MissionTrip: org%``. The ``%`` at the end matches anything that follows. Touchpoint's built-in Mission Trip support does this so that this will work for any church. ``Lines 63-69`` add to the tag called `MissionTrip`. Note the AddToTag on ``Line 67``. It uses a church specific BundleType called ``Mission Trip Transaction``, which requires you to create this BundleType for entering Mission Trip gifts. This section of code is only needed if you enter Mission Trip support gifts without using TouchPoint's support for Mission Trip Giving exclusively. **Online** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 71-93 :lineno-start: 71 :linenos: ``Lines 71-76`` create a tag called `Online`. These come from the TouchPoint Mobile App (``Source = 1``) and have a Transaction Description of ``Online Giving``. However, The ``Mobile`` tag already contains these. ``Lines 78-85`` add to the tag called `Online`. These do not come from the Touchpoint Mobile App (``Source = 0``). And The BundleType is ``Online``. When a gift occurs online, Online Bundles are created automatically by Touchpoint. But those gifts with a TransactionDesc of ``Recurring Giving`` are excluded as they need to be categorized separately. .. seealso:: :func:`model.CreateContributionTag` about using the ``<>`` prefix for the TransactionDesc search parameter. ``Lines 87-93`` add to the tag called `Online` with a church specific search. This search finds contributions in either of the two bundle types ``Manual Credit Cards`` or ``Payroll Deductions``. For this code to produce results, you are required to create new BundleTypes and enter the appropriate contributions into those bundle types. **Recurring** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 95-99 :lineno-start: 95 :linenos: ``Lines 95-99`` create a tag called `Recurring`. All recurring gifts will have a Transaction table row with ``Recurring Giving`` in the TransactionDesc column. **SundayMainWorship** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 101-105 :lineno-start: 101 :linenos: ``Lines 101-105`` create a tag called `SundayMainWorship`. The three standard BundleTypes used for offering plate donations are ``Generic Envelopes``, ``Loose Checks and Cash``, and ``Preprinted Envelopes`` **Church Specific BundleType Tags** The following sections through ``Line 155`` are all church specific. All of these sections work by using a custom BundleType which is used to identify the contribution RowTypes for this report. You can either create these new BundleTypes and start posting contributions to that Bundle or you can delete these sections for your church. .. literalinclude:: Files/Content/GivingTypesData.py :lines: 107-113 :lineno-start: 107 :linenos: ``Lines 108-113`` add to the tag called `SundayMainWorship` with a church specific search. And requires a BundleType called ``Sunday Main Worship``. .. literalinclude:: Files/Content/GivingTypesData.py :lines: 115-155 :lineno-start: 115 :linenos: The different sections above all require creating BundleTypes of the name referred to in the SearchParameters.BundleTypes assignment. The exception is ``Line 126`` which contains two possibilities, create a BundleType for just one of these. **NonTaxDeductible** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 157-161 :lineno-start: 157 :linenos: ``Lines 157-161`` create a tag called `NonTaxDeductible`. The ``SearchParameters.NonTaxDed = 1`` does the trick here. **The Unknown Tag** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 163-168 :lineno-start: 163 :linenos: ``Lines 163-168`` create a tag called `Unknown`. This search should not contain any contributions and is meant to catch anything that slips through the cracks. The search does this with the line ``SearchParameters.ContributionTags = "<>Gt{}-%".format(fundSet)``. In other words, it finds contributions that do not already have a contribution tag for the appropriate fundSet. .. seealso:: :func:`model.CreateContributionTag` for the description of the ContributionTags search parameter. If the tag is not empty, then those contributions have not been considered in the previous sections and you need to look closely at them to figure where they should go and what search parameters will work. Or you may need to create one or more new tags to hold these in logical groupings. **The Total Tag** .. literalinclude:: Files/Content/GivingTypesData.py :lines: 170-174 :lineno-start: 170 :linenos: ``Lines 170-174`` create a tag called `Total`. This tag should contain the total of all the previous tags since it does not have any search parameters except for the FundIds for the particular column. This ends the explanation of the `CreateTags` function. Build the Three Columns for the Report ========================================================= The next lines of code define a function called `CreateFundSetColumns` which makes three calls to the `CreateTags` function, one call for each FundSet/column. Generally speaking, the first column is intended to be for giving to any of the church's Funds. The second column is intended to be for the single default and main giving fund, such as General Tithe, or whatever you call it at your church. Then the third column is all the funds other than the main giving fund. This function has two paths of execution: one for a specific church, and one for a generic churches which may fit for your church. You may need to customize one of these two paths for your church based on your fund structure. You will notice that there are three different sets of Priority numbers starting with either: 100, 200, or 300. These numbers correspond to the three FundSets ``AllFunds``, ``MainFund``, and ``Other`` which also correspond to the three columns of the report. The first column's amounts for ``AllFunds`` should add to the sum of the second two columns. .. literalinclude:: Files/Content/GivingTypesData.py :lines: 176-206 :lineno-start: 176 :linenos: ``Lines 176-192`` This code path works for the named church only after it has been modified to fit your church. The FundIds are what are necessary. .. seealso:: If you are using custom Statements and CustomFundSets at your church: | :doc:`/Finance/CustomStatements` | :doc:`/CustomProgramming/TextScripts/CustomFundSets` | :func:`model.CustomStatementsFundIdList` ``Line 177`` allows the global variable `Priority` to be assigned to within the function. Normally in Python functions all variables are local to the function and although global variables can be read and used within a function, they cannot be assigned to. ``Lines 193-206`` This section works for the Generic funds which may or may not work for your church but is a good starting point. Wrapping it All Up =================== Now that all the global data is set and all the functions are defined, the real work starts here. All that remains to be done is to call the previously defined functions, and then display the validation report. .. literalinclude:: Files/Content/GivingTypesData.py :lines: 208-217 :lineno-start: 208 :linenos: ``Line 208`` removes the existing set of ContributionTags to make way for this new set. The tags to be removed start with ``Gt`` using the ``%`` wild card to match anything to the right of `Gt`. .. seealso:: :func:`model.DeleteContributionTags` Lines ``210-211`` call the two main functions, one to create the date range tags and the other to create all the tags for the three fund sets. ``Lines 213-214`` save the `GivingTypesData` DynamicData object to a text file called ``GivingTypesData``. This file contains a record of all the SearchParameters that were used to create the ContributionTags. The links in the displayed validation report use this file on the screen for each column/row/priority combination. ``Lines 216-217`` The last two lines display the validation report on the screen after joining the entire list of lines in `ValidationReportList` into a single string called `html`. The last thing is to view the Validation Report which should display on the screen if you have manually run this script. Each heading is a link that save the contributions found by each set of SearchParameters to an Excel file. This should be helpful when customizing and validating your report.