Skip to content

Commit c50ed2c

Browse files
committed
On Recipients, store count of funders
ThreeSixtyGiving/grantnav#940
1 parent 02b96cd commit c50ed2c

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

datastore/db/models.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from django.db.utils import DataError
99
from django.utils import timezone
1010

11+
from additional_data.sources.find_that_charity import non_primary_org_ids_lookup_maps
12+
1113

1214
class Latest(models.Model):
1315
"""Latest best data we have"""
@@ -277,6 +279,8 @@ def update_aggregate(self, grant):
277279
# "GBP": { "grants": 0, "total": 0, "avg": 0, min: 0, max: 0 } },
278280
# ...
279281
# },
282+
# This only covers common stats.
283+
# See classes that inherit this - they may override update_aggregate() and add more.
280284

281285
amount = grant["amountAwarded"]
282286
currency = grant["currency"]
@@ -373,6 +377,49 @@ class Meta:
373377

374378
non_primary_org_ids = ArrayField(models.TextField())
375379

380+
"""While collecting aggregate info on funders, we need to store some data temporarily that we don't want to store in the database.
381+
This stores all primary ids so we can count unique funders."""
382+
_aggregate_funders_primary_ids = set()
383+
"""While collecting aggregate info on funders, we need to store some data temporarily that we don't want to store in the database.
384+
This stores information by currency."""
385+
_aggregate_funders_currencies = {}
386+
387+
def update_aggregate(self, grant):
388+
# Step 1: Call parent
389+
super().update_aggregate(grant)
390+
391+
# Step 2: update _aggregate_funders_* vars with info from this grant
392+
# This function is called repeatedly from datastore/db/management/commands/manage_entities_data.py
393+
# and it's inefficient to call non_primary_org_ids_lookup_maps every time.
394+
# But after discussion with MW that is ok.
395+
(
396+
non_primary_to_primary_org_ids_lookup,
397+
primary_to_non_primary_org_ids_lookup,
398+
) = non_primary_org_ids_lookup_maps()
399+
currency = grant["currency"]
400+
if currency not in self._aggregate_funders_currencies:
401+
self._aggregate_funders_currencies[currency] = {
402+
"funders_primary_ids": set(),
403+
}
404+
for funder in grant["fundingOrganization"]:
405+
# If the org-id provided is a non-primary org-id return the primary
406+
# otherwise return the specified org-id
407+
funder_primary_id = non_primary_to_primary_org_ids_lookup.get(
408+
funder["id"], funder["id"]
409+
)
410+
self._aggregate_funders_primary_ids.add(funder_primary_id)
411+
self._aggregate_funders_currencies[currency]["funders_primary_ids"].add(
412+
funder_primary_id
413+
)
414+
415+
# Step 3: copy info from _aggregate_funders_* vars to aggregate for saving to the database
416+
self.aggregate["funders"] = len(self._aggregate_funders_primary_ids)
417+
418+
for currency_id, currency_data in self._aggregate_funders_currencies.items():
419+
self.aggregate["currencies"][currency_id]["funders"] = len(
420+
self._aggregate_funders_currencies[currency_id]["funders_primary_ids"]
421+
)
422+
376423

377424
class Funder(Entity):
378425
class Meta:

0 commit comments

Comments
 (0)