• Nitin Ledange
  • NEWBIE
  • 35 Points
  • Member since 2016

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 5
    Replies
Hello All,

Can you please help me to optimize below code ?
Need to avoid for() inside for(). Apart from that, if there's any other optimization, you can add that too.
Requirement :  whenever an attachment is inserted/attached to DTM_Uploaded_Document__c record , Clone all the attachment from DTM_Uploaded_Document__c to Merchant_Application Record Or Headless_Merchant_Staging record. There's no relationship between these 3 objects, Only Name is common between them. Also, once all the related attachments has been cloned to related merchant App or Staging, need to set a checkbox field to true of DTM_Uploaded_Document__c parent record.


public class VH_AddAttachemntToMerchantTriggerHandler extends TriggerHandler {
    
    Public override void afterInsert(){

        Map<String, List<Attachment>> NameMap = new Map<String, List<Attachment>>(); 

        List<Attachment> attList ;
        if(!Trigger.New.isEmpty()){
             attList = [SELECT Id, Name, Body, ContentType, Parent.Name, ParentId, Parent.Type FROM Attachment WHERE Id IN: Trigger.New AND Parent.Type = 'DTM_Uploaded_Document__c' LIMIT 50000];   
        }
         
        if(!attList.isEmpty())
        {
            for(Attachment a : attList) {
               if(!NameMap.containsKey(a.Parent.Name)){
                    NameMap.put(a.Parent.Name, new List<Attachment>{a});
                }
                else{
                    NameMap.get(a.Parent.Name).add(a);
                }     
            }  
        }
        

        Set<Id> parentIds = new Set<Id>();
        List<Attachment> insertAttachList = new List<Attachment>();
        Map<String, List<Attachment>> merchAttachMap = new Map<String, List<Attachment>>(); // to check if all the attachment from Document Upload Record has been attached to MerchantApp record OR Stagin Record
        List<VH_Merchant_Application__c    > merchAppList = new List<VH_Merchant_Application__c>([SELECT Id, Name FROM VH_Merchant_Application__c    WHERE Name IN: NameMap.keySet()]);
        List<VH_HeadlessService_MerchantApp_Staging__c> merchStagingList = new List<VH_HeadlessService_MerchantApp_Staging__c>([SELECT Id, Unique_Merchant_Key__c FROM VH_HeadlessService_MerchantApp_Staging__c WHERE Unique_Merchant_Key__c IN: NameMap.keySet()]);
       // clone the attachments to Merchant Application
        if(!merchAppList.isEmpty()){
            for(VH_Merchant_Application__c m : merchAppList){
                if(NameMap.containsKey(m.Name) && !NameMap.get(m.Name).isEmpty()){
                   for(Attachment a : NameMap.get(m.Name)){
                        Attachment b = a.clone();
                        b.ParentId = m.Id;
                        insertAttachList.add(b);
                        parentIds.add(a.ParentId);
                        
                       if(merchAttachMap.containsKey(m.Name)){
                                merchAttachMap.get(m.Name).add(a);   
                       }
                       else{
                           merchAttachMap.put(m.Name, new List<Attachment>{a});
                       }
                    }
                }
        }            
        }
        if(!merchStagingList.isEmpty()){
            for(VH_HeadlessService_MerchantApp_Staging__c vm : merchStagingList){
                if(NameMap.containsKey(vm.Unique_Merchant_Key__c) && !NameMap.get(vm.Unique_Merchant_Key__c).isEmpty()){
                    for(Attachment a : NameMap.get(vm.Unique_Merchant_Key__c)){
                        Attachment b = a.clone();
                        b.ParentId = vm.Id;
                        insertAttachList.add(b);
                        parentIds.add(a.ParentId); 
                        
                        if(merchAttachMap.containsKey(vm.Name)){
                                merchAttachMap.get(vm.Name).add(a);   
                        }
                        else{
                           merchAttachMap.put(vm.Name, new List<Attachment>{a});
                        }
                    }
                }
            }
        }
        if(!insertAttachList.isEmpty()){
              Insert insertAttachList;  
        }
        
        
        List<DTM_Uploaded_Document__c> updateDTMList = new List<DTM_Uploaded_Document__c>();
        if(!parentIds.isEmpty()){
            for(DTM_Uploaded_Document__c d : [SELECT Id, name, Can_be_Deleted__c FROM DTM_Uploaded_Document__c WHERE Id IN: parentIds]){
                if(nameMap.containsKey(d.Name) && merchAttachMap.containsKey(d.Name) && nameMap.get(d.Name).size() == merchAttachMap.get(d.Name).size()){
                    d.Can_be_Deleted__c = true;
                    updateDTMList.add(d);                    
                }

            }
        }
        
        if(!updateDTMList.isEmpty()){
            update updateDTMList;
        }
    }
}
need to update the Case Contact Phone field with Account Phone value whenever Account record is updated through the trigger.
My code : 
trigger CaseUpdate on Account (After update) {

    List<Case> toUpdateCases = new List<case>();
    for(Account a : Trigger.New){
        for(Account acc : [Select ID, Name, Phone,(Select ID, Contact.Phone, ContactId from Cases) from Account where ID=: a.Id]){
            for(Case C : acc.Cases){
                   c.Contact.Phone = acc.Phone;
                   toUpdateCases.add(c);
             }
        }
    }
    update toUpdateCases;
}

