GivingHouseholds Python Script

To install this script, copy all of the code below. Create a new Python document in Special Content using the name GivingHouseholds. Then paste the code into editor and save.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#roles=Finance

from System import DateTime

IsAdmin = model.UserIsInRole("Admin")

Html = model.TextContent('GivingHouseholdsHtml')

# Read from cached data created during morning batch
data = model.DynamicDataFromJson(model.TextContent('GivingHouseholdsData'))

def FmtNumber(value, ndecimals):
    fmt = "N{}".format(ndecimals)
    return "" if value== None else value.ToString(fmt)

def SafeDiv(num, dem):
    return float(num) / dem if dem > 0 else 0.0

def NewRowAdmin(row, combined, days, querycode):
    isheadcode = "AND IsHeadOfHousehold = 1"
    isfamilygiver = "AND IsFamilyGiver( Days={}, FundIdOrBlankForAll='180' ) = 1".format(days)
    return '''<tr>
        <th>{}</th>
        <td><a href="/QueryCode?code={} {}" target="validate">{:,d}</a></td>
        <td><a href="/QueryCode?code={} {} {}" target="validate">{:,d}</a></td>
        <td>{:.1%}</td>
        <td><a href="/Contributions?dt1={}&dt2={}&fundid=180&taxnontax=Both&filterbyactivetag=true&setQueryTag={}" target="validate">{:,.2f}</a></td>
        <td>{:.1%}</td>
        <td>{:.1%}</td>
        <td>{:,.2f}</td>
        </tr>\n'''.format(
           model.SpaceCamelCase(row.RowType), 
           querycode, isheadcode, row.Households, 
           querycode, isheadcode, isfamilygiver, row.Cnt, 
           SafeDiv(row.Cnt, row.Households), 
           row.StartDt, row.EndDt, row.Tag, row.Amount, 
           SafeDiv(row.Households, combined.Households),
           SafeDiv(row.Amount, combined.Amount),
           SafeDiv(row.Amount, combined.Cnt))

def NewRow(row, combined):
    return '''<tr>
        <th>{}</th>
        <td>{:,d}</td>
        <td>{:,d}</td>
        <td>{:.1%}</td>
        <td>{:,.2f}</td>
        <td>{:.1%}</td>
        <td>{:.1%}</td>
        <td>{:,.2f}</td>
        </tr>\n'''.format(
           model.SpaceCamelCase(row.RowType), 
           row.Households, 
           row.Cnt, 
           SafeDiv(row.Cnt, row.Households), 
           row.Amount, 
           SafeDiv(row.Households, combined.Households),
           SafeDiv(row.Amount, combined.Amount),
           SafeDiv(row.Amount, combined.Cnt))

def GetTable(data, label, querycode):
    table = '''
    <table class="table" border="1" style="width: auto;">
    <thead>
    <tr>
        <th class="large">{}</th>
        <th align="right">Total Households</th>
        <th align="right">Households Who Gave</th>
        <th align="right">% Households Who Gave</th>
        <th align="right">Amount Given ($)</th>
        <th align="right">% of Total Givers</th>
        <th align="right">% of Gifts</th>
        <th align="right">Average Household Giving ($)</th>
    </tr>
    </thead>
    <tbody>
        {}
        {}
        {}
    </tbody>
    </table>
    '''

    if IsAdmin:
        return table.format(label,
                NewRowAdmin(data.Member, data.Combined, data.Days, querycode.Members),
                NewRowAdmin(data.NonMember, data.Combined, data.Days, querycode.NonMembers),
                NewRowAdmin(data.Combined, data.Combined, data.Days, querycode.Combined))

    return table.format(label,
            NewRow(data.Member, data.Combined),
            NewRow(data.NonMember, data.Combined),
            NewRow(data.Combined, data.Combined))

ytd = GetTable(data.Ytd, 'Year to Date', data.QueryCode)
d30 = GetTable(data.D30, 'Last 30 Days', data.QueryCode)
d365 = GetTable(data.D365, 'Last 365 Days', data.QueryCode)

print Html.replace('<!--ytd-->', ytd).replace('<!--d30-->', d30).replace('<!--d365-->', d365)

# the following is only used in development 
#Html = model.Content('C:/dev/bvcmsdocs/source/CustomProgramming/Python/Scripts/Giving/Households/Files/Content/GivingHouseholdsHtml.text.html')
#runfrom=C:/dev/bvcmsdocs/source/CustomProgramming/Python/Scripts/Giving/Households/Files/Content/GivingHouseholds.py