function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Chris ShadeChris Shade 

APEX & Data.com API Example

I was interested in building an APEX trigger that would allow me to automatically add contacts fromm Data.com.  I couldn't find any examples on this forum so I opened a case and Gage Hudson (Sr. Technical Engineer) was kind enough to give me an example.  Anyways, I wanted to share in case anyone else has a similar interest.



public class SearchController {
    public Boolean isError;
    public Boolean showAccount;

    @TestVisible private String query = 'None';
    @TestVisible private String errorMsg = 'No Error Message';
    @TestVisible private String purchaseFlowOutput = '';
    @TestVisible private Map<String, DCC> currentPage;
    @TestVisible private String newA; // String ID of newly created account for display

    @TestVisible private String currentId;

    @TestVisible private Map<String, String> inputMap = new Map<String, String>();

    public SearchController () {
        Map<String, DCC> currentPage = new Map<String, DCC>();
        isError = false;
        showAccount = false;
    }

    public void searchCompanies() {
        errorMsg = 'No Error Message'; // Reset error message for new search

        query = buildQuery();

        if (query != null) {
            currentPage = execQuery(query);
            checkDupe();
        } else {
            query = 'None'; // Reset Query if not going to run
        }
    }

    @TestVisible private String buildQuery() {
        String s = 'SELECT AnnualRevenue, City, CompanyId, Country, Description, DunsNumber, Fax, Industry, NaicsCode, ' +
            'NaicsDesc, Name, NumberOfEmployees, Ownership, Phone, Sic, SicDesc, Site, State, Street, TickerSymbol, TradeStyle, Website, ' +
            'YearStarted, Zip';
        s = s + ' FROM DatacloudCompany';
        s = s + ' WHERE ';

        boolean firstHit = false; // Change to false on first hit to add AND to rest
        Set<String> regexMatchField = new Set<String>{'Name', 'Website', 'Zip'};

        for (String key : inputMap.keySet()){
            // Make sure that field has a value
            if (inputMap.get(key) != null && !inputMap.get(key).trim().equals('')) {
                if (firstHit)
                    s = s + ' AND ';

                if (regexMatchField.contains(key) )
                    s = s + String.escapeSingleQuotes(key) + ' LIKE \'%' + String.escapeSingleQuotes(inputMap.get(key)) + '%\'';
                else
                    s = s + String.escapeSingleQuotes(key) + ' = \'' + String.escapeSingleQuotes(inputMap.get(key)) + '\'';

                firstHit = true;
            }
        }
        s = s + ' LIMIT 20';
        query = s;
        System.debug('Query string set as : ' + query);

        if (!firstHit) {
            System.debug('No inputs found - firstHit = false');
            return null;
        }

        return s;
    }

    @TestVisible private Map<String, DCC> execQuery(String q) {
        List<DatacloudCompany> results = new List<DatacloudCompany>();
        Map<String, DCC> res = new Map<String, DCC>();
        try {
            results = Database.query(q);

            System.debug('Query successful');

            for (DatacloudCompany c : results) {
                res.put(c.CompanyId, new DCC(c));
            }
        } catch (exception e) {
            isError = true;
            System.debug('Error during execution of query caught');
        }
        return res;
    }

    @TestVisible private void checkDupe() {
        ID userId = UserInfo.getUserId();
        List<Account> accts = [SELECT Jigsaw, ID FROM Account WHERE Jigsaw IN :currentPage.keySet()];
        for(Account a : accts) {
            DCC dc = currentPage.get(a.Jigsaw);
            dc.setRenderBox('false');
            dc.setAccountId(a.ID);
            currentPage.put(dc.getId(), dc);
        }
    }

    @TestVisible private Set<String> getSelectedDDCIds(){
        Set<String> ddcIds = new Set<String>();
        for (DCC c : currentPage.values()) {
            if (c.getSelected().compareTo('true')==0 && c.getHasLink().compareTo('true')!=0)
                ddcIds.add(c.getId());
        }

        return ddcIds;
    }