No Error but not Working.
Need help!
Challenge Not yet complete... here's what's wrong: 
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Update failed. First exception on row 0 with id 0060I00000UJtyaQAD; first error: CANNOT_EXECUTE_FLOW_TRIGGER, The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID 3010I000000YTYA. Flow error messages: An unhandled fault has occurred in this flow
An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information. Contact your administrator for help.: []
Does Anybody know the solution? 
Hi Guys, I'm trying to display all the related contacts to all the related Accounts (Accounts are returned by a SOQL query when I input some name in VF Page nd it uses Like 'input%' ). But I'm getting Visualforce Error  System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!find}' in component <apex:commandButton> in page passingvaluestocontroller: Class.aaPage52.find: line 24, column 1 Class.aaPage52.find: line 24, column 1 . 

Here's My Code : 
VF PAge : 
<apex:page controller="aaPage52">
<apex:form >
<apex:pageBlock title="Search" >
<apex:outputLabel for="searchString" value="Enter the Search String : ">
</apex:outputLabel>
<apex:inputText value="{!searchText}" id="searchString"/>
<apex:commandButton value="Find" action="{!find}" />
</apex:pageBlock>
<apex:pageBlock title="Results">
<apex:pageblockTable value="{!results}" var="r">
<apex:column value="{!r.name}"/>
<apex:column value="{!r.Phone}"/>
<apex:column value="{!r.Industry}"/>
</apex:pageblockTable>
</apex:pageBlock> 
<apex:pageBlock title="Contacts Related to this Account">
<apex:pageblockTable value="{!Contacts}" var="con">
<apex:column value="{!con.FirstName}"/>
<apex:column value="{!con.LastName}"/>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

Controller : 

public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry from Account where name LIKE :searchText+'%']; 
     If(results.size()!=0){
     List<contact> cont;
     for(Integer i=0; i< results.size(); i++){
       cont  = [Select FirstName, LastName from Contact where AccountID =:results[i].Id];       
     }
     con.addAll(cont);
     }
     update con;
     return null;
    }   
}

And Earlier when I didn't use con.addAll(cont); , I was able to Display the related Contacts  when Only one Account was returned by the Account Query. 


Appreciate your help.
Thanks,
Nitin Patil
I all of a sudden started to get this Error. Related to Picklist. It was working fine yesterday.

User-added image
Challenge Not yet complete... here's what's wrong: 
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Update failed. First exception on row 0 with id 0060I00000UJtyaQAD; first error: CANNOT_EXECUTE_FLOW_TRIGGER, The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID 3010I000000YTYA. Flow error messages: An unhandled fault has occurred in this flow
An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information. Contact your administrator for help.: []
Does Anybody know the solution? 
Hi Guys, I'm trying to display all the related contacts to all the related Accounts (Accounts are returned by a SOQL query when I input some name in VF Page nd it uses Like 'input%' ). But I'm getting Visualforce Error  System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!find}' in component <apex:commandButton> in page passingvaluestocontroller: Class.aaPage52.find: line 24, column 1 Class.aaPage52.find: line 24, column 1 . 

