• Yogesh Biyani
  • NEWBIE
  • 75 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 59
    Questions
  • 52
    Replies
What is the SOQL to find all the subscribed/scheduled dashboards? 
I am a bit confused about the relationship between Task and EmailMessage objects.

One can find the Task from EmailMessage using ActivityId but not sure how to get the EmailMessage from Task. Can someone show how to get the EmailMessage from the Task object? 
A custom object is associated with account and contact via a lookup field.  Is it possible to find all accounts and contacts of all the custom object records which are updated using a SOQL query? 
Here is the Apex Class
public class AssignLeadsUsingAssignmentRules
{
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
            Database.DMLOptions dmo = new Database.DMLOptions();
            dmo.assignmentRuleHeader.useDefaultRule= true;          
            Lead Leads=[select id,OwnerId from lead where lead.id in :LeadIds];
            Leads.setOptions(dmo);
        	system.debug('Before Update Lead Details' + Leads);
         	Database.update(Leads,dmo);
        	Lead Leads2=[select id,OwnerId from lead where lead.id in :LeadIds];
        	system.debug('After Update Lead Details' + Leads2);
   }
}

Here is the test class 
@isTest 
      public class TestAssignLeadsUsingAssignmentRules{
      static testMethod void createnewlead() {
     
   //   Test.startTest();    
      Lead leadToCreate =new Lead();
      List<id> Ids= New List<Id>();
    //  leadToCreate.ownerid= userToCreate.id;
      leadToCreate.ownerid= UserInfo.getUserId();  
      leadToCreate.LastName ='Sample1';
      leadToCreate.Email='Someone@somewhere.com';
      leadToCreate.Company='OneTwo34';
      leadToCreate.LeadSource='Partner Referral';
      leadToCreate.Country='IN';
      leadToCreate.Source_Last_Lead_Source_Detail__c='Form - Contact Form';
          
      insert leadToCreate; 
      
      Ids.add(leadToCreate.id);
      AssignLeadsUsingAssignmentRules.leadAssign(Ids);
      System.assertEquals('00G1W000002RyhMUAS', leadToCreate.OwnerId, 'Something is wrong');

 	//  Test.stopTest();
      
   }
}

The test class fails as shown below User-added imageAs you can see the debug log shows the lead OwnerId has changed but the change does not persist outside the class in the test. What am I missing? 
We have some accounts with incorrect account team and the following query identifies all such accounts. Basically, accounts with two or more account team members with the Distributor role has incorrect teams.
Select AccountId, Account.Name, count(id) from AccountTeamMember WHERE TeamMemberRole ='Distributor License Share' AND UserId!='0051W000004SVNhQAO' Group BY AccountId, Account.Name HAVING count(id) >=2 LIMIT 2000
What is the easiest way to delete all such account teams? 

I am still learning Apex/SOQL; how do I collect the AccountIds from the above aggregate result and pass it to get all the AccountTeamMember IDs to delete? The following code in developer console fails with the following error

Invalid identifier ' '. Apex identifiers must start with an ASCII letter (a-z or A-Z) followed by any number of ASCII letters (a-z or A-Z), digits (0 - 9), '$', '_'.​​​​​​​
List<AggregateResult> results =  [Select  AccountId, Account.Name, count(id) from AccountTeamMember 
                      WHERE TeamMemberRole ='Distributor License Share' AND UserId!='0051W000004SVNhQAO' 
                      Group BY AccountId, Account.Name HAVING count(id) >=2 LIMIT 2000 ];

System.debug(results.size());

System.debug(results[0]);

Set<id > AccountIds = new Set<id>();
      
