+ Start a Discussion
Ravi Dutt SharmaRavi Dutt Sharma 
I have DOB (API Name : BirthDate__c) and I want to calculate age in years and months. I have created two formula fields
 
Age in years

FLOOR((TODAY()- BirthDate__c )/365.2425)
 
Age in months (remaining months)

FLOOR(MOD((TODAY()-BirthDate__c),365.2425)/30)

If date of birth is 11 Aug 2013 and todays date is 11 Aug 2015, this gives result as 1 year 12 months. Instead the result should be 2 years 0 months.
Best Answer chosen by Ravi Dutt Sharma
William TranWilliam Tran
Ravi,

Here's how I would approach it:

FORMULA for YEAR:
IF (  (MONTH(Today()) +12 - MONTH(BirthDate__c ))>=12, YEAR(Today())-YEAR(BirthDate__c), YEAR(Today())-YEAR(BirthDate__c) -1)

FORMULA for MONTH:
IF (  (MONTH(Today()) +12 - MONTH(BirthDate__c ))>=12,  (MONTH(Today()) +12 - MONTH(BirthDate__c ))-12, (MONTH(Today()) +12 - MONTH(BirthDate__c )))

Thx
Anusha ArrojuAnusha Arroju 
Hi everyone,can someone help how to write testclass for the below code..
Thanks in Advance.

public class Displayrelatedlists {
    //1.list of wrapperclass
     public list<AccountContactWrapper> lstAccountContactWrapper { get; set; }
    public list<AccountContactWrapper> lstSelectedAccountContactWrapper { get; set; }
    //list for selecting the account records
    public list<account> selectedAccounts{get;set;} 

    public Displayrelatedlists () {
        //Allocating the memory for the list
        lstSelectedAccountContactWrapper = new list<AccountContactWrapper>();
        if(lstAccountContactWrapper == null) {
            //allocate memory for the wrapperlist
            lstAccountContactWrapper = new list<AccountContactWrapper>();
            for(account a:[select id,name,phone,(select id,name from contacts)from account limit 10]) {
                lstAccountContactWrapper.add(new AccountContactWrapper(a));
            }
        }
    }
 
    public void ProcessSelected() {
        lstSelectedAccountContactWrapper =new list<AccountContactWrapper>();
        selectedAccounts =new list<Account>();
        for(AccountContactWrapper wrapobj:lstAccountContactWrapper){
            if(wrapobj.isSelected==true) {
                selectedAccounts.add(wrapobj.acc);
            } 
        }
       
        for(Account acc:[select id,name,phone,(select id,name from contacts) from account where id in:selectedAccounts]) {
            lstSelectedAccountContactWrapper.add(new AccountContactWrapper(acc)); 
        }
             
    }
    public class AccountContactWrapper {
 
        public Account acc {get;set;}
        public boolean isSelected {get;set;}
   
        public AccountContactWrapper(account a) {
            acc = a;
            isselected=false;
        }
    }
}
Best Answer chosen by Anusha Arroju
Maharajan CMaharajan C
Hi Anusha,

Please try the below test class:
 
@isTest
public class DisplayrelatedlistsTest {
    @isTest static void testDisplayrelatedlistsMethod(){

        // Add if there is any other fields are required for Account Create
        Account acc = new Account(Name = 'Test Account');
        insert acc;
        
        // Add if there is any other fields are required for Account Create
        List<Contact> conlist = new List<Contact>();
        conlist.add(new contact(lastname = 'Test Con', accountId = acc.Id));
        conlist.add(new contact(lastname = 'Test Con1', accountId = acc.Id));
        
        insert conlist;
        
        Displayrelatedlists disp = new Displayrelatedlists();
        
        for(Displayrelatedlists.AccountContactWrapper a : disp.lstAccountContactWrapper){
            a.isSelected = true;
        }
        
        Test.startTest();
        disp.ProcessSelected();
        Test.stopTest();
        
    }
}

Thanks,
Maharajan.C
srkSFsrkSF 
Hi All,
I am getting Null Pointer Exception: Attempting to de-reference a null object at this line only-----> DealsMap.put(deal.id,deal)

Screenshot of the Null Pointer Exception

User-added image

It's not displaying any values in tabular format from Map Collection in my VF Page also.
How do I fix this issue?Please help me!

Apex Class:

