#logos

# Quotes code refactoring in CRM API 
#quotes #crmapi
Refactored the AdminQuotesController in CrmApi today. It queries quotes from Logos (OrdersApi) and from Salesforce.  I like the pattern of having two interfaces: ILogosQuotesService and ICrmQuotesService to abstract both sources but admit that most of our code is aware that we're getting quotes from two places and so it makes sense for it to reference interfaces tied to one side and the other instead of a single interface the somehow abstracts both sides of the fence.

After refactoring, the orders API client in my implementation of ILogosQuoteService is returning unauthorized. The problem was that I set it up in the CrmApi.v1 TypeRegistry as a Singleton instead of HybridHttpOrThreadLocalScoped.  That won't work because it has to pass credentials per request.

# Deleted Opportunity problems in CRM API
#quote #crmapi #salesforce #apex
The CRM API integration tests were failing because the test quote couldn't be integrated to Salesforce UAT sandbox because a record with the same external id (our Logos quote ID) already existed, but was soft-deleted.

I was having trouble finding the soft-deleted record.  [This article]([How to find deleted records in Salesforce using SOQL | Wipfli](https://www.wipfli.com/insights/articles/tc-how-to-find-deleted-records-in-salesforce-using-soql)) helped.  The answer is to execute developer console Apex code:
```apex
List<opportunity> deletedOpps = [SELECT Id
FROM Opportunity
WHERE LogosQuoteId__c = '6667952' and IsDeleted = TRUE
ALL ROWS];

system.debug(deletedOpps);
```

The `ALL ROWS` part is the key.  But, it doesn't work with a regular SOQL query, just from Apex code like this.

I had to insert a new record manually because the upsert we were doing in the quote loader was always failing with an `ENTITY_DELETED` error.  I used Apex (the developer console in Salesforce) to 
execute this:
```apex
Opportunity opp = new Opportunity(Amount = 10, Name='bens test', CloseDate = Date.newInstance(1960, 2, 17), StageName='Negotiating', LogosQuoteId__c = '6667952');
insert opp;
```

Now the integration test passes.

The key findings I had to research to get right:
1. The list of parameters to the sobject (`Opportunity`) are comma-separated and formatted as `key = value`
2. Create a new Date with `Date.newInstance(year, month, date)`
3. Use `insert nn` to insert the object

# Segment/Cohort Count Scheduled Check
I implemented a scheduled check in CRM API to compare segment population counts from our DB to the user counts in Amplitude cohorts.  The idea was to highlight cohorts where the population difference was difference enough to indicate sync was failing somehow.

Unfortunately, this approach didn't work.  Some cohorts were even over 50% off from the segment population count. I'm assuming this is because the users are just not present in Amplitude, which is very possible.  I removed the scheduled check for now until (if) we can find a better solution to check on these syncs.