for(AggregateResult exp: results){
    AccountIds.add((Id)exp.get('AccountId'));
}



 
Currently, we have 8 different triggers on the opportunity class and I am refactoring the code and moving it to a helper class. I am thinking of using the switch statement as shown in this article (https://developer.salesforce.com/blogs/2018/05/summer18-rethink-trigger-logic-with-apex-switch.html). 

Here is the original trigger
 trigger OppPusher on Opportunity (before update) {
Date dNewCloseDate;
Date dOldCloseDate;
Boolean bPushed=false;
for (Opportunity oIterator : Trigger.new) { //Bulk trigger handler so that you can mass update opportunities and this fires for all'
// gets new values for updated rows
dNewCloseDate = oIterator.CloseDate; // get the new closedate
dOldCloseDate = System.Trigger.oldMap.get(oIterator.Id).CloseDate; //get the old closedate for this opportunity
//if different do something.
}
}

Here is the new trigger and class 
trigger OppTriggers  on  Opportunity (    before insert, 
                                           after insert, 
                                           before update, 
                                           after update) {

	OppTriggerHandler.handleTrigger(Trigger.new, Trigger.old, Trigger.operationType);

}

public with sharing class OppTriggerHandler { 
    
    public static void handleTrigger(List<Opportunity> workingRecords, 
                                     List<Opportunity> oldRecords, 
                                     System.TriggerOperation triggerEvent ) {
                                         
                                         
                                         switch on triggerEvent {
                                             
                                             when BEFORE_UPDATE{
                                                 Date dNewCloseDate;
                                                 Date dOldCloseDate;
                                                 Boolean bPushed=false;
                                                 
                                                 for (Opportunity oIterator : workingRecords) { //Bulk trigger handler so that you can mass update opportunities and this fires for all'
                                                     // gets new values for updated rows
                                                     dNewCloseDate = oIterator.CloseDate; // get the new closedate 
                                              	     dOldCloseDate = System.Trigger.oldMap.get(oIterator.Id).CloseDate; //get the old closedate for this opportunity
                                                    //if different do something.
                                                   
                                                 }
                                             }
                                             when AFTER_INSERT, AFTER_UPDATE {
                                                 //create related records
                                             }
                                             when BEFORE_INSERT {
                                                 //set value on record create
                                             }
                                             when AFTER_DELETE {
                                                 //prevent deletion of sensitive data
                                             }
                                             when else {
                                                 //do nothing for AFTER_UNDELETE, BEFORE_DELETE, or BEFORE_UPDATE
                                             }
                                         }
                                     }
}

And the compiler fails with 
Variable does not exist: CloseDate message.

How do I about this error message? 


 
I am trying to mass delete listviews from a test site using the workbench. Here is the destructivechanges.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <name>ListView</name>
        <members>Case.All_Open_Requests</members>
        <members>Case.All_Open_Requests_Since_2016</members>
        <members>Case.All_Request_Created_Today</members>
    </types>
    <version>44.0</version>
</Package>

Here is the package.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>44.0</version>
</Package>

Both of these are in a zip file changes.zip, and the workbench shows success but it is not deleted for the interface. What am I missing?
 
Here are some examples of fake contacts in our database which we would like to clean. 
User-added image
Here is the current code and as you can tell the credentials are visible to anyone accessing the code. How can we remove it from the code? 
String myString = 'somekey:somepassword';
        
        Blob myBlob = Blob.valueof(myString);
        
        String authorization1 = 'basic ' + EncodingUtil.base64Encode(myBlob);
        HttpRequest req = new HttpRequest();
        
        req.setEndpoint('https://api.somesite.com/token');
        req.setMethod('POST');
        
        req.setBody('grant_type=client_credentials');
        
        req.setHeader('Authorization', authorization1);
        
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        
        Http http = new Http();
        
        HTTPResponse res = http.send(req);

I reviewed Named Credentials but am thrown off with the 64 bit encoding requirement. Thanks in advance for your help.

Yogesh
SOQL statements cannot query more than 20 different child types.

So how do I merge the Contacts from two different queries? 

For eg. 
List<Contact> querychilds1 = [select id,Orphan__c ,
                                     (Select id from PrimaryContact__r ),
                                      (Select id from Attachments ),
                                      (Select id from CampaignMembers ),
                                      (Select id from Cases ),
                                      (Select id from CaseContactRoles ) 
                                         and few more totaling to twenty....
                                      from contact 
                                      WHERE id IN :listofcontacts]; 

          List<Contact> querychilds2 = [select id,Orphan__c ,
                                      (Select id from Feeds ),
                                      (Select id from Histories ),
                                      (Select id from DeclinedEventRelations ),
                                      (Select id from DuplicateRecordItems ),
                                      (Select id from EmailMessageRelations ),
                                      (Select id from FeedSubscriptionsForEntity ) 
                                      from contact 
                                      WHERE id IN :listofcontacts];


       
We would like to find all contacts without any relationships in the database and mark them for deletion.  Listing my approach below and am wondering if anyone can comment on the same.  Thank you all in advance. 

Yogesh​

Step 1 - Using the following code to identify all the relationships and the number of each
Schema.SObjectType contactSType = Contact.sObjectType;
Schema.DescribeSObjectResult dsr = contactSType.getDescribe();
string s='';
integer i=0;
for(Schema.ChildRelationship child : dsr.getChildRelationships()) {
    System.debug(i+' '+child.getChildSObject()+'--'+child.getRelationshipName()+'--'+child.getField());

        String query1='select Count_distinct('+child.getField()+ ') from '+child.getChildSObject()
 
        try 
        {   
      
            List<SObject> l=Database.Query(query1);
            integer t=(integer)l[0].get('expr0');
   
		   system.debug('r'+i+'='+ t);
 		   if(t>0)
				s+='r'+i+'='+ t+' '+child.getChildSObject()+'--'+child.getRelationshipName()+'--'+child.getField()+'; ';
       }
        
        catch(Exception e){
            
            System.debug(e.getMessage());
        }

    i++;
}

system.debug(s);

Here are the results
r0=295 AcceptedEventRelation--AcceptedEventRelations--RelationId
r1=424054 Account--Accounts_Contacts__r--Contactconnect__c
r7=112769 Attachment--Attachments--ParentId
r8=4863 CampaignMember--CampaignMembers--ContactId
r10=122885 Case--Cases--ContactId
r17=334394 ContactFeed--Feeds--ParentId
r25=107 DeclinedEventRelation--DeclinedEventRelations--RelationId
r26=1660 DuplicateRecordItem--DuplicateRecordItems--RecordId
r27=31130 EmailMessageRelation--EmailMessageRelations--RelationId
r31=2139 EntitySubscription--FeedSubscriptionsForEntity--ParentId
r32=4142 Event--Events--WhoId
r33=409 EventRelation--EventRelations--RelationId
r37=57 GoogleDoc--GoogleDocs--ParentId
r40=248704 License_With_Order__c--License_Contact__r--l_contact__c
r41=136238 License_With_Order__c--Order_B_Contact__r--o_b_contact__c
r42=245711 License_With_Order__c--Order_C_Contact__r--o_c_contact__c
r43=637 Note--Notes--ParentId
r46=13765 OpportunityContactRole--OpportunityContactRoles--ContactId
r51=8820 Quote--Quotes--ContactId
r54=892 Sertifi2_0__ContractContactJunction__c--Sertifi2_0__Signers__r--Sertifi2_0__Contact__c
r60=27768 Task--Tasks--WhoId
r61=912 TopicAssignment--TopicAssignments--EntityId
r62=239 UndecidedEventRelation--UndecidedEventRelations--RelationId
r65=740 Zendesk__Zendesk_Ticket__c--Zendesk__Zendesk_Tickets__r--Zendesk__Requester__c
r67=3828 simplesurvey__Survey__c--simplesurvey__Surveys__r--simplesurvey__Contact__c

r9=33202 CampaignMember--null--LeadOrContactId
r16=22 Contact--null--ReportsToId
r22=29 ContentVersion--null--FirstPublishLocationId
r34=6542 FeedComment--null--ParentId
r38=160901 Lead--null--ConvertedContactId
Step 2.  Create a batch process to find each record without such relationships and mark them for deletion Here is the sample code demonstrating this step using some of the relationships identified above.
List<Contact> queryResults = [select id ,(select id from AcceptedEventRelations) ,
							    (select id from PrimaryContact__r) ,
                                (select id from AccountContactRoles) ,
                                (select id from ActivityHistories),
                                (select id from Cases) from contact ORDER BY id LIMIT 10000]; 

Set<Id> resultIds = (new Map<Id,Contact>(queryResults)).keySet();
System.debug(resultIds.size());
for (Contact c : queryResults) {
 //   System.debug(c);
    if(c.Cases.size()>0||
       c.AcceptedEventRelations.size()>0||
       c.PrimaryContact__r.size()>0||
      c.AccountContactRoles.size()>0||
      c.ActivityHistories.size()>0)
    {
  /*      for (Case c1 : c.Cases) {
            System.debug(c1);
        }*/
       // System.debug('Keep');
        resultIds.remove(c.id);
    }
    else 
    {
        //System.debug('Delete1');
     
    }
        
        for (ActivityHistory c1 : c.ActivityHistories) {
         //   System.debug(c1);
        }
    
    for (Account c1 : c.PrimaryContact__r) {
       // System.debug(c1);
    }
}

System.debug(resultIds.size());

List<Lead> ls =[Select Id,ConvertedContactId from Lead where ConvertedContactId IN :resultIds];

if(ls.size()>0)
{
    for(Lead l : ls)
    {
        resultIds.remove(l.ConvertedContactId);
        system.debug('removed id '+l.ConvertedContactId);
    }
}

System.debug(resultIds.size()); // these the contacts to mark for deletion
I am trying to the queries from this link into a visualforce page. Here is the controller class 
// https://salesforce.stackexchange.com/questions/118109/how-to-use-custom-date-fields-in-visualforce-page
// 
public with sharing class DisplayDriftInfluncedOpportunity{
    public static Date startDate{get;set;}
    public static Date endDate{get;set;}
    //public static List<Account> accList{get;set;}
    public boolean showResult{get;set;}
    public boolean blnNoResultFound{get;set;}
    public List<SObject> Records {get; set;}
    
    public DisplayDriftInfluncedOpportunity(){
        showResult = false;
        blnNoResultFound = false;
        Records = new List<SObject>();
        endDate=date.today();
        startDate=endDate-90;
    }
    
    
    public void searchResults(){
        List<Task> accs= [select Id, AccountId
                          from Task
                          where
                          Subject = 'Conversation in Drift' and
                          AccountId != null and
                          AccountId in (
                              Select AccountId
                              from Opportunity
                              WHERE 
                              //Calendar_Year(CreatedDate)=2018
                              DAY_ONLY(CreatedDate) >= :startDate and
                              DAY_ONLY(CreatedDate) <= :endDate
                          )]
            ;
        
        Set<Id> acca1 = new Set<Id>();
        for(Task t :accs)
            acca1.add(t.AccountId);
        
        List<SObject> r=[select AccountId accId, COUNT(Name) oCount , SUM(Amount) Total , DAY_ONLY(CreatedDate) CreatedDate  , CloseDate 
                         from Opportunity
                         where
                        // Calendar_Year(CreatedDate)=2018 and
                         DAY_ONLY(CreatedDate) >= :startDate and
                         DAY_ONLY(CreatedDate) <= :endDate and
                         AccountId in :acca1
                         group by DAY_ONLY(CreatedDate), AccountId, CloseDate];
        
        Records =r;
        
    }
}

And the corresponding visualforce page .
 
<apex:page controller="DisplayDriftInfluncedOpportunity" docType="html-5.0">
    
<center><h1>Opportunity Search Page</h1></center>
<apex:form >
   Start Date: <apex:input type="date" value="{!startDate}" required="true" />
   End Date: <apex:input type="date" value="{!endDate}" required="true" /> 
    <apex:commandButton action="{!searchResults}" value="Search" />
</apex:form> 
<apex:pageBlock title="Opportunities Influenced by Drift">
  <apex:pageBlockTable value="{!Records}" var="Record">
   <apex:column >
    <apex:facet name="header">Account id</apex:facet>
    <apex:outputlink value="/{!Record['accId']}">{!Record['accId']}</apex:outputlink>
   </apex:column>
   <apex:column >
    <apex:facet name="header">Count</apex:facet>
       <apex:outputText value="{!Record['oCount']}"/>
   </apex:column>
   <apex:column >
    <apex:facet name="header">Total</apex:facet>
       <apex:outputText value="{!Record['Total']}"/>
   </apex:column>
      
   <apex:column >
    <apex:facet name="header">CreatedDate</apex:facet>
       <apex:outputText value="{!Record['CreatedDate']}"/>
   </apex:column>
   <apex:column >
    <apex:facet name="header">CloseDate</apex:facet>
       <apex:outputText value="{!Record['CloseDate']}"/>
   </apex:column>
  </apex:pageBlockTable>
</apex:pageBlock>
    
</apex:page>
 Instead of Account Id associated with the Opportunity, I would like to show the Account Name. What do I need to change?

Yogesh
Following query results in 17000+ records. How do I save this result to csv/excel file? I tried SDFC Dev Console Data Exporter  but is saves only about 1000 rows. 
SELECT 
    CreatedDate,Id, Owner.Name,Inquiry_Type__c,
(SELECT id FROM EmailMessages 
WHERE Incoming = true)
FROM Case WHERE Sales_Department__c='Sales' AND Response_Indicator__c=TRUE
Hello All, I have hacked up a VF page to display the 3 contacts associated with a custom object. Here is the VF code 
<apex:page standardController="License_With_Order__c" >
<apex:pageBlock  >
<apex:pageBlockSection columns="3"  >
<apex:repeat value="{!$ObjectType.License_With_Order__c.FieldSets.Contacts}" var="field">
<apex:outputField style="width:350px;float:left" value="{!License_With_Order__c[field]}"/>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>

And here is the preview


 User-added image 

As you can see the labels of the third column are in multiple rows.
  1. How do I make them show up in the same row?
  2. Secondly, How do I make the Order C Country and Order B Country under appropriate contacts? 
Thanks in advance for your help. 

Regards,
Yogesh
I am using a dynamic query but it fails with Use query() for non-count queries . What am I missing? 
 
for(Schema.ChildRelationship child : dsr.getChildRelationships()) {
String query=  'select count(id) FROM CONTACT WHERE ID NOT IN (SELECT '+
            	child.getField()+' FROM '+child.getChildSObject()+ ')'; 

        integer  t=Database.countquery(query);
system.debug(t);
}

 
The following queries list the IDs of such accounts (400k+) and contacts(800k+). Workbench will display the result in a table however only a few (e.g. 50) are displayed in the table and then I have select "more" to see the next set. What is the best tool to export this large dataset?
 
1) select id ,(select id from AcceptedEventRelations) ,(select id from Accounts_Contacts__r) ,(select id from Attachments) ,(select id from CampaignMembers) ,(select id from Cases) ,(select id from Feeds) ,(select id from Histories) ,(select id from DeclinedEventRelations) ,(select id from EmailMessageRelations) ,(select id from FeedSubscriptionsForEntity) ,(select id from Events) ,(select id from EventRelations) ,(select id from Notes) ,(select id from OpportunityContactRoles) ,(select id from Quotes) ,(select id from Tasks) ,(select id from UndecidedEventRelations) ,(select id from simplesurvey__Surveys__r) from contact