public with sharing class searchname1 {

    public PageReference edit() {
       
        return null;
    }

   public String name { get; set; }
    public list<Training_Deal__c> lstdeal { get; set; }
    public list<Course_Master__c> lstcourse { get; set; }
    public Map<id, Training_Deal__c> DealsMap { get; set; }
   
    
    public boolean searched{get;set;}
    
    //default constructor
    public searchname1(){
    searched=false;
    string namestr=apexpages.currentpage().getparameters().get('name');
    if(null!=namestr){
    name=namestr;
    }
               
    }
    public PageReference search() {
    searched=true;
     string searchstr1=('%'+name+'%');
         
           
        System.debug('-----------before for loop');
        try{
        for ( Course_Master__c crs : [select ID,Name,Course_Name__c,
                                      (select ID,Name,Course__c,Fees_Finalized__c from Training_Deals__r) from Course_Master__c 
            where Course_Name__c LIKE :searchstr1] ) {
                            for ( Training_Deal__c deal : crs.Training_Deals__r ) {
                                  System.debug(deal.Course__c + ' - ' + deal.Name + ' - ' + deal.Fees_Finalized__c );
                                 DealsMap.put(deal.id,deal);
                                 System.debug('Map of Deals-----'+DealsMap);  
                                }
                 
                            }
             System.debug('----------After for loop');   
        }catch(Exception e){
            System.debug('Exception occured'+e);
        }                    
          
              return null;
    }


    
}
VF Page:
<apex:page controller="searchname1" >
  <apex:form >
   <apex:pageblock id="one" >
    <apex:pageblockSection >
    <apex:pageblocksectionitem >
       <apex:outputlabel >Course to Search</apex:outputlabel>
         <apex:inputtext value="{!name}"/>
         </apex:pageblocksectionitem>
         <apex:commandButton value="Search" action="{!search}"/>
          </apex:pageblockSection>
      </apex:pageblock>       
           <apex:pageBlock id="SearchResults" rendered="{!searched}" >
               
           <!-- <apex:pageblocktable value="{!lstcourse}" var="c">
            <apex:column value="{!c.Name}"/>
                
             <apex:column value="{!c.Course_Name__c}"/>
            
               </apex:pageblocktable>
<apex:pageblocktable value="{!DealsMap}" var="d">
           
             <apex:column value="{!d.Name}"/>  
             <apex:column value="{!d.Course__c}"/>
             <apex:column value="{!d.Fees_Finalized__c}"/>     
            </apex:pageblocktable>
--> 
               

    <apex:pageBlock >
        <apex:repeat value="{!DealsMap}" var="d">
       {!d}<br/><br/>
         <apex:repeat value="{!DealsMap[d]}" var="d1">
        {!d1.name} <br/><br/>
         </apex:repeat>

    </apex:repeat>

               </apex:pageBlock>
        
   
     <apex:pageblockbuttons >
             <apex:commandButton value="edit" action="{!edit}"/>
            </apex:pageblockbuttons>
      </apex:pageBlock>
  </apex:form>
</apex:page>

 
Best Answer chosen by srkSF
Maharajan CMaharajan C
Hi Surekha,

You have to initiate the DealsMap in search method. Otherwise you will get the null pointer exception.

add the below in search method:
DealsMap = new Map<id, Training_Deal__c>();
 
public with sharing class searchname1 {

    public PageReference edit() {
       
        return null;
    }

   public String name { get; set; }
    public list<Training_Deal__c> lstdeal { get; set; }
    public list<Course_Master__c> lstcourse { get; set; }
    public Map<id, Training_Deal__c> DealsMap { get; set; }
   
    
    public boolean searched{get;set;}
    
    //default constructor
    public searchname1(){
    searched=false;
    string namestr=apexpages.currentpage().getparameters().get('name');
    if(null!=namestr){
    name=namestr;
    }
               
    }
    public PageReference search() {
    searched=true;
    DealsMap = new Map<id, Training_Deal__c>(); /// Add this line
     string searchstr1=('%'+name+'%');
         
           
        System.debug('-----------before for loop');
        try{
        for ( Course_Master__c crs : [select ID,Name,Course_Name__c,
                                      (select ID,Name,Course__c,Fees_Finalized__c from Training_Deals__r) from Course_Master__c 
            where Course_Name__c LIKE :searchstr1] ) {
                            for ( Training_Deal__c deal : crs.Training_Deals__r ) {
                                  System.debug(deal.Course__c + ' - ' + deal.Name + ' - ' + deal.Fees_Finalized__c );
                                 DealsMap.put(deal.id,deal);
                                 System.debug('Map of Deals-----'+DealsMap);  
                                }
                 
                            }
             System.debug('----------After for loop');   
        }catch(Exception e){
            System.debug('Exception occured'+e);
        }                    
          
              return null;
    }


    
}

Thanks,
Maharajan.C
Jonathan Wolff 7Jonathan Wolff 7 
Hello, I build a List button that Includes a Visualforce Page. When I chose Accounts in List view and click account I only see the blank Page without the account fields. Please tell me how to change it.

<apex:page standardController="Account" renderAs="pdf" recordSetVar="accounts" >
 

<h1>Welcome to APP!</h1>
 
