Skip to content

Commit

Permalink
use query_all to get all records (#1589)
Browse files Browse the repository at this point in the history
* use query_all to get all records

* cast uuid field

* throw some to-dos in for future self

* use bulk query method

* handle badly formatted uuids from SF (and log them)

* handle blank book (and log)

* code cleanup, get current year to replace with new data

* add sentry cron monitor - run daily
  • Loading branch information
mwvolo authored Oct 29, 2024
1 parent 640cf17 commit baa80d2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 39 deletions.
2 changes: 1 addition & 1 deletion openstax/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@
('0 2 * * *', 'django.core.management.call_command', ['delete_resource_downloads']),
('0 6 * * *', 'django.core.management.call_command', ['update_resource_downloads']),
('0 0 8 * *', 'django.core.management.call_command', ['update_schools_and_mapbox']),
# ('0 0 1 * *', 'django.core.management.call_command', ['update_opportunities']),
('0 0 * * *', 'django.core.management.call_command', ['update_opportunities']),
('0 10 * * *', 'django.core.management.call_command', ['update_partners']),
]

Expand Down
95 changes: 57 additions & 38 deletions salesforce/management/commands/update_opportunities.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,79 @@
import datetime
import uuid
from django.core.management.base import BaseCommand
from salesforce.models import AdoptionOpportunityRecord
from salesforce.salesforce import Salesforce
import sentry_sdk
from sentry_sdk.crons import monitor


class Command(BaseCommand):
help = "update book adoptions from salesforce.com for getting adoptions by account uuid"

def handle(self, *args, **options):
with Salesforce() as sf:
now = datetime.datetime.now()
def query_base_year(self, base_year, adoption_status):
query = ("SELECT Id, "
"Adoption_Type__c, "
"Base_Year__c, "
"Confirmation_Date__c, "
"Confirmation_Type__c, "
"How_Using__c, "
"Savings__c, "
"Students__c, "
"Opportunity__r.Book__r.Name, "
"Opportunity__r.StageName, "
"Opportunity__r.Contact__r.Accounts_UUID__c "
"FROM Adoption__c WHERE "
"Base_Year__c = {} AND Opportunity__r.Contact__r.Accounts_UUID__c != null "
"AND Confirmation_Type__c = 'OpenStax Confirmed Adoption' "
"AND Opportunity__r.Contact__r.Adoption_Status__c = '{}'").format(base_year, adoption_status)

base_year = now.year
if now.month < 7: # if it's before July, the base year is the previous year (4/1/2024 = base_year 2023)
base_year -= 2
else:
base_year -= 1
return query

# TODO: I don't think this is needed - updating the records should be fine, and keeps something on the form
# TODO: for the user. Eventually, this should update CMS DB with updated data if they fill out the form
# truncate the table
# AdoptionOpportunityRecord.objects.all().delete()

# then we will get any new records
query = ("SELECT Id, "
"Adoption_Type__c, "
"Base_Year__c, "
"Confirmation_Date__c, "
"Confirmation_Type__c, "
"How_Using__c, "
"Savings__c, "
"Students__c, "
"Opportunity__r.Book__r.Name, "
"Opportunity__r.StageName, "
"Opportunity__r.Contact__r.Accounts_UUID__c "
"FROM Adoption__c WHERE "
"Base_Year__c = {} AND Opportunity__r.Contact__r.Accounts_UUID__c != null "
"AND Confirmation_Type__c = 'OpenStax Confirmed Adoption' "
"AND Opportunity__r.Contact__r.Adoption_Status__c != 'Current Adopter'").format(base_year)

response = sf.query(query)
records = response['records']

for record in records:
def process_results(self, results):
for i, record in enumerate(results):
try:
opportunity, created = AdoptionOpportunityRecord.objects.update_or_create(
opportunity_id=record['Id'],
defaults={'account_uuid': record['Opportunity__r']['Contact__r']['Accounts_UUID__c'],
account_uuid=uuid.UUID(record['Opportunity__r']['Contact__r']['Accounts_UUID__c']),
book_name=record['Opportunity__r']['Book__r']['Name'],
defaults={'opportunity_id': record['Id'],
'opportunity_stage': record['Opportunity__r']['StageName'],
'adoption_type': record['Adoption_Type__c'],
'base_year': record['Base_Year__c'],
'confirmation_date': record['Confirmation_Date__c'],
'confirmation_type': record['Confirmation_Type__c'],
'how_using': record['How_Using__c'],
'savings': record['Savings__c'],
'students': record['Students__c'],
'book_name': record['Opportunity__r']['Book__r']['Name'],
'students': record['Students__c']
}
)
opportunity.save()
except ValueError:
sentry_sdk.capture_message("Adoption {} has a badly formatted Account UUID: {}".format(record['Id'], record['Opportunity__r']['Contact__r']['Accounts_UUID__c']))
except TypeError:
sentry_sdk.capture_message("Adoption {} exists without a book".format(record['Id']))

@monitor(monitor_slug='update-opportunities')
def handle(self, *args, **options):
with Salesforce() as sf:
now = datetime.datetime.now()

base_year = now.year
if now.month < 7: # before july, current year minus 2 (4/1/2024, base year = 2023)
base_year -= 2
else: # otherwise, current year minus 1 (10/1/2024, base year = 2023)
base_year -= 1

# first, we get last year's records
# these people need to renew, show them what we know from last base year confirmed adoption
query = self.query_base_year(base_year, "Past Adopter")

results = sf.bulk.Adoption__c.query(query)
self.process_results(results)

# now get this year's records - this will ensure accurate data on the renewal form if already filled out
current_base_year = base_year + 1
updated_records = self.query_base_year(current_base_year, "Current Adopter")

results = sf.bulk.Adoption__c.query(updated_records)
self.process_results(results)

0 comments on commit baa80d2

Please sign in to comment.