2) select id ,(select id from CaseContactRoles) ,(select id from Tags) ,(select id from DuplicateRecordItems) ,(select id from GoogleDocs) ,(select id from Sertifi2_0__Signers__r) ,(select id from Personas) ,(select id from TopicAssignments) ,(select id from Zendesk__Zendesk_Tickets__r) from contact

3) select id ,(select id from Feeds) ,(select id from Histories) ,(select id from Attachments) ,(select id from Cases) ,(select id from Contacts) ,(select id from Emails) ,(select id from FeedSubscriptionsForEntity) ,(select id from Notes) ,(select id from Opportunities) ,(select id from Tasks) ,(select id from simplesurvey__Surveys__r) from Account

4) select id ,(select id from ChildAccounts) ,(select id from AccountPartnersFrom) ,(select id from AccountPartnersTo) ,(select id from Tags) ,(select id from AccountTeamMembers) ,(select id from Contracts) ,(select id from DuplicateRecordItems) ,(select id from Events) ,(select id from GoogleDocs) ,(select id from OpportunityPartnersTo) ,(select id from PartnersFrom) ,(select id from PartnersTo) ,(select id from Sertifi2_0__Sertifi_EContracts__r) ,(select id from Personas) ,(select id from TopicAssignments) ,(select id from Zendesk__Zendesk_Tickets__r) from Account


 
Hello All,