<p>Thank you, <b><apex:outputText value=" {!Account.Name}"/></b>, for 
   working with APP.</p>
 
<p>Your account details are:</p>
 
<table>
<tr><th>Account Name</th>
    <td><apex:outputText value="{!Account.Name}"/></td>
    </tr>
<tr><th>Account Rep</th>
    <td><apex:outputText value="{!Account.Owner.Name}"/></td>
    </tr>
<tr><th>Customer Since</th>
    <td><apex:outputText value="{0,date,long}">
        <apex:param value="{!Account.CreatedDate}"/>
        </apex:outputText></td>
    </tr>
</table>
    
</apex:page>

User-added image


Result:

User-added image
Best Answer chosen by Jonathan Wolff 7
Maharajan CMaharajan C
Hi Jonathan,

Please try the below code:
 
<apex:page standardController="Account" renderAs="pdf" recordSetVar="accounts" extensions="AccountListPDFController">
    
    
    <h1>Welcome to APP!</h1>
    
    <apex:repeat value="{!accounts}" var="Account">
        
        <p>Thank you, <b><apex:outputText value=" {!Account.Name}"/></b>, for 
            working with APP.</p>
        
        <p>Your account details are:</p>
        
        <table>
            <tr><th>Account Name</th>
                <td><apex:outputText value="{!Account.Name}"/></td>
            </tr>
            <tr><th>Account Rep</th>
                <td><apex:outputText value="{!Account.Owner.Name}"/></td>
            </tr>
            <tr><th>Customer Since</th>
                <td><apex:outputText value="{0,date,long}">
                    <apex:param value="{!Account.CreatedDate}"/>
                    </apex:outputText></td>
            </tr>
        </table>
    </apex:repeat>
</apex:page>

Apex Class:
 
public class AccountListPDFController {
    public List<Account> accounts{get;private set;}
    public AccountListPDFController(ApexPages.StandardSetController stdSetController){
        accounts = (List<Account>) stdSetController.getSelected();
    }
}

Thanks,
Maharajan.C
​​​​​​​​​​​​​​
Sreenivas MSreenivas M 
I have a einstein which is attached to whatsapp channel,i have 2 different dialogs in bot,the first one will answers the question and second dialog basically ask the customer regarding feedback question.

On web chat these 2 messages are coming separately one by one but where in case of whatsapp all these 2 dialogs are going as single message so customer is couldn't identify the feedback question actually we are asking.User-added image
Best Answer chosen by Sreenivas M
Sreenivas MSreenivas M
According to the salesforce documentation it has been implemented in such way that all the messages in digital enagagement channels (whatsapp,facebook etc) the delay between the messages will be discarded. Because of this all the messages will be come in single block.Even if we tried using setting up the delay with flow it will not work.

https://help.salesforce.com/articleView?id=sf.bots_service_deploy_to_channels.htm&type=5

User-added image
Vishy RamVishy Ram 
All: 

I am trying to do a change set for Lead assignment from one sand box to another. I get the following error, not sure what to make of it. 
1. I ensured the profile does have Read, Edit & View all object permission on leads.
2. I am successfully able to upload the change set to my target sand box org.
3. But get the following error on validation. please sos. (Is it a profile, permission issue or some thing with the actual assignment rule that is not correct).

Error message:
Line 3 Column 21 (Assignee does not have permission to view leads: Assignee ID). Which Line 3 and what column 21 and what does the error mean.

please sos.

vishy
609 284 7018 (vishy.ram@capgemini.com)
Best Answer chosen by Vishy Ram
logontokartiklogontokartik
Hi,
Can you pull out the assignment rules xml out and verify for lead? You can define a package.xml file and retrieve all the rules. 


<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
        <members>Lead</members>
        <name>AssignmentRules</name>
 </types>
    <version>31.0</version>
</Package>
The retrieved file will help you figure out which one is causing issue

MatK62MatK62 
I am having trouble completing the challenge for the "Create and Edit Lightning Components" module of the "Lightning Components Basics" trail. Here is the challenge:

Create a camping component that contains a campingHeader and a campingList component.
    The campingList component contains an ordered list of camping supplies that include Bug Spray, Bear Repellant, and Goat Food.
    The campingHeader component contains an H1 heading style with a font size of 18 points and displays 'Camping List'.

Here is my code:

camping.cmp

<aura:component >   
    <c:campingHeader/>
    <c:campingList/>
</aura:component>

campingHeader.cmp

<aura:component >
    <H1>Camping List</H1>
</aura:component>

campingHeader.css

.THIS {
}

H1.THIS {
    font-size: 18px;
}

campingList.cmp

<aura:component >
    <aura:attribute name="campingSupplies" type="List" default="['Bear Repellant', 'Bug Spray', 'Goat Food']" />
