Tuesday, June 30, 2015

Trigger : Throw an error if we try to update an Account with contacts

Recently I got a requirement on Triggers.Trigger should trow an error if we try to update an Account which contains child contacts.
Update should be successful if Account does not contains any child Contacts.
I felt some how difficulty in writing this trigger by considering governor limits and optimizing the use of collections but I managed to write the trigger successfully.. After writing this trigger I wanted to share it with others and here is the trigger.

trigger AccountsWithContacts on Account (before update) {
    
    Set<Id> accWithContacts = new Set<Id>();
    for(Contact c: [Select Id,Name,AccountId from Contact Where AccountId In: Trigger.NewMap.KeySet()])
    {
        accWithContacts.add(c.AccountId);
    }
    
    for(Account acc:Trigger.New)
    {
        if(accWithContacts.Contains(acc.Id))
            acc.addError('could not update Account with contacts');
    }

}



Monday, June 22, 2015

Difference between apex:message,apex:messages,apex:pageMessage and apex:pageMessages in salesforce

We have different components that supports displaying messages in a visual force page like <apex:message>,<apex:messages>,<apex:pageMessage> and <apex:pageMessages>. Let us see how each component behaves.

Lets take some sample code to understand each component. We have not included any message components in the VF.

<apex:page controller="MyRegisterCon2" sidebar="false" docType="HTML-5.0"   >

<apex:form >
  <apex:pageBlock >
  <apex:pageblockSection columns="1" >
  <apex:inputtext value="{!FirstName}" label="First Name"  />
  <apex:inputtext value="{!LastName}" label="Last Name" />
  <apex:input value="{!Jdate}" label="DOB" type="date" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"/>
  </apex:pageblockSection>
  <apex:pageBlockButtons >
  <apex:commandButton value="submit" action="{!save}" />
  </apex:pageBlockButtons>
  </apex:pageBlock>
  </apex:form>
</apex:page>

public with sharing class MyRegisterCon2 {

    public Date Jdate { get; set; }
   
    public Integer Phone { get; set; }
    
    public String LastName { get; set; }

    public String FirstName { get; set; }
    
    public PageReference save() {
    
        return null;
    }
       

}





Though phone and DOB are not strings it is not showing any errors when you click on submit.


<apex:message>:

This  component is used to display warning or error message for a specific component.

Change visualforce to following code.

<apex:page controller="MyRegisterCon2" sidebar="false" docType="HTML-5.0"   >

<apex:form >
  <apex:pageBlock >
  <apex:pageblockSection columns="1" >
  <apex:message for="phone" />
  <apex:inputtext value="{!FirstName}" label="First Name"  />
  <apex:inputtext value="{!LastName}" label="Last Name" />
  <apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />

  </apex:pageblockSection>
  <apex:pageBlockButtons >
  <apex:commandButton value="submit" action="{!save}" />
  </apex:pageBlockButtons>
  </apex:pageBlock>
  </apex:form>

</apex:page>







In above code I have included  <apex:message for="phone" /> . Though we have given text for DOB and Phone fields the message is shown for only specific component.
 i.e. Phone.

<apex:messages>

Include above code in VF page it will display all the messages . If we observe styling was not applied to the messages.

<apex:page controller="MyRegisterCon2" sidebar="false" docType="HTML-5.0"   >

<apex:form >
  <apex:pageBlock >
  <apex:pageblockSection columns="1" >
  <apex:messages />
  <apex:inputtext value="{!FirstName}" label="First Name"  />
  <apex:inputtext value="{!LastName}" label="Last Name" />
  <apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />
  </apex:pageblockSection>
  <apex:pageBlockButtons >
  <apex:commandButton value="submit" action="{!save}" />
  </apex:pageBlockButtons>
  </apex:pageBlock>
  </apex:form>

</apex:page>





<apex:pageMessages>

The  above component provides the SF styling for the messages. 

<apex:page controller="MyRegisterCon2" sidebar="false" docType="HTML-5.0"   >