    public PageReference purchaseAccountDetails() { // Method invoked by VF to purchase details
        if (currentPage == null || currentPage.size() == 0) {
            return null;
        }

        String id;
        DatacloudCompany dcTemp;

        Set<String> ddcIds = getIdsThatRequirePurchase(getSelectedDDCIds());

        if (ddcIds.size() > 0) {
            purchase(ddcIds);
        }

        purchaseFlowOutput = 'Company purchase successful!';
        return null;
    }

    private Set<String> getIdsThatRequirePurchase(Set<String> ddcIds){
        // query the list of owned entity ids, and add them to a set.
        Set<String> ownedEntityIds = new Set<String>();
        for (DatacloudOwnedEntity ownedEntity : [SELECT DataDotComKey from DatacloudOwnedEntity
                                                 WHERE DataDotComKey in :ddcIds]){
            ownedEntityIds.add(ownedEntity.DataDotComKey);
        }

        // iterate over the list of ddc ids and add them a new set if they are not found.
        Set<String> returnSet = new Set<String>();
        for (String ddcId : ddcIds){
            if (!ownedEntityIds.contains(ddcId)){
                returnSet.add(ddcId);
            }
        }
        return returnSet;
    }

    @TestVisible public PageReference createAccount() {
        // Filter ids that already have accounts
        Set<String> ddcIdsForAccounts = getSelectedDDCIds();
        Set<String> ddcIdsThatRequirePurchase = getIdsThatRequirePurchase(ddcIdsForAccounts);

        if (ddcIdsThatRequirePurchase.size() > 0){
            purchaseFlowOutput = 'Account creation failed because some details have not been purchased';
            return null;
        }

        List<DatacloudCompany> dcTemp = searchIds(ddcIdsForAccounts);
        List<Account> accts = new List<Account>();

        if (dcTemp != null)
            createAccounts(dcTemp);

        purchaseFlowOutput = 'Account successfully created!';
        return null;
    }

    @TestVisible private Boolean purchase(Set<String> DDCids) {
        DatacloudPurchaseUsage pu = new DatacloudPurchaseUsage(DatacloudEntityType='1',
                                                               Description='Added via search-before-create Account Tool');

        try {
            insert pu;
        } catch (Exception e) {
            System.debug('Error when inserting purchase usage object');
            return false;
        }

        List<DatacloudOwnedEntity> ownedEntities = new List<DatacloudOwnedEntity>();

        for (String ddcId : ddcIds){
            ownedEntities.add(new DatacloudOwnedEntity(PurchaseUsageId = pu.id,
                                                       DataDotComKey = ddcId,
                                                       DatacloudEntityType = '1'));
        }

        try {
            insert ownedEntities;
        } catch (DMLException e){
            System.debug('Error when inserting owned entities');
            return false;
        }
        return true;
    }

    private List<DatacloudCompany> searchIds(Set<String> ddcIds) {
        List<DatacloudCompany> ddcCompany = new List<DatacloudCompany>();
        Integer size  = ddcIds.size();
        try {
            ddcCompany = [SELECT AnnualRevenue, City, CompanyId, Country, Description, DunsNumber,
                          Fax, Industry, NaicsCode, NaicsDesc, Name, NumberOfEmployees,
                          Ownership, Phone, Sic, SicDesc, Site, State, Street, TickerSymbol,
                          TradeStyle, Website, YearStarted, Zip FROM DatacloudCompany WHERE
                          CompanyId in :ddcIds limit :size];

            return ddcCompany;
        } catch (exception e) {
            isError = true;
            System.debug('Error during execution of query was caught');
        }

        return null; // Clearly an Error Occured
    }


