+ Start a Discussion
Cloud AtlasCloud Atlas 
Hi ,

Can some one help me to write a trigger to prevent delete of all Account records and its supporting test class.
Doesn't matter who the user is (Sys Admin/Custom Profile/Read Only...etc), the user should not be able to delete the account record.
There cannot be any exception.

Any help is appreciate.
Thanks!
A
Best Answer chosen by Cloud Atlas
Mohan_ShanmugamMohan_Shanmugam
Hi Ashish,

Here is the trigger which will prevent deletion of Account record.
trigger preventAccountDeletion on Account (before delete) {

    for(Account acc : trigger.old){
        acc.adderror('Account Cannot be deleted');
    }

}

TestClass for the above trigger would be
@isTest
private class testPreventAccountDeletion {
	
    static testmethod void testPreventAccDel(){
        Account accRecord = new Account(name='testAccount');
        insert accRecord;
        
        try{
            delete accRecord;
        }catch(DMLexception e){
            system.assert(e.getMessage().contains('Account Cannot be deleted'),'Account Cannot be deleted');                       
        }
    }
}

i did not get this - "There cannot be any exceptions"

with the above no user cannot delete a Account record, if attempted to do then a validation will thrown on a different page informing that account cannot de deleted. Below is the screensshot of error message.

User-added image
If you want the error to be in a differnt fashion then override the delete button with VF page as you like.

Hope this helps!

Thanks,
Mohan Shanmugam
 
Yogesh BiyaniYogesh Biyani 
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? 
Best Answer chosen by Yogesh Biyani
AubryAubry
Yogesh, your test class must re-query the lead to get the new owner Id, after calling the "leadAssign" method on line 20.
@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);
      Lead createdLead = [SELECT OwnerId FROM Lead WHERE Id = :leadToCreate.Id];
      System.assertEquals('00G1W000002RyhMUAS', createdLead.OwnerId, 'Something is wrong');

 	//  Test.stopTest();
      
   }
}

this code should work
Beauty Kumari 1Beauty Kumari 1 
I created a trigger on case. Member_ID__c is a auto-number field on contact object. I am trying to find out repeat cases logged by a contact using custom checkbox Repeat_Caller__c on case. There are many other conditions, but I removed them in this code for simplicity. I am not able to match Member_ID__c field in cases even though multiple cases are created by the same contact. In other words, I am not able to enter the IF condition. I have pasted the trigger below.

Please guide me as to where the problem might be. Any help is appreciated.

 
trigger repeatCase1 on Case (before insert,before update) {
    List<Case> caseList = trigger.new;   
    Set<id> memberIdSet = new set<id>();
    for(case c: caseList){
        memberIdSet.add(c.Contact.Member_ID__c);
    }
      List<Case> allcase = [select Contact.Member_ID__c from case where contact.Member_ID__c IN: memberIdSet];               
      for(Case cs: caseList ){  
        for(Case all: allcase ){ 
            if(cs.contact.Member_ID__c == all.contact.Member_ID__c ){
                    cs.Repeat_Caller__c=True;
            }
        }
    }
    
}
Best Answer chosen by Beauty Kumari 1
Boss CoffeeBoss Coffee
I don't believe trigger.new will have access to its parent's fields, so attempting to access those fields will return null. The following handles before insert. I use a Map to hold the Contacts that the Trigger.new Cases look up to, thus you can access the appropriate Contact Member Id field when you do your checks in the for loop.
if(Trigger.isBefore && Trigger.isInsert) {
        // Get the list of Cases from trigger.new
        List<Case> caseList = trigger.new;   
        
        // Get a set of Contact Ids that will be used for queries
        Set<Id> contactIds = new Set<Id>();
        for(case c: caseList){
            // For each case from the trigger, add its Contact Id to the set
            contactIds.add(c.ContactId);
        }
        
        // Now, get a list of cases that would look up to the same Contact (and safety check to make sure its Member Id field is not null)
        List<Case> allcase = [select Id, ContactId, Contact.Member_Id__c from case WHERE ContactId IN :contactIds AND Contact.Member_Id__c != null];
        
        // Grab a Map of Contacts that are looked up to by the trigger Cases
        Map<Id,Contact> conMap = new Map<Id,Contact>([SELECT Id, Name, Member_Id__c FROM Contact WHERE Id IN :contactIds AND Contact.Member_Id__c != null]);
        
        for(Case cs: caseList ){  
            for(Case all: allcase ){ 
                // For the trigger Case, grab the Contact Member Id field from the Map and compare with the Case already existing
                if(conMap.get(cs.ContactId).Member_Id__c == all.Contact.Member_Id__c ){
                    // If there is a match, then set the field to true
                    cs.Repeat_Caller__c=True;
                }
            }
        }
    }