Is there a way to know which objects have the lookups to contact? So far, I have found following objects in our instance

Events
Quotes
Lead 
CampaignMember
Case
ZendeskSupportTicket

Yogesh
How to find contacts which do not have cases, opportunities, activities, etc so that we can delete such contacts from the database? 
Thanks in advance.

Yogesh

 
In compliance with GDPR, we have implemented a process to delete all the user information from the database. After deleting the data we send a final email to the requester informing the actions taken. However, the final email message stays in the database and has the email address of the recipient. How can we delete the email after it is sent? 

Here is the code which sends the confirmation email. 
 
public void SendConfirmationEmailMessage(Contact_Preference__c cp){
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
 
        message.toAddresses = new String[] { cp.Email__c };
        message.setSubject('Data Deletion Confirmation Email');
        message.setHtmlBody(Messaging.renderStoredEmailTemplate('00X1W000001USk9', null, cp.id).getHTMLBody());
     Messaging.SingleEmailMessage[] messages =  
            new List<Messaging.SingleEmailMessage> {message};

     Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
        if (results[0].success) {
            System.debug('The email was sent successfully.');
        } else {
            System.debug('The email failed to send: '
                  + results[0].errors[0].message);
        }

    }

 
Here is the Apex Class
public class AssignLeadsUsingAssignmentRules
{
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
            Database.DMLOptions dmo = new Database.DMLOptions();
            dmo.assignmentRuleHeader.useDefaultRule= true;          
            Lead Leads=[select id,OwnerId from lead where lead.id in :LeadIds];
            Leads.setOptions(dmo);
        	system.debug('Before Update Lead Details' + Leads);
         	Database.update(Leads,dmo);
        	Lead Leads2=[select id,OwnerId from lead where lead.id in :LeadIds];
        	system.debug('After Update Lead Details' + Leads2);
   }
}