</aura:component>

When I check the challenge, I get the error message:

Challenge Not yet complete... here's what's wrong:
The component is not using the correct font size.

Any help is greatly appreciated.
Best Answer chosen by MatK62
Nayana KNayana K
campingList.cmp

<aura:component >
    <ol>
<li>Bear Repellant</li>
<li>Bug Spray</li>
<li>Goat Food</li>
</ol>
</aura:component>


campingHeader.css

.THIS {
}

H1.THIS {
    font-size: 18pt;
}
 
SS KarthickSS Karthick 
Hi folks,
       can anyone tell me soql for getting user id who has access the record??
Like 
I have created test objects
5 users in my org.
if user 1 creates record on test object then user2,user3,user5 access that reocrd and user4 cannot access the reocrd
I wanna soql query for get all user id who has permission to access the record that is created by user1

Thanks in advance
Karthick
Best Answer chosen by SS Karthick
bob_buzzardbob_buzzard
You can get at this information by querying the <sobject>Share sobject, although you may need to query public groups to see which users are members if the sharing is based on groups.

Each <sobject>Share record is the same format regardless of the actual sobject type - here's the docs for CaseShare:

https://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_caseshare.htm
Toyota System 3Toyota System 3 
Apex tests have started to fail where we assert PersonEmail field is populated.

Replicated the issue in Execute Anonymous via the following code:
Account customer = new Account();
customer.RecordTypeId=[select id from RecordType where sObjectType = 'Account' and DeveloperName = 'Consumer' limit 1].Id;
customer.lastname='Test Account';
customer.personEmail = 'test.testAAA@example.eu';
customer.PersonHomePhone = '061386212';
insert customer;

customer= [select id, name, firstname, lastname, personEmail, PersonHomePhone, IsPersonAccount  from account where id=:customer.id];
system.debug(logginglevel.info,'Account = '+customer);
system.debug(logginglevel.info,'Account.personEmail = '+customer.personEmail);
system.debug(logginglevel.info,'Account.PersonHomePhone = '+customer.PersonHomePhone);
The debug logs show PersonHomePhone populated but PersonEmail is null.  The Person Email field is visible on the record after creation via the UI and via a query in Developer Console.

After a random period of time the same query in Execute Anonymous starts to return the PersonEmail field.

I have also witnessed the field being populated if I query it via a list, but empty if I specify an Id in the where clause.

Query list:
SOQL1

Query with Id:
SOQL2

Very strange behaviour.

There seems to be some slow running process that means PersonEmail is not immedeatly available to query (even though it is visible via the UI).

Please help.
 
Best Answer chosen by Toyota System 3
Toyota System 3Toyota System 3
This has now been confirmed as a Known Issue.

https://trailblazer.salesforce.com/issues_view?id=a1p4V000002BQKcQAO
 
SattibabuSattibabu 
Create an Apex class that returns an array (or list) of strings: 
Create an Apex class that returns an array (or list) of formatted strings ('Test 0', 'Test 1', ...). The length of the array is determined by an integer parameter.The Apex class must be called 'StringArrayTest' and be in the public scope.
The Apex class must have a public static method called 'generateStringArray'.
The 'generateStringArray' method must return an array (or list) of strings. Each string must have a value in the format 'Test n' where n is the index of the current string in the array. The number of returned strings is specified by the integer parameter to the 'generateStringArray' method.

MyApexClass to above Challenge:

public class StringArrayTest {
    
    public static List<string> generateStringArray(Integer n)
    {
        List<String> myArray = new List<String>();
        
        for(Integer i=0;i<n;i++)
        {
            myArray.add('Test'+i);
            System.debug(myArray[i]);
        }
        return myArray;
        
    }


It's compile and execute as per requirement in Developer console. But Traihead showing the below error:

Challenge not yet complete... here's what's wrong: 
Executing the 'generateStringArray' method failed. Either the method does not exist, is not static, or does not return the proper number of strings.

Anyhelp would be greatly appreciated. Thanks.
 
Best Answer chosen by Sattibabu
Carolina Ruiz MedinaCarolina Ruiz Medina
Hi Sattibabu,
Please find below a little fix for your issue.

The problem was the space between Test and the number you had : Test0, Test1.... and what was necessary was Test 0, Test 1, ... 
public class StringArrayTest {
    
    public static List<String> generateStringArray(Integer n)
    {
        List<String> myArray = new List<String>();
        for(Integer i=0;i<n;i++)
        {
           myArray.add('Test '+i);
           System.debug(myArray[i]);
        }
        return myArray;
    }
}

Also I will say that if in the test we pass through a negative value it will create values in the array then maybe for real purposes you would like to validate that.

Hope it it helpful :)

Regards,
Carolina.