AlasAlas 

What is MVC??

 

I know it as MODEL(objects) VIEW(visualforce) CONTROLLER(apex).

 

 

Why we will call as MVC, and if some one asks what is MVC what definition i can tell.

 

What is the use of MVC architecture??

Best Answer chosen by Admin (Salesforce Developers) 
SamuelDeRyckeSamuelDeRycke

It's a code design pattern that seperates your code into the parts you listed yourself. The use is a better structure of your code, which makes it easier to change and maintain it. With little impact, you should for instance be able to replace the entire view, without changes to the model or controller logic.

 

This is a well established pattern, and there are 1000 articles, blogs, papers, books,video's  about it.   http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller (chek out the references for more info)

jkcjkc 
I am trying to figure out how Queue works, so I created a new queue in Leads but now I can't figure out how exact can a record be manually added to the queue list. Any help is appreciated thank you! :)
Best Answer chosen by jkc
Vinoth Vijaya BaskerVinoth Vijaya Basker
Hi, 

You can add the record by clicking [Change] which is available near Owner field. 

Please let me know, if you have any questions. 

Thanks,
Vinoth
Suzanne WasnerSuzanne Wasner 
I know I have completed the challenge correctly but keep getting this error. Note that the challenge has you create a "custom" object, not a "customer" object as stated in the error. I would like my 500 pts, please. :-)
Best Answer chosen by Suzanne Wasner
Ajay K DubediAjay K Dubedi
Hi Suzanne,

Remember, this module is meant for Lightning Experience. When you launch your hands-on org, switch to Lightning Experience to complete this challenge.

Please try the below steps:

1. You create new Trailhead Playground.
2. Click the Object Manager tab.
4. Click Create | Custom Object in the top right corner.
5. For Label, enter 'Offer'.
6. For Plural Label, enter 'Offers'.
7.Object Name 'Offer'.
8.Record Name 'Offer Name'.
9.Data type 'Auto Number'.
10.Display format 'OF-{0000}'.
11.string number 123.
12. Check the box for Launch New Custom Tab Wizard after saving this custom object.
13. Leave the rest of the values as default and click Save.
14. Select your desired Tab Style and click Next, Next, and Save.
15. Then goto Fields & Relationships in 'Offer' object and click 'New' button in top right corner.
16. In data type select Currency and click next.
17. For Label, enter 'Offer Amount'.
18. Select your desired Tab Style and click Next, Next, and Save.
19. In data type select Date and click next.
20. For Label, enter 'Target Close Date'.
21. Select your desired Tab Style and click Next, Next, and Save.

Please let me know if you have any query.
    
Please mark it as best Answer if you find it helpful.

Thank You
Ajay Dubedi
maxoutmaxout 

Hi, is it possible to create nested table on apex page using  pageBlockTable or other tags?

 

I got an erreor: Save error: Object type not accessible. Please check permissions and make sure the object is not in development mode: SOQL statements cannot query aggregate relationships more than 1 level away from the root entity object. RequestAsPDF.page.

 

Using <apex:column breakbefore> and a controller extention could fill the child table content in a new row.

But is there anything already there to use? Thanks.

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

You can not do this:

 

 

<apex:page standardController="Account">
    <apex:pageBlock>
        <apex:pageBlockTable value="{!Account.Contacts}" var="theContact">
            <apex:column>
                {!theContact.FirstName} {!theContact.LastName}
            </apex:column>
            <apex:column>
                <apex:pageBlock>
                    <apex:pageBlockTable value="{!theContact.ActivityHistories}" var="theActivity">
                        {!theActivity.Subject}
                    </apex:pageBlockTable>
                </apex:pageBlock>
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

When the page is compiled, it generates a SOQL query that looks like this:

 

 

SELECT Id,
  (SELECT Id,FirstName,LastName,
    (SELECT Id,Subject FROM ActivityHistories)
   FROM Contacts)
FROM Account

This isn't a legal syntax (you can't query more than one level down). Instead, you need to query the data in a controller or extension and then expose the data that way.

 