Here is the test class 
@isTest 
      public class TestAssignLeadsUsingAssignmentRules{
      static testMethod void createnewlead() {
     
   //   Test.startTest();    
      Lead leadToCreate =new Lead();
      List<id> Ids= New List<Id>();
    //  leadToCreate.ownerid= userToCreate.id;
      leadToCreate.ownerid= UserInfo.getUserId();  
      leadToCreate.LastName ='Sample1';
      leadToCreate.Email='Someone@somewhere.com';
      leadToCreate.Company='OneTwo34';
      leadToCreate.LeadSource='Partner Referral';
      leadToCreate.Country='IN';
      leadToCreate.Source_Last_Lead_Source_Detail__c='Form - Contact Form';
          
      insert leadToCreate; 
      
      Ids.add(leadToCreate.id);
      AssignLeadsUsingAssignmentRules.leadAssign(Ids);
      System.assertEquals('00G1W000002RyhMUAS', leadToCreate.OwnerId, 'Something is wrong');

 	//  Test.stopTest();
      
   }
}

The test class fails as shown below User-added imageAs you can see the debug log shows the lead OwnerId has changed but the change does not persist outside the class in the test. What am I missing? 
I was planning to bring in data from an external database and found that it will cost us 13+GB of storage. The data has more than 7 million records across 4 tables, so at 2kb per record, the total cost would be 7000000*2/(1024*1024) = 13.4 GB. We would like to search and report on the data and add associated contacts and accounts to campaigns. What are our options?  
Here is the Apex Class
public class AssignLeadsUsingAssignmentRules
{
    @InvocableMethod
    public static void LeadAssign(List<Id> LeadIds)
    {
            Database.DMLOptions dmo = new Database.DMLOptions();
            dmo.assignmentRuleHeader.useDefaultRule= true;          
            Lead Leads=[select id,OwnerId from lead where lead.id in :LeadIds];
            Leads.setOptions(dmo);
        	system.debug('Before Update Lead Details' + Leads);
         	Database.update(Leads,dmo);
        	Lead Leads2=[select id,OwnerId from lead where lead.id in :LeadIds];
        	system.debug('After Update Lead Details' + Leads2);
   }
}