    private String createAccounts(List<DatacloudCompany> ddcCompanies) {
        Map<String, Account> accountMap = new Map<String, Account>();
        for (DatacloudCompany dc : ddcCompanies){
            accountMap.put(dc.CompanyId, new Account(AccountSource='Data.com', AnnualRevenue=dc.AnnualRevenue,
                                                     BillingCity=dc.city, ShippingCity=dc.city, Jigsaw=dc.CompanyId, BillingCountry=dc.Country,
                                                     ShippingCountry=dc.Country, Description=dc.Description, DunsNumber=dc.DunsNumber,
                                                     Fax=dc.Fax, Industry=dc.Industry, NaicsCode=dc.NaicsCode, NaicsDesc=dc.NaicsDesc,
                                                     Name=dc.Name, NumberOfEmployees=dc.NumberOfEmployees, Ownership=dc.Ownership,
                                                     Phone=dc.Phone, Sic=dc.Sic, SicDesc=dc.SicDesc, Site=dc.Site, BillingState=dc.State,
                                                     ShippingState=dc.State, BillingStreet=dc.Street, ShippingStreet=dc.Street,
                                                     TickerSymbol=dc.TickerSymbol, Tradestyle=dc.TradeStyle, Website=dc.Website,
                                                     YearStarted=dc.YearStarted, BillingPostalCode=dc.Zip, ShippingPostalCode=dc.Zip));
        }

        if (accountMap.size() > 0) {
            insert accountMap.values();
        }

        for (String ddcId : accountMap.keySet()) {
            DCC dcc = currentPage.get(ddcId);
            dcc.setAccountId(accountMap.get(ddcId).id);
            dcc.setRenderBox('false');
        }
        return null;
    }

    // Used by the tests to reset the input map
    @TestVisible private void resetInputMap(){
        inputMap = new Map<String, String>();
    }

    @TestVisible public Boolean getHaveResults() {
        return (currentPage != null && currentPage.size() > 0)?  true : false;
    }

    public PageReference returnToPage() {
        return null;
    }

    /* ---------- Getters and Setters ---------- */

    /* --- Below here are getters and setters for the VisualForce Page --- */
    public Map<String, DCC> getCurrentPage() {
        return currentPage;
    }
    public String getInputCompanyName() {
        return inputMap.get('Name');
    }
    public void setInputCompanyName(String value) {
        inputMap.put('Name', value);
    }
    public String getInputCity() {
        return inputMap.get('City');
    }
    public void setInputCity(String value) {
        inputMap.put('City', value);
    }
    public String getInputCountry() {
        return inputMap.get('Country');
    }

    public void setInputCountry(String value) {
        inputMap.put('Country', value);
    }
    public String getInputPostalCode() {
        return inputMap.get('Zip');
    }
    public void setInputPostalCode(String value) {
        inputMap.put('Zip', value);
    }
    public Boolean getShowAccount() {
        return showAccount;
    }
    public Boolean getIsError() {
        return isError;
    }
    public void setIsError(Boolean value) {
        this.isError = value;
    }
    public String getErrorMsg() {
        return errorMsg;
    }
    public String getQuery() {
        return query;
    }
    public String getPurchaseFlowOutput() {
        return purchaseFlowOutput;
    }
    /* ---------- Custom Class ---------- */

    public class DCC {
        private DatacloudCompany comp;
        private String selected;
        private String renderBox;
        private String accountId;
        private String companyId;

        public DCC(DatacloudCompany item) {
            this.comp = item;
            this.selected = 'false';
            this.renderBox = 'true';
            this.accountId = null;
            companyId = item.companyId;
        }

        public String getLink() {
            if (accountId == null){
                return '';
            }
            return '<a href="'+ System.URL.getSalesforceBaseUrl().toExternalForm() + '/' + accountId + '" > Account </a>';
        }

        public String getHasLink() {
            if (accountId != null){
                return 'true';
            }
            return 'false';
        }
        public String getAccountId() {
            return accountId;
        }
        public void setAccountId(String value) {
            this.accountId = value;
        }
        public DatacloudCompany getComp() {
            return comp;
        }
        public String getSelected() {
            if (accountId != null){
                return 'true';
            }
            return selected;
        }
        public void setSelected(String value) {
            this.selected = value;
        }
        public String getRenderBox() {
            return renderBox;
        }
        public void setRenderBox(String value) {
            this.renderBox = value;
        }
       
        @TestVisible private void setId(String companyId){
            this.companyId = companyId;
        }
        public String getId() {
            return companyId;
        }
        public String getTickerSymbol() {
            return comp.TickerSymbol;
        }
        public String getName() {
            return comp.Name;
        }
        public String getCity() {
            return comp.City;
        }
        public String getCountry() {
            return comp.Country;
        }
        public String getPhone() {
            return comp.Phone;
        }
        public String getIndustry() {
            return comp.Industry;
        }
        public String getSite() {
            return comp.Site;
        }
    }
}