Here's My Code : 
VF PAge : 
<apex:page controller="aaPage52">
<apex:form >
<apex:pageBlock title="Search" >
<apex:outputLabel for="searchString" value="Enter the Search String : ">
</apex:outputLabel>
<apex:inputText value="{!searchText}" id="searchString"/>
<apex:commandButton value="Find" action="{!find}" />
</apex:pageBlock>
<apex:pageBlock title="Results">
<apex:pageblockTable value="{!results}" var="r">
<apex:column value="{!r.name}"/>
<apex:column value="{!r.Phone}"/>
<apex:column value="{!r.Industry}"/>
</apex:pageblockTable>
</apex:pageBlock> 
<apex:pageBlock title="Contacts Related to this Account">
<apex:pageblockTable value="{!Contacts}" var="con">
<apex:column value="{!con.FirstName}"/>
<apex:column value="{!con.LastName}"/>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

Controller : 

public class aaPage52 {
    List<Account> results;
    List<Contact> con;
    public String searchText { get; set; }    
    public List<Account> getResults() {
        return results;
    }    
    public List<Contact> getContacts() {
        return con;
    }
    
    public pageReference find(){
     results = [Select Name,Phone,Industry from Account where name LIKE :searchText+'%']; 
     If(results.size()!=0){
     List<contact> cont;
     for(Integer i=0; i< results.size(); i++){
       cont  = [Select FirstName, LastName from Contact where AccountID =:results[i].Id];       
     }
     con.addAll(cont);
     }
     update con;
     return null;
    }   
}

And Earlier when I didn't use con.addAll(cont); , I was able to Display the related Contacts  when Only one Account was returned by the Account Query. 


Appreciate your help.
Thanks,
Nitin Patil
We have Layout Read-only fields to be added. Seems like a bug, when we try to add read-only fields they become read-write on layout. Please see below example.
 
public class metadatatest {
    public static void runUpdateLayouts(){        
        Metadata.Layout la = getLayout('Account-Account Layout');

        Metadata.LayoutSection sec = new Metadata.LayoutSection();
        sec.customLabel = true;
        sec.detailHeading = true;
        sec.editHeading = true;
        sec.label = 'Custom fields';
        sec.style = metadata.LayoutSectionStyle.OneColumn;

        Metadata.LayoutColumn col1 = new Metadata.LayoutColumn();

        Metadata.LayoutItem layoutField = new Metadata.LayoutItem();

        layoutField.field = 'testfield__c';
        layoutField.behavior = metadata.UiBehavior.Readonly;

        col1.layoutItems.add(layoutField);
        sec.layoutColumns.add(col1);

        la.layoutSections.add(sec);

        Metadata.DeployContainer dc = new Metadata.DeployContainer();
        dc.addMetadata(la);

        Id jobid = Metadata.Operations.enqueueDeployment(dc,null);
    }

    public static Metadata.Layout getLayout(String layoutName){
        List<String> layoutList = new List<String>{layoutName};
            List<Metadata.Metadata> components = Metadata.Operations.retrieve(Metadata.MetadataType.Layout, layoutList);
        return (Metadata.Layout)components[0];
    }
}


Above code will add testfield__c field to Account standard layout. But it shows as Readonly in Layout editor. But in Account both view and edit modes it's read-write.

On Layout editor:
In Layout editor

On View/Edit mode:
Edit/View Mode

It's actually editable and saving data to Account object here. Feel free to try out above code snippet. Appreciate any fix/workaround for this. Thanks.

 
Hello
I have some difficulty in understanding the following

a) Normally apex code & trigger run in system.context
   But How to make the apex code execute in USER Mode?
   if the apex code executing in USER Mode  is called by a trigger, will the trigger also execute in USER Mode?

b) Can a visual force page run in USER Mode instead of system.context , again what changes need to be done and why?

c) By default webservice classes written in apex , rest api execute in what Mode?

d) what is the use of system.RunAs with respect to the above.

I hope I am clear

Thanks
Vandana R