Edit: Clarification. The point here is that you can't use something that will be dynamically generating a query in this case. Ideally, you'd do something like this:

 

 

public class account_wrapper {
  public account record { get; set; }
  public list<contact_wrapper> contacts { get; set; }
}

public class contact_wrapper {
  public contact record { get; set; }
  public list<activity_wrapper> activities { get; set; }
}

public class activity_wrapper {
  public activityhistory record { get; set; }
}

 

Elsewhere in your controller, call the necessary recursive queries to get all the data you need to populate this structure.

 

Finally, in your VF page, you can nest the tags recursively, as what you were originally trying to do; the syntax will be slightly different, obviously, because now you have a class that wraps the values in a way that can be fed to the pageBlockTable tag.

bobnunny1bobnunny1 
I'm trying to complete the trail module named in the subject, but I'm getting an error of:
Challenge Not yet complete... here's what's wrong: 
Couldn't find newField.behavior set to 'Metadata.UiBehavior.Edit', or newField.field set to 'AMAPI__Apex_MD_API_Twitter_name__c' or method doesn't return 'layoutMetadata'. Please double-check the instructions

Everything looks right to me in the class.  I can't use the namespace they provide because it's already taken.   Earlier in the exercise, it tells you to use your own namespace which I've done.  Can anyone see what's wrong?
 
public class UpdateContactPageLayout {
    // Add custom field to page layout
    
    public Metadata.Layout addLayoutItem () {
        
        // Retrieve Contact layout and section 
        List<Metadata.Metadata> layoutsList = 
            Metadata.Operations.retrieve(Metadata.MetadataType.Layout, 
            new List<String> {'Contact-Contact Layout'});
        Metadata.Layout layoutMetadata = (Metadata.Layout) layoutsList.get(0);
        Metadata.LayoutSection contactLayoutSection = null;
        List<Metadata.LayoutSection> layoutSections = layoutMetadata.layoutSections;
        for (Metadata.LayoutSection section : layoutSections) {
            
            if (System.equals(section.label, 'Additional Information')) {
                contactLayoutSection = section;
                break;
            }
        }
        
        // Add the field under Contact info section in the left column
        List<Metadata.LayoutColumn> contactColumns = contactLayoutSection.layoutColumns;     
        List<Metadata.LayoutItem> contactLayoutItems = contactColumns.get(0).layoutItems;
        
        // Create a new layout item for the custom field
        Metadata.LayoutItem newField = new Metadata.LayoutItem();
        newField.behavior = Metadata.UiBehavior.Edit;
        newField.field = 'BOBN_TRAILHEAD__Apex_MD_API_Twitter_name__c';
        contactLayoutItems.add(newField);
        
        return layoutMetadata;
    }
}

 
Best Answer chosen by bobnunny1
Bill DodsonBill Dodson
Mine is exactly like yours except line 28 I have as:

newField.field = 'AMAPI__Apex_MD_API_Twitter_name__c';

Challenge completed for me.
Derek DolanDerek Dolan 
I have been building a VF page that updates child and parent records 

The error that I get back after inputting is
​​​​​​
Visualforce Error
Help for this Page

System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!insertChild}' in component <apex:commandButton> in page updatechild: Class.AddingChildController.insertChild: line 23, column 1


User-added image
​​​​​​This is the VF page
 
<apex:page controller="AddingChildController" >
<apex:form >
    <apex:variable var="rowNum" value="{!0}" />
    <apex:pageBlock >
        <apex:variable var="rowNum" value="{!0}" />
        <apex:PageBlockTable value="{!childList}" var="int">
        <apex:facet name="footer">
            <apex:commandLink value="Add" action="{!insertRow}"/>
            </apex:facet>
            <apex:column headerValue="Lead Generator">
                <apex:inputField value="{!int.Lead_Gen__c}"/>                                      
            </apex:column>
            
            
            
            <apex:column headerValue="Monday">
            <apex:inputField value="{!int.Monday__c}"/>
            </apex:column>
            <apex:column headerValue="Tuesday">
            <apex:inputField value="{!int.Tuesday__c}"/>
            </apex:column>
            <apex:column headerValue="Wednesday">
            <apex:inputField value="{!int.Wednesday__c}"/>
            </apex:column>
            <apex:column headerValue="Thursday">
            <apex:inputField value="{!int.Thursday__c}"/>
            </apex:column>
            <apex:column headerValue="Friday">
            <apex:inputField value="{!int.Friday__c}"/>
            </apex:column>
             <apex:column headerValue="Delete">
            <apex:commandLink style="font-size:15px; font-weight:bold; text-align:center;color:red;" value="X" action="{!delRow}">
                <apex:param value="{!rowNum}" name="index"/>
                </apex:commandLink>
                <apex:variable var="rowNum" value="{!rowNum+1}"/>
            </apex:column>
        </apex:PageBlockTable>
    <apex:pageBlockButtons >
        <apex:commandButton value="Save" action="{!insertChild}"/>
        </apex:pageBlockButtons>
    </apex:pageBlock>

  </apex:form>
