diff --git a/src/main/java/com/impactupgrade/nucleus/client/SfdcClient.java b/src/main/java/com/impactupgrade/nucleus/client/SfdcClient.java index 505bf5cce..930ca9558 100644 --- a/src/main/java/com/impactupgrade/nucleus/client/SfdcClient.java +++ b/src/main/java/com/impactupgrade/nucleus/client/SfdcClient.java @@ -656,6 +656,7 @@ public List getDonatingContacts(Calendar updatedSince) updatedSinceClause = "SystemModStamp >= " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(updatedSince.getTime()); } queryResults.add(queryDonatingContacts(updatedSinceClause)); + queryResults.add(queryDonatingAccountsContacts(updatedSinceClause)); if (updatedSince != null) { updatedSinceClause = "Id IN (SELECT ContactId FROM CampaignMember WHERE SystemModStamp >= " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(updatedSince.getTime()) + ")"; @@ -666,8 +667,12 @@ public List getDonatingContacts(Calendar updatedSince) } protected QueryResult queryDonatingContacts(String updatedSinceClause) throws ConnectionException, InterruptedException { - String updatedContactsQuery = "select Id from Contact " + - "where " + updatedSinceClause; + if (Strings.isNullOrEmpty(updatedSinceClause)) { + env.logJobWarn("no filter provided; out of caution, skipping the query to protect API limits"); + return new QueryResult(); + } + String updatedContactsQuery = "SELECT Id FROM Contact " + + "WHERE " + updatedSinceClause; List updatedContacts = queryListAutoPaged(updatedContactsQuery); if (CollectionUtils.isEmpty(updatedContacts)) { return new QueryResult(); @@ -676,10 +681,10 @@ protected QueryResult queryDonatingContacts(String updatedSinceClause) throws Co .map(sObject -> "'" + sObject.getField("Id") + "'") .collect(Collectors.joining(",")); - String totalOpportunityAmountQuery = "select ContactId, SUM(Amount) TotalAmount from Opportunity " + - "where ContactId in (" + updatedContactIds + ")" + - "group by ContactId " + - "having sum(Amount) > 0"; + String totalOpportunityAmountQuery = "SELECT ContactId, SUM(Amount) TotalAmount FROM Opportunity " + + "WHERE ContactId IN (" + updatedContactIds + ")" + + "GROUP BY ContactId " + + "HAVING SUM(Amount) > 0"; List aggregateResults = queryListAutoPaged(totalOpportunityAmountQuery); if (aggregateResults.isEmpty()) { return new QueryResult(); @@ -688,9 +693,42 @@ protected QueryResult queryDonatingContacts(String updatedSinceClause) throws Co String contactIds = aggregateResults.stream() .map(sObject -> "'" + sObject.getField("ContactId") + "'") .collect(Collectors.joining(",")); - String query = "select " + getFieldsList(CONTACT_FIELDS, env.getConfig().salesforce.customQueryFields.contact, null) + - " from Contact " + - "where Id in (" + contactIds + ")"; + String query = "SELECT " + getFieldsList(CONTACT_FIELDS, env.getConfig().salesforce.customQueryFields.contact, null) + " " + + "FROM Contact " + + "WHERE Id IN (" + contactIds + ")"; + return query(query); + } + + protected QueryResult queryDonatingAccountsContacts(String updatedSinceClause) throws ConnectionException, InterruptedException { + if (Strings.isNullOrEmpty(updatedSinceClause)) { + env.logJobWarn("no filter provided; out of caution, skipping the query to protect API limits"); + return new QueryResult(); + } + String updatedAccountsQuery = "SELECT Id FROM Account " + + "WHERE " + updatedSinceClause; + List updatedAccounts = queryListAutoPaged(updatedAccountsQuery); + if (CollectionUtils.isEmpty(updatedAccounts)) { + return new QueryResult(); + } + String updatedAccountIds = updatedAccounts.stream() + .map(sObject -> "'" + sObject.getField("Id") + "'") + .collect(Collectors.joining(",")); + + String totalOpportunityAmountQuery = "SELECT AccountId, SUM(Amount) TotalAmount FROM Opportunity " + + "WHERE AccountId IN (" + updatedAccountIds + ")" + + "GROUP BY AccountId " + + "HAVING SUM(Amount) > 0"; + List aggregateResults = queryListAutoPaged(totalOpportunityAmountQuery); + if (aggregateResults.isEmpty()) { + return new QueryResult(); + } + + String accountIds = aggregateResults.stream() + .map(sObject -> "'" + sObject.getField("AccountId") + "'") + .collect(Collectors.joining(",")); + String query = "SELECT " + getFieldsList(CONTACT_FIELDS, env.getConfig().salesforce.customQueryFields.contact, null) + " " + + "FROM Contact " + + "WHERE AccountId IN (" + accountIds + ")"; return query(query); } diff --git a/src/main/java/com/impactupgrade/nucleus/service/segment/CrmService.java b/src/main/java/com/impactupgrade/nucleus/service/segment/CrmService.java index 84b40cd54..a89aa3299 100644 --- a/src/main/java/com/impactupgrade/nucleus/service/segment/CrmService.java +++ b/src/main/java/com/impactupgrade/nucleus/service/segment/CrmService.java @@ -191,7 +191,6 @@ default void batchFlush() throws Exception { PagedResults getEmailAccounts(Calendar updatedSince, EnvironmentConfig.CommunicationList communicationList) throws Exception; PagedResults getSmsContacts(Calendar updatedSince, EnvironmentConfig.CommunicationList communicationList) throws Exception; PagedResults getDonatingContacts(Calendar updatedSince) throws Exception; - //TODO: getDonatingAccounts // Map> // We pass the whole list of contacts that we're about to sync to this all at once, then let the implementations