Here is the test class 
@isTest 
      public class TestAssignLeadsUsingAssignmentRules{
      static testMethod void createnewlead() {
     
   //   Test.startTest();    
      Lead leadToCreate =new Lead();
      List<id> Ids= New List<Id>();
    //  leadToCreate.ownerid= userToCreate.id;
      leadToCreate.ownerid= UserInfo.getUserId();  
      leadToCreate.LastName ='Sample1';
      leadToCreate.Email='Someone@somewhere.com';
      leadToCreate.Company='OneTwo34';
      leadToCreate.LeadSource='Partner Referral';
      leadToCreate.Country='IN';
      leadToCreate.Source_Last_Lead_Source_Detail__c='Form - Contact Form';
          
      insert leadToCreate; 
      
      Ids.add(leadToCreate.id);
      AssignLeadsUsingAssignmentRules.leadAssign(Ids);
      System.assertEquals('00G1W000002RyhMUAS', leadToCreate.OwnerId, 'Something is wrong');

 	//  Test.stopTest();
      
   }
}

The test class fails as shown below User-added imageAs you can see the debug log shows the lead OwnerId has changed but the change does not persist outside the class in the test. What am I missing? 
We have some accounts with incorrect account team and the following query identifies all such accounts. Basically, accounts with two or more account team members with the Distributor role has incorrect teams.
Select AccountId, Account.Name, count(id) from AccountTeamMember WHERE TeamMemberRole ='Distributor License Share' AND UserId!='0051W000004SVNhQAO' Group BY AccountId, Account.Name HAVING count(id) >=2 LIMIT 2000
What is the easiest way to delete all such account teams? 

I am still learning Apex/SOQL; how do I collect the AccountIds from the above aggregate result and pass it to get all the AccountTeamMember IDs to delete? The following code in developer console fails with the following error

Invalid identifier ' '. Apex identifiers must start with an ASCII letter (a-z or A-Z) followed by any number of ASCII letters (a-z or A-Z), digits (0 - 9), '$', '_'.​​​​​​​
List<AggregateResult> results =  [Select  AccountId, Account.Name, count(id) from AccountTeamMember 
                      WHERE TeamMemberRole ='Distributor License Share' AND UserId!='0051W000004SVNhQAO' 
                      Group BY AccountId, Account.Name HAVING count(id) >=2 LIMIT 2000 ];

System.debug(results.size());

System.debug(results[0]);

Set<id > AccountIds = new Set<id>();
      
for(AggregateResult exp: results){
    AccountIds.add((Id)exp.get('AccountId'));
}



 
Currently, we have 8 different triggers on the opportunity class and I am refactoring the code and moving it to a helper class. I am thinking of using the switch statement as shown in this article (https://developer.salesforce.com/blogs/2018/05/summer18-rethink-trigger-logic-with-apex-switch.html). 

Here is the original trigger
 trigger OppPusher on Opportunity (before update) {
Date dNewCloseDate;
Date dOldCloseDate;
Boolean bPushed=false;
for (Opportunity oIterator : Trigger.new) { //Bulk trigger handler so that you can mass update opportunities and this fires for all'
// gets new values for updated rows
dNewCloseDate = oIterator.CloseDate; // get the new closedate
dOldCloseDate = System.Trigger.oldMap.get(oIterator.Id).CloseDate; //get the old closedate for this opportunity
//if different do something.
}
}

Here is the new trigger and class 
trigger OppTriggers  on  Opportunity (    before insert, 
                                           after insert, 
                                           before update, 
                                           after update) {

	OppTriggerHandler.handleTrigger(Trigger.new, Trigger.old, Trigger.operationType);

}

public with sharing class OppTriggerHandler { 
    
    public static void handleTrigger(List<Opportunity> workingRecords, 
                                     List<Opportunity> oldRecords, 
                                     System.TriggerOperation triggerEvent ) {
                                         
                                         
                                         switch on triggerEvent {
                                             
                                             when BEFORE_UPDATE{
                                                 Date dNewCloseDate;
                                                 Date dOldCloseDate;
                                                 Boolean bPushed=false;
                                                 
                                                 for (Opportunity oIterator : workingRecords) { //Bulk trigger handler so that you can mass update opportunities and this fires for all'
                                                     // gets new values for updated rows
                                                     dNewCloseDate = oIterator.CloseDate; // get the new closedate 
                                              	     dOldCloseDate = System.Trigger.oldMap.get(oIterator.Id).CloseDate; //get the old closedate for this opportunity
                                                    //if different do something.
                                                   
                                                 }
                                             }
                                             when AFTER_INSERT, AFTER_UPDATE {
                                                 //create related records
                                             }
                                             when BEFORE_INSERT {
                                                 //set value on record create
                                             }
                                             when AFTER_DELETE {
                                                 //prevent deletion of sensitive data
                                             }
                                             when else {
                                                 //do nothing for AFTER_UNDELETE, BEFORE_DELETE, or BEFORE_UPDATE
                                             }
                                         }
                                     }
}

And the compiler fails with 
Variable does not exist: CloseDate message.

How do I about this error message? 


 
I am trying to mass delete listviews from a test site using the workbench. Here is the destructivechanges.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <name>ListView</name>
        <members>Case.All_Open_Requests</members>
        <members>Case.All_Open_Requests_Since_2016</members>
        <members>Case.All_Request_Created_Today</members>
    </types>
    <version>44.0</version>
</Package>

Here is the package.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>44.0</version>
</Package>

Both of these are in a zip file changes.zip, and the workbench shows success but it is not deleted for the interface. What am I missing?
 
Here are some examples of fake contacts in our database which we would like to clean. 
User-added image
Here is the current code and as you can tell the credentials are visible to anyone accessing the code. How can we remove it from the code? 
String myString = 'somekey:somepassword';
        
        Blob myBlob = Blob.valueof(myString);
        
        String authorization1 = 'basic ' + EncodingUtil.base64Encode(myBlob);
        HttpRequest req = new HttpRequest();
        
        req.setEndpoint('https://api.somesite.com/token');
        req.setMethod('POST');
        
        req.setBody('grant_type=client_credentials');
        
        req.setHeader('Authorization', authorization1);
        
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        
        Http http = new Http();
        
        HTTPResponse res = http.send(req);

I reviewed Named Credentials but am thrown off with the 64 bit encoding requirement. Thanks in advance for your help.

Yogesh
I am trying to the queries from this link into a visualforce page. Here is the controller class 
// https://salesforce.stackexchange.com/questions/118109/how-to-use-custom-date-fields-in-visualforce-page
// 
public with sharing class DisplayDriftInfluncedOpportunity{
    public static Date startDate{get;set;}
    public static Date endDate{get;set;}
    //public static List<Account> accList{get;set;}
    public boolean showResult{get;set;}
    public boolean blnNoResultFound{get;set;}
    public List<SObject> Records {get; set;}
    
    public DisplayDriftInfluncedOpportunity(){
        showResult = false;
        blnNoResultFound = false;
        Records = new List<SObject>();
        endDate=date.today();
        startDate=endDate-90;
    }
    
    
    public void searchResults(){
        List<Task> accs= [select Id, AccountId
                          from Task
                          where
                          Subject = 'Conversation in Drift' and
                          AccountId != null and
                          AccountId in (
                              Select AccountId
                              from Opportunity
                              WHERE 
                              //Calendar_Year(CreatedDate)=2018
                              DAY_ONLY(CreatedDate) >= :startDate and
                              DAY_ONLY(CreatedDate) <= :endDate
                          )]
            ;
        
        Set<Id> acca1 = new Set<Id>();
        for(Task t :accs)
            acca1.add(t.AccountId);
        
        List<SObject> r=[select AccountId accId, COUNT(Name) oCount , SUM(Amount) Total , DAY_ONLY(CreatedDate) CreatedDate  , CloseDate 
                         from Opportunity
                         where
                        // Calendar_Year(CreatedDate)=2018 and
                         DAY_ONLY(CreatedDate) >= :startDate and
                         DAY_ONLY(CreatedDate) <= :endDate and
                         AccountId in :acca1
                         group by DAY_ONLY(CreatedDate), AccountId, CloseDate];
        
        Records =r;
        
    }
}

And the corresponding visualforce page .
 
<apex:page controller="DisplayDriftInfluncedOpportunity" docType="html-5.0">
    
<center><h1>Opportunity Search Page</h1></center>
<apex:form >
   Start Date: <apex:input type="date" value="{!startDate}" required="true" />
   End Date: <apex:input type="date" value="{!endDate}" required="true" /> 
    <apex:commandButton action="{!searchResults}" value="Search" />
</apex:form> 
<apex:pageBlock title="Opportunities Influenced by Drift">
  <apex:pageBlockTable value="{!Records}" var="Record">
   <apex:column >
    <apex:facet name="header">Account id</apex:facet>
    <apex:outputlink value="/{!Record['accId']}">{!Record['accId']}</apex:outputlink>
   </apex:column>
   <apex:column >
    <apex:facet name="header">Count</apex:facet>
       <apex:outputText value="{!Record['oCount']}"/>
   </apex:column>
   <apex:column >
    <apex:facet name="header">Total</apex:facet>
       <apex:outputText value="{!Record['Total']}"/>
   </apex:column>
      
   <apex:column >
    <apex:facet name="header">CreatedDate</apex:facet>
       <apex:outputText value="{!Record['CreatedDate']}"/>
   </apex:column>
   <apex:column >
    <apex:facet name="header">CloseDate</apex:facet>
       <apex:outputText value="{!Record['CloseDate']}"/>
   </apex:column>
  </apex:pageBlockTable>
</apex:pageBlock>
    
</apex:page>
 Instead of Account Id associated with the Opportunity, I would like to show the Account Name. What do I need to change?

Yogesh
Following query results in 17000+ records. How do I save this result to csv/excel file? I tried SDFC Dev Console Data Exporter  but is saves only about 1000 rows. 
SELECT 
    CreatedDate,Id, Owner.Name,Inquiry_Type__c,
(SELECT id FROM EmailMessages 
WHERE Incoming = true)
FROM Case WHERE Sales_Department__c='Sales' AND Response_Indicator__c=TRUE
Hello All, I have hacked up a VF page to display the 3 contacts associated with a custom object. Here is the VF code 
<apex:page standardController="License_With_Order__c" >
<apex:pageBlock  >
<apex:pageBlockSection columns="3"  >
<apex:repeat value="{!$ObjectType.License_With_Order__c.FieldSets.Contacts}" var="field">
<apex:outputField style="width:350px;float:left" value="{!License_With_Order__c[field]}"/>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>

And here is the preview


 User-added image 

As you can see the labels of the third column are in multiple rows.
  1. How do I make them show up in the same row?
  2. Secondly, How do I make the Order C Country and Order B Country under appropriate contacts? 
Thanks in advance for your help. 

Regards,
Yogesh
I am using a dynamic query but it fails with Use query() for non-count queries . What am I missing? 
 
for(Schema.ChildRelationship child : dsr.getChildRelationships()) {
String query=  'select count(id) FROM CONTACT WHERE ID NOT IN (SELECT '+
            	child.getField()+' FROM '+child.getChildSObject()+ ')'; 

        integer  t=Database.countquery(query);
system.debug(t);
}

 
Hello All,

Is there a way to know which objects have the lookups to contact? So far, I have found following objects in our instance

Events
Quotes
Lead 
CampaignMember
Case
ZendeskSupportTicket

Yogesh
How to find contacts which do not have cases, opportunities, activities, etc so that we can delete such contacts from the database? 
Thanks in advance.

Yogesh

 
In compliance with GDPR, we have implemented a process to delete all the user information from the database. After deleting the data we send a final email to the requester informing the actions taken. However, the final email message stays in the database and has the email address of the recipient. How can we delete the email after it is sent? 

Here is the code which sends the confirmation email. 
 
public void SendConfirmationEmailMessage(Contact_Preference__c cp){
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
 
        message.toAddresses = new String[] { cp.Email__c };
        message.setSubject('Data Deletion Confirmation Email');
        message.setHtmlBody(Messaging.renderStoredEmailTemplate('00X1W000001USk9', null, cp.id).getHTMLBody());
     Messaging.SingleEmailMessage[] messages =  
            new List<Messaging.SingleEmailMessage> {message};

     Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
        if (results[0].success) {
            System.debug('The email was sent successfully.');
        } else {
            System.debug('The email failed to send: '
                  + results[0].errors[0].message);
        }

    }

 
I have created a button to call apex class as suggested in https://help.salesforce.com/articleView?id=000006031&type=1. However, the code does not return to original page.  What am I missing? 

Here is the VF Page 
<apex:page standardController="Contact_Preference__c" extensions="myContactPreferenceControllerExtension" action="{!autoRun}">
   
    <apex:sectionHeader title="Auto-Running Apex Code"/>
    <apex:outputPanel >
        You tried calling Apex Code from a button.  If you see this page, something went wrong.  You should have 
        been redirected back to the record you clicked the button from.
       
    </apex:outputPanel>
</apex:page>

Here is the controller
public class myContactPreferenceControllerExtension {

    private final Contact_Preference__c cp;
    
    public myContactPreferenceControllerExtension(ApexPages.StandardController stdController) {
        this.cp = (Contact_Preference__c)stdController.getRecord();
    }

    public String getGreeting() {
        return 'Hello ' + cp.name + ' (' + cp.id + ')';
    }
    
 
    
    // Code we will invoke on page load.
    public PageReference autoRun() {
 
        String theId = ApexPages.currentPage().getParameters().get('id');
 
        if (theId == null) {
            // Display the Visualforce page's content if no Id is passed over
            return null;
        }
 
        for (Contact_Preference__c o:[select id, name,first_name__c,Email__c from Contact_Preference__c where id =:theId]) {
            // Do all the dirty work we need the code to do
            // 
            o.First_Name__c='FirstName';
            o.Last_Name__c='LastName';
           // o.Email__c='someone@somewhere.com';
          
            Blob targetBlob = Blob.valueOf(o.Email__c);
			Blob hash = Crypto.generateDigest('MD5', targetBlob);
            o.Email__c=EncodingUtil.convertToHex(hash)+'@somewhere.com';

           update o;
        }
 
        // Redirect the user back to the original page
        PageReference pageRef = new PageReference('/' + theId);
        pageRef.setRedirect(true);
        return pageRef;
 
    }
 
}

 
On the Opportunity record I have a quick action to create Contact roles. When I click on the quick action , I am opening a flow screen. And on that screen I need to prepopulate the Opportunity Id from where I came . What is the way ? 

I created a variable called recordID and set the type as input. Foe some reason that is not working. Any help ??