</apex:page>

And this is the controller

 
public class AddingChildController {
Id parentId;
public List<Time_Sheets__c> childList {get;set;}
public Integer rowNum{get;set;}

public Lead_Gen__c Parent {get;set;}
 
 
 


public AddingChildController(){
    Id childId = ApexPages.currentPage().getParameters().get('childId');
    childList = new List<Time_Sheets__c>();
    childList.add(new Time_Sheets__c());
    ParentId=ApexPages.currentPage().getParameters().get('ParentId');   
      
}

public pagereference insertChild(){
    insert childList;

    Parent.Id=parentId;
    update Parent;

    Pagereference page=new pagereference('/'+parentId);
    Return page;

       
}    

public void insertRow(){
    childList.add(new Time_Sheets__c());
    
    
}

public void delRow(){
    rowNum = 
Integer.valueof(apexpages.currentpage().getparameters().get('index'));

childList.remove(rowNum);
}
}

​​​​​​Could someone assist with what I am missing

cheers 
Best Answer chosen by Derek Dolan
Khan AnasKhan Anas (Salesforce Developers) 
Hi Derek,

Greetings to you!

This error occurs when your variable (sObject, List, Set or any other data type) is not initialized (allocated memory). In order to use the non-primitive data type in the code, we need to initialize the memory first. If we don’t do that it may result in Attempt to de-reference a null object error. 

For Example, if you use like this:
Account acc;
acc.Name = 'Khan';

It will result in attempt to de-reference a null object error.

We should use it like this:
Account acc = new Account();
acc.Name = 'Khan';

Reference: http://www.sfdcpoint.com/salesforce/system-nullpointerexception-attempt-to-de-reference-a-null-object/

In your code, you need to initialize the Parent in the constructor:
Parent = new Account();

Please try below code:
public class AddingChildController {
Id parentId;
public List<Time_Sheets__c> childList {get;set;}
public Integer rowNum{get;set;}

public Lead_Gen__c Parent {get;set;}
 
 
 


public AddingChildController(){
    Parent = new Account();
    Id childId = ApexPages.currentPage().getParameters().get('childId');
    childList = new List<Time_Sheets__c>();
    childList.add(new Time_Sheets__c());
    ParentId=ApexPages.currentPage().getParameters().get('ParentId');   
      
}

public pagereference insertChild(){
    insert childList;

    Parent.Id=parentId;
    update Parent;

    Pagereference page=new pagereference('/'+parentId);
    Return page;

       
}    

public void insertRow(){
    childList.add(new Time_Sheets__c());
    
    
}

public void delRow(){
    rowNum = 
Integer.valueof(apexpages.currentpage().getparameters().get('index'));

childList.remove(rowNum);
}
}

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
vandana rajuvandana raju 
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
Best Answer chosen by vandana raju
Navin SoniNavin Soni
Hi Vandana,

System mode -
  • System mode is nothing but running apex code by ignoring user's permissions. For example, logged in user does not have create permission but he/she is able to create a record.
  • In system mode, Apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren't applied for the current user. This is to ensure that code won’t fail to run because of hidden fields or objects for a user.
  • In Salesforce, all apex code run in system mode. It ignores user's permissions. Only exception is anonymous blocks like developer console and standard controllers. Even runAs() method doesn't enforce user permissions or field-level permissions, it only enforces record sharing.
User mode - 
  • User mode is nothing but running apex code by respecting user's permissions and sharing of records. For example, logged in user does not have create permission and so he/she is not able to create a record.
  • In Salesforce, only standard controllers and anonymous blocks like developer console run in user mode.
Thank You,
Navin Soni