<apex:form >
  <apex:pageBlock >
  <apex:pageblockSection columns="1" >
  <apex:pageMessages />
  <apex:inputtext value="{!FirstName}" label="First Name"  />
  <apex:inputtext value="{!LastName}" label="Last Name" />
  <apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />
  </apex:pageblockSection>
  <apex:pageBlockButtons >
  <apex:commandButton value="submit" action="{!save}" />
  </apex:pageBlockButtons>
  </apex:pageBlock>
  </apex:form>

</apex:page>





<apex:pageMessage>

This component is used to dispaly custom messages with severity error,warning etc.  in the VF page.

<apex:page controller="MyRegisterCon2" sidebar="false" docType="HTML-5.0"   >

<apex:form >
  <apex:pageBlock >
  <apex:pageblockSection columns="1" >
  <apex:pageMessage summary="This is page message"  severity="warning" strength="3" />
  <apex:inputtext value="{!FirstName}" label="First Name"  />
  <apex:inputtext value="{!LastName}" label="Last Name" />
  <apex:input value="{!Jdate}" label="DOB" type="date" id="dob" />
  <apex:inputtext value="{!Phone}" label="Phone"  id="phone"  />
  </apex:pageblockSection>
  <apex:pageBlockButtons >
  <apex:commandButton value="submit" action="{!save}" />
  </apex:pageBlockButtons>
  </apex:pageBlock>
  </apex:form>

</apex:page>




Hope this will be helpful to understand differrent messages in VF.

Thanks,
Naveen.

Tuesday, April 7, 2015

How to generate weekly report and sent it as a attachment in mail in Salesforce?

Problem:
 We can generate reports as per our requirement using standard Report Builder Functionality.
With report builder we can create reports ,run reports and even we can schedule and send through mails.


The problem is we can get report as body of the mail not as attachment .

 

Solution:

With  Apex Code we can send reports as attchemnts. This is ideal, because you can have the code run weekly, scheduled inside your salesforce.com instance. No visualforce necessary in this case, because the results could be emailed or submitted to an HTTP server (not FTP, because Apex Code can't yet do that).
  Below is the sample code which gets content from Report and prepares an attachment to send through mail.
  It implements System.Schedulable interface so we can schedule this class to run weekly or monthly.
 

global class Accounts_Weekly_Report implements System.Schedulable {
    global void execute(SchedulableContext sc) {
        ApexPages.PageReference report = new ApexPages.PageReference('/00OF0000006WD6L?csv=1');
        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
        attachment.setFileName('Accounts_Weekly_Report.csv');
        attachment.setBody(report.getContent());
        attachment.setContentType('text/csv');
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        message.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment } );
        message.setSubject('Accounts Weekly Report');
        message.setPlainTextBody('The report is attached.');
        message.setToAddresses( new String[] { 'abc1@test.com','abc2@test.com' } );
        message.setCcAddresses(new String[] { 'abc3@test.com'});
        Messaging.sendEmail( new Messaging.SingleEmailMessage[] { message } );
        
    }
    }


Thanks,
Naveen.
www.autorabit.com 

Monday, March 9, 2015

Validation before the deployment with ANT

We can do deployment from one org to another using eclipse or Ant migration tool.  To validate the deployments we have an option Validate deployment in eclipse. Where it does a  deployment check and never actually saves to the server. We can do same by using Ant using  A task called deployCodeCheckOnly.

   <target name="deployCodeCheckOnly">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" deployRoot="retrieveUnpackaged" checkOnly="true"/>
    </target>

Thanks,
Naveen.
http://www.autorabit.com/

New enhancements/Features related to Developement/APIs in Salesforce Spring 15

As we know new Salesforce Spring 15 (i.e. Version 33) is  came into live from mid of February 2015. Following are the main features or enhancements related to Developement/APIs in Salesforce Spring 15.
 
   Force.com development and API Enhancements:
  1.   Deploy to production without running all tests with Quick Deploy. You can now deploy components to production by skipping the execution of all Apex tests for components that have been validated within the last four days.
  2. New Visualforce attributes for Visualforce map component displays locations more precisely.
  3. The URLFOR function has been optimized for use with attachments in Visualforce.
  4.  Submit more batch jobs with Apex Flex Queue.
  5.   Use asynchronous callouts to make long-running requests from a Visualforce page to an external Web service and process responses with callback methods (aka, Long-Running Callouts).
  6.   Setup test data for an entire test class and then access them in every test method in the test class using the new @testSetup annotation.
  7.      Queueable Apex can now chain a job to another job an unlimited number of times.
  8.       The Apex callout size limit for requests and responses has been increased to the heap size limit.
  9.       List Apex classes and triggers with a Tooling API endpoint.
  10.    If you use ConnectApi (Chatter in Apex) there are an extremely large number of enhancements to checkout.
  11.  There is a number of new and modified Apex classes and interfaces so see the docs for details.
  12.     API v33.0 has a large number of new and changed objects for you to pore over. The REST API now supports insert/update of BLOB data plus CORS support!
  13.     The Streaming API now supports generic streaming for events that aren’t tied to Salesforce data changes.
  14.    The Tooling API adds SOSL support and a few new objects and new fields on existing objects.
  15.     For ISV there are also a number of enhancements that will make you happy and your jobs easier.
 Thanks,
Naveen.

Sunday, February 8, 2015

What is the difference between Insert and Database.Insert in salesforce.


Insert
If we use the DML statement (insert), then in bulk operation if error occurs, the execution will stop. In that case Apex code throws an error and none of the record is inserted to the database.


Database.Insert
If DML database methods (Database.insert) used, then if error occurs the remaining records will be inserted / updated means partial DML operation will be done. The only record throwing an error will not be inserted / updated.

So you should use Database.insert in any bulk dml operation if you are not monitoring the code properly

Regards,
Naveen,
http://www.autorabit.com/.

How to delete data from Recycle bin in salesforce.

When we use DML statement delete the data is deleted from that particular object but it is available in recycle bin to restore.

 
data1 =[Select id from Object1__c];
delete data1;


If we execute above code the data will be removed from Object data base, but will be availble in recycle bin.

If  we want to remove data from recycle bin below code will works.

data1 =[Select id from Object1__c];
delete data1;

DataBase.emptyRecycleBin(oldDL); 



Regards,
Naveen.
http://www.autorabit.com/

Monday, January 26, 2015

How to convert Salesforce WSDL to JAR files

Salesforce provides different APIs like Enterprise,Metadata,Partner or our own  Custom Apex WSDL etc.
To convert WSDL to JAR files salesforce provides an API called WSC(Web service connector).
The below is the command to convert WSDL to JAR file.

You can download wsc.jar and its dependencies from below path and make sure java is installed and classpath is set.

http://mvnrepository.com/artifact/com.force.api/force-wsc/29.0.0


java -classpath D:\Jars\force-wsc-32.1.0.jar;D:\Jars\ST4-4.0.8.jar;D:\Jars\appengine-api-1.0-sdk-1.9.10.jar;D:\Jars\antlr-runtime-3.5.2.jar com.sforce.ws.tools.wsdlc D:\Jars\metadata.wsdl D:\Jars\metadata.jar


Regards,
Naveen
http://www.autorabit.com

Creating complex Custom Dashboard/Chart in Salesforce

Salesforce visualforce charting helps us to build custom or complex Charts.
Use Visualforce charting to assemble a variety of chart components into a complex chart that represents multiple sets of related data. The end result can be quite sophisticated and attention getting.
Below is a sample Visualforce and Apex code to build a custom Chart in salesforce.

public class ChartController {
    // Return a list of data points for a chart
    public List<Data> getData() {
        return ChartController.getChartData();
    }
    
    // Make the chart data available via JavaScript remoting
    @RemoteAction
    public static List<Data> getRemoteData() {
        return ChartController.getChartData();
    }

    // The actual chart data; needs to be static to be
    // called by a @RemoteAction method
    public static List<Data> getChartData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Operation1', 80, 90, 55));
        data.add(new Data('Operation2', 65, 15, 65));
        data.add(new Data('Operation3', 50, 32, 75));
        data.add(new Data('Operation4', 72, 28, 85));
        data.add(new Data('Operation5', 65, 51, 95));
        data.add(new Data('Operation6', 48, 45, 99));
        return data;
    }
    
    // Wrapper class
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}



<apex:page controller="ChartController">
<apex:chart data="{!data}" height="400" width="500">
    <apex:legend position="left"/>
    <apex:axis type="Numeric" position="left" title="Success Records" grid="true"
        gridFill="true" fields="data1,data2,data3" dashSize="2">
        <apex:chartLabel />
    </apex:axis>
    <apex:axis type="Category" position="bottom" fields="name" title="Operation Name">
        <apex:chartLabel rotate="315"/>
    </apex:axis>
    <apex:barSeries orientation="vertical" axis="left" stacked="true" colorSet="#AA9BFC,#0FD,#F10"
        xField="name" yField="data1,data2,data3" highlightColor="#AD9CFC"  title="Update,Delete,Insert"/>
</apex:chart>
</apex:page>

Regards,
Naveen
http://www.autorabit.com

Tuesday, January 20, 2015

How to Create a field in Salesforce Using java

Hi ,

To add custom field to a custom object use below code. You must use Partner and metadata API's to create the custm field.

//To following code creates a metadata connection
import com.sforce.soap.metadata.*;
import com.sforce.soap.partner.LoginResult;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
/**
* Login utility.
*/
public class MetadataLoginUtil {
public static MetadataConnection login() throws ConnectionException {
final String USERNAME = "username@gmail.com";
// This is only a sample. Hard coding passwords in source files is a bad practice.
final String PASSWORD = "Password+SecurityToken";
final String URL = "https://login.salesforce.com/services/Soap/u/31.0";

//Quick Start Step 3: Walk through the Java Sample Code
final LoginResult loginResult = loginToSalesforce(USERNAME, PASSWORD, URL);
//System.out.println(loginResult);
return createMetadataConnection(loginResult);
}
private static MetadataConnection createMetadataConnection(
final LoginResult loginResult) throws ConnectionException {
final ConnectorConfig config = new ConnectorConfig();
config.setServiceEndpoint(loginResult.getMetadataServerUrl());
config.setSessionId(loginResult.getSessionId());
return new MetadataConnection(config);
}
private static LoginResult loginToSalesforce(
final String username,
final String password,
final String loginUrl) throws ConnectionException {
final ConnectorConfig config = new ConnectorConfig();
config.setAuthEndpoint(loginUrl);
config.setServiceEndpoint(loginUrl);
config.setManualLogin(true);
return (new PartnerConnection(config)).login(username, password);
}

}

//The following code creates a custom field using metadata conncetion and createMetadata() method.

import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool.ManagedBlocker;
import com.sforce.async.Error;
import com.sforce.soap.metadata.*;
import com.sforce.soap.metadata.FieldType;
import com.sforce.soap.metadata.Package;
import com.sforce.soap.metadata.SaveResult;
import com.sforce.soap.partner.*;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;
import com.sforce.ws.wsdl.SfdcApiType;
/**
* Login utility.
*/
public class PartnerLoginUtil {

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
try {
PartnerLoginUtil p= new PartnerLoginUtil( );
p.createCustomExtField("CustomObjectName");

} catch (ConnectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private void createCustomExtField(String name) {
// TODO Auto-generated method stub
CustomField cs = new CustomField();
cs.setFullName(name+".CustExtField__c");
cs.setLabel("CustExtField");
cs.setType(FieldType.Number);
cs.setExternalId(true);
cs.setPrecision(10);
cs.setScale(8);
try {
MetadataConnection metadataConnection = MetadataLoginUtil.login();
SaveResult[] results = metadataConnection
.updateMetadata(new Metadata[] {cs});

for (SaveResult r : results) {
if (r.isSuccess()) {
System.out.println("Created component: " + r.getFullName());
} else {
System.out
.println("Errors were encountered while creating "
+ r.getFullName());
for (com.sforce.soap.metadata.Error e : r.getErrors()) {
System.out.println("Error message: " + e.getMessage());
System.out.println("Status code: " + e.getStatusCode());
}
}
}
} catch (ConnectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}


Regards,
Naveen
http://www.autorabit.com