Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/4718 pac snapshot #4767

Merged
merged 17 commits into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fec/data/templates/committees-single.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
aria-selected="true">Financial Summary</a>
{% if committee_type != 'I' %}
<ul>
{% if FEATURES.pac_snapshot %}<li><a href="#committee-snapshot">Committee snapshot</a></li>{% endif %}
<li><a href="#total-raised">Total raised</a></li>
<li><a href="#total-spent">Total spent</a></li>
<li><a href="#cash-summary">Cash summary</a></li>
Expand Down
214 changes: 214 additions & 0 deletions fec/data/templates/partials/committee/financial-summary.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,220 @@
{{ missing_transferred.missing_transferred_committee_message(former_committee_name, former_authorized_candidate_name, former_authorized_candidate_id) }}
</div>
{% endif %}
{% if FEATURES.pac_snapshot %}
<div class="entity__figure entity__figure--narrow" id="committee-snapshot">
patphongs marked this conversation as resolved.
Show resolved Hide resolved
<div class="heading--section">
<h3>Committee snapshot</h3>
</div>

{% set shared_circle_props = 'cx="21" cy="21" r="15.91549430918954"' %}
{% set shared_text_props = 'x="50%" y="57%"' %}
{% set coverage_str = totals.coverage_start_date|date ~' to ' ~totals.coverage_end_date|date %}

{% if totals.individual_contributions_percent %}
{% set rec_ind = totals.individual_contributions_percent|round|int %}
{% set rec_ind_class = 'raising' %}
{% set rec_ind_ring = '0 100' %}
{% set rec_ind_l = rec_ind ~'%' %}
{% if rec_ind > 100 %}
{% set rec_ind_l = '>100%' %}
{% set rec_ind_ring = '100 0' %}
{% elif rec_ind > 0 and rec_ind < 1 %}
{% set rec_ind_l = '<1%' %}
{% else %}
{% set rec_ind_ring = rec_ind ~ ' ' ~ (100 - rec_ind) %}
{% endif %}
{% else %}
{% set rec_ind_l = '!' %}
{% set rec_ind_ring = '0 100' %}
{% set rec_ind_class = '' %}
Comment on lines +62 to +65
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rfultz I think this applies to if it's 0 then give the "!" error state? Do we really want to do that anytime it's 0? Are there currently any errors thrown from the API right now when it can't be calculated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New code just committed includes == 0 values in the outer if statement

{% endif %}

{% if totals.party_and_other_committee_contributions_percent %}
{% set rec_com = totals.party_and_other_committee_contributions_percent|round|int %}
{% set rec_com_class = 'raising' %}
{% set rec_com_ring = '0 100' %}
{% set rec_com_l = rec_com ~'%' %}
{% if rec_com > 100 %}
{% set rec_com_l = '>100%' %}
{% set rec_com_ring = '100 0' %}
{% elif rec_com > 0 and rec_com < 1 %}
{% set rec_com_l = '<1%' %}
{% else %}
{% set rec_com_ring = rec_com ~ ' ' ~ (100 - rec_com) %}
{% endif %}
{% else %}
{% set rec_com_l = '!' %}
{% set rec_com_ring = '0 100' %}
{% set rec_com_class = '' %}
{% endif %}

{% if totals.contributions_ie_and_party_expenditures_made_percent %}
{% set dis_com = totals.contributions_ie_and_party_expenditures_made_percent|round|int %}
{% set dis_com_class = 'spending' %}
{% set dis_com_ring = '0 100' %}
{% set dis_com_l = dis_com ~'%' %}
{% if dis_com > 100 %}
{% set dis_com_l = '>100%' %}
{% set dis_com_ring = '100 0' %}
{% elif dis_com > 0 and dis_com < 1 %}
{% set dis_com_l = '<1%' %}
{% else %}
{% set dis_com_ring = dis_com ~ ' ' ~ (100 - dis_com) %}
{% endif %}
{% else %}
{% set dis_com_l = '!' %}
{% set dis_com_ring = '0 100' %}
{% set dis_com_class = '' %}
{% endif %}

{% if totals.operating_expenditures_percent %}
{% set dis_oe = totals.operating_expenditures_percent|round|int %}
{% set dis_oe_class = 'spending' %}
{% set dis_oe_ring = '0 100' %}
{% set dis_oe_l = dis_oe ~'%' %}
{% if dis_oe > 100 %}
{% set dis_oe_l = '>100%' %}
{% set dis_oe_ring = '100 0' %}
{% elif dis_oe > 0 and dis_oe < 1 %}
{% set dis_oe_l = '<1%' %}
{% else %}
{% set dis_oe_ring = dis_oe ~ ' ' ~ (100 - dis_oe) %}
{% endif %}
{% else %}
{% set dis_oe_l = '!' %}
{% set dis_oe_ring = '0 100' %}
{% set dis_oe_class = '' %}
{% endif %}

{# set the meters' max value to the greater of receipts or disbursements #}
{% if totals.fed_receipts and totals.fed_disbursements and totals.last_cash_on_hand_end_period %}
{% if totals.fed_receipts >= totals.fed_disbursements %}
{% set meters_max = totals.fed_receipts %}
{% else %}
{% set meters_max = totals.fed_disbursements %}
{% endif %}
{# but override both if COH is larger for some reason #}
{% if totals.last_cash_on_hand_end_period > meters_max %}
{% set meters_max = totals.last_cash_on_hand_end_period %}
{% endif %}
{% endif %}

{% if com_type_glossary and com_type_text %}
<p>Learn more about <span class="term" data-term="{{ com_type_glossary }}" title="Click to define" tabindex="0">{{ com_type_text }}</span> like {{ committee.name }}.</p>
{% endif %}
<div class="tag__category">
<div class="tag__item">Coverage dates: {{ coverage_str }}</div>
</div>
<div class="snapshot-summary">
<span class="t-data t-bold">Total receipts: <span class="t-normal">{{ totals.fed_receipts|currency }}</span></span>
<meter min="0" max="{{ meters_max }}" value="{{ totals.fed_receipts }}" title="US Dollars" data-cat="raising"></meter>
<span class="t-data t-bold">Total disbursements: <span class="t-normal">{{ totals.fed_disbursements|currency }}</span></span>
<meter min="0" max="{{ meters_max }}" value="{{ totals.fed_disbursements }}" title="US Dollars" data-cat="spending"></meter>
<span class="t-data t-bold">Cash on hand: <span class="t-normal">{{ totals.last_cash_on_hand_end_period|currency }}</span></span>
<meter min="0" max="{{ meters_max }}" value="{{ totals.last_cash_on_hand_end_period }}" title="US Dollars" data-cat="cash"></meter>
</div>
<div class="grid grid--2-wide">
<div class="grid__item">
<h4 class="t-centered">Money raised</h4>
<div class="grid grid--2-wide">
<div class="grid__item">
<figure>
<svg viewBox="0 0 42 42" class="donut {{ rec_ind_class }}" role="img" aria-labelledby="snap-raise-ind-t snap-raise-ind-d">
<title id="snap-raise-ind-t">Percent raised from individual conributions {{ coverage_str }}</title>
<desc id="snap-raise-ind-d">98% of money raised came from individual contributions</desc>
<circle class="center" {{ shared_circle_props|safe }}></circle>
<circle class="ring" {{ shared_circle_props|safe }}></circle>
<circle class="segment" {{ shared_circle_props|safe }} stroke-dasharray="{{ rec_ind_ring }}"></circle>
<g class="chart-text">
<text {{ shared_text_props|safe }}>{{ rec_ind_l }}</text>
</g>
</svg>
<figcaption>Percent raised in individual <span class="term" data-term="contribution" title="Click to define" tabindex="0">contributions</span></figcaption>
</figure>
</div>
<div class="grid__item">
<figure>
<svg viewBox="0 0 42 42" class="donut {{ rec_com_class }}" aria-labelledby="snap-raise-com-t snap-raise-com-d">
<title id="snap-raise-com-t">Percent raised from other federal political committees {{ coverage_str }}</title>
<desc id="snap-raise-com-d">0% of money raised came from other federal political committees</desc>
<circle class="center" {{ shared_circle_props|safe }}></circle>
<circle class="ring" {{ shared_circle_props|safe }}></circle>
<!-- The stroke-dashoffset should add up to 100, with the first value being the color -->
<circle class="segment" {{ shared_circle_props|safe }} stroke-dasharray="{{ rec_com_ring }}"></circle>
<text {{ shared_text_props|safe }}>{{ rec_com_l }}</text>
</svg>
<figcaption>Percent raised in contributions from other federal <span class="term" data-term="political committee" title="Click to define" tabindex="0">political committees</span></figcaption>
</figure>
</div>
</div>
</div>
<div class="grid__item">
<h4 class="t-centered">Money spent</h4>
<div class="grid grid--2-wide">
<div class="grid__item">
<figure>
<svg viewBox="0 0 42 42" class="donut {{ dis_com_class }}" role="img" aria-labelledby="snap-spend-com-t snap-spend-com-d">
<title id="snap-spend-com-t">Percent spent on contributions to other federal political committees {{ coverage_str }}</title>
<desc id="snap-spend-com-d">96% of money spent went to other federal political committees</desc>
<circle class="center"{{ shared_circle_props|safe }}></circle>
<circle class="ring"{{ shared_circle_props|safe }}></circle>
<circle class="segment" {{ shared_circle_props|safe }} stroke-dasharray="{{ dis_com_ring }}"></circle>
<g class="chart-text">
<text {{ shared_text_props|safe }}>{{ dis_com_l }}</text>
</g>
</svg>
<figcaption>Percent spent on contributions to other <span class="term" data-term="national committee" title="Click to define" tabindex="0">federal committees</span></figcaption>
</figure>
</div>
<div class="grid__item">
<figure>
<svg viewBox="0 0 42 42" class="donut {{ dis_oe_class }}" role="img" aria-labelledby="snap-spend-ox-t snap-spend-ox-d">
<title id="snap-spend-ox-t">Percent spent on operating expenditures {{ coverage_str }}</title>
<desc id="snap-spend-ox-d">96% of money spent on operating expenditures</desc>
<circle class="center" {{ shared_circle_props|safe }}></circle>
<circle class="ring" {{ shared_circle_props|safe }}></circle>
<!-- The stroke-dashoffset should add up to 100, with the first value being the color -->
<circle class="segment" {{ shared_circle_props|safe }} stroke-dasharray="{{ dis_oe_ring }}"></circle>
<text {{ shared_text_props|safe }}>{{ dis_oe_l }}</text>
</svg>
<figcaption>Percent spent on <span class="term" data-term="operating expenditures" title="Click to define" tabindex="0">operating expenditures</span></figcaption>
</figure>
</div>
</div>
</div>
</div>
<div class="footer-methodology">
<p class="t-note">
The percentages shown do not represent 100% of this committee's activity. Refer to the tables that follow for a complete breakdown of raising and spending.
</p>
<div>
<button class="button--alt js-methodology" data-a11y-dialog-show="methodology-committee-snapshot">Methodology</button>
</div>
</div>
<div class="js-modal modal" id="methodology-committee-snapshot" aria-hidden="true">
<div tabindex="-1" class="modal__overlay" data-a11y-dialog-hide=""></div>
<div role="dialog" class="modal__content" aria-labelledby="raised-modal-title">
<div role="document">
<button type="button" class="modal__close button--close--primary" data-a11y-dialog-hide="" title="Close this dialog window"></button>
<h2 id="raised-modal-title">Methodology</h2>
<strong>Receipts</strong>
<p>Percentage contributions from individuals</p>
<ul><li>Total individual contributions divided by total receipts (Form 3X Line 11(a)(iii) divided by Line 19)</li></ul>

<p>Contributions from party committees plus contributions from other federal committees divided by total receipts (Form 3X Line 11(b) + Line 11(c) divided by Line 19)</p>
<ul><li><strong>The language under the doughnut could be something like, "percent raised from contrbutions from PACS and party committees."</strong></li></ul>
<strong>Disbursements</strong>
<p>Percentage IEs, federal candidate contributions and party coordinated expenditures</p>
<ul><li>Contributions to federal candidates plus independent expenditures plus party coordinated expenditures divided by total disbursements (Form 3X Line 23 + 24 + 25 divided by Line 31)</li></ul>
<p>Percentage operating expenditures</p>
<ul><li>Total operating expenditures divided by total disbursements (Form 3X Line 21(c) divided by Line 31)</li></ul>
</div>
</div>
</div>
</div>
{# end pac_snapshot (next line) #}
{% endif %}
<div class="entity__figure entity__figure--narrow" id="total-raised">
<div class="heading--section heading--with-action">
<h3 class="heading__left">Total raised</h3>
Expand Down
81 changes: 81 additions & 0 deletions fec/data/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,11 +456,91 @@ def get_committee(committee_id, cycle):
sponsor_candidate["related_cycle"] = cycle if election_years else None
sponsor_candidates.append(sponsor_candidate)

# Human-friendly text and glossary links for the front-end
com_org_type = committee.get('organization_type')
com_com_type = committee.get('committee_type')
com_desig = committee.get('designation')
# The big "can't be" tests for the others
if com_org_type == 'C':
com_type_text = 'corporate'
com_type_glossary = 'Corporation'
elif com_org_type == 'W':
com_type_text = 'corporations without capital stock'
com_type_glossary = ''
elif com_org_type == 'L':
com_type_text = 'labor organization'
com_type_glossary = 'Labor organization'
elif com_org_type == 'M':
com_type_text = 'membership organization'
com_type_glossary = 'Membership organization'
elif com_org_type == 'T':
com_type_text = 'trade association'
com_type_glossary = 'Trade association'
elif com_org_type == 'V':
com_type_text = 'cooperatives'
com_type_glossary = ''
elif com_org_type == 'D':
com_type_text = 'leadership PACs'
com_type_glossary = ''
elif com_com_type == 'H':
com_type_text = '[H committee_type]'
com_type_glossary = ''
elif com_com_type == 'S':
com_type_text = '[S committee_type]'
com_type_glossary = ''
elif com_com_type == 'P':
com_type_text = '[P committee_type]'
com_type_glossary = ''
elif com_desig == 'B':
com_type_text = 'lobbyist-registrant PACs'
com_type_glossary = 'Lobbyist/Registrant PAC'
elif com_desig == 'D':
com_type_text = 'leadership PACs'
com_type_glossary = 'Leadership PAC'
elif com_desig == 'J':
com_type_text = 'joint fundraising committees'
com_type_glossary = 'Joint fundraising committee'
elif com_desig == 'A':
com_type_text = '[A designation]'
com_type_glossary = ''
elif com_desig == 'P':
com_type_text = '[P designation]'
com_type_glossary = ''
elif com_com_type == 'O':
com_type_text = 'super PACs'
com_type_glossary = 'Super PAC'
elif com_com_type == 'W':
com_type_text = 'hybrid PACs'
com_type_glossary = 'Hybrid PAC'
elif com_com_type == 'V':
com_type_text = 'hybrid PACs'
com_type_glossary = 'Hybrid PAC'
elif com_com_type == 'N':
com_type_text = 'political action committees'
com_type_glossary = 'Political Action Committee (PAC)'
elif com_com_type == 'Q':
com_type_text = 'political action committees'
com_type_glossary = 'Political Action Committee (PAC)'
elif com_com_type == 'U':
com_type_text = '[U committee_type]'
com_type_glossary = ''
elif com_com_type == 'I':
com_type_text = '[I committee_type]'
com_type_glossary = ''
elif com_com_type == 'Y':
com_type_text = 'party committees'
com_type_glossary = 'Party committee'
elif com_com_type == 'X':
com_type_text = 'party committees'
com_type_glossary = 'Party committee'

template_variables = {
"candidates": candidates,
"committee": committee,
"committee_id": committee_id,
"committee_type": committee["committee_type"],
"com_type_text": com_type_text,
"com_type_glossary": com_type_glossary,
patphongs marked this conversation as resolved.
Show resolved Hide resolved
"context_vars": context_vars,
"cycle": cycle,
"cycles": cycles,
Expand Down Expand Up @@ -559,6 +639,7 @@ def committee(request, committee_id):

cycle = request.GET.get("cycle", None)
committee = get_committee(committee_id, cycle)

return render(request, "committees-single.jinja", committee)


Expand Down
2 changes: 2 additions & 0 deletions fec/fec/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
'debts': bool(env.get_credential('FEC_FEATURE_DEBTS', '')), # TODO: debts dates
'map': bool(env.get_credential('FEC_FEATURE_HOME_MAP', '')),
'pac_party': bool(env.get_credential('FEC_FEATURE_PAC_PARTY', '')),
'pac_snapshot': bool(env.get_credential('FEC_FEATURE_PAC_SNAPSHOT', '')),
'presidential_map': bool(env.get_credential('FEC_FEATURE_PRESIDENTIAL_MAP', '')),
}

Expand All @@ -77,6 +78,7 @@
FEATURES['debts'] = True
FEATURES['map'] = True
FEATURES['pac_party'] = True
FEATURES['pac_snapshot'] = True
FEATURES['presidential_map'] = True

# Application definition
Expand Down
Loading