Tuesday, June 26, 2012

Tree View in a Visualforce Page... Accounts/Contacts/Cases in a single view

Watch a DEMO here.....

Screenshot:
Step 1:

Download the Jquery Plugin from here. Upload this Zip file into Static Resources with the name "Jtreeview"

Step 2:

Create the Apex Class "treenodes" and paste the below code.



  public class treenodes {    /* Wrapper class to contain the nodes and their children */  public class cNodes  {     public List<Contact> parent {get; set;}   Public Account gparent {get;set;}     public cNodes(Account  gp, List<Contact> p)   {       parent = p;       gparent = gp;   }  }  /* end of Wrapper class */     Public List<cNodes> hierarchy;    Public List<cNodes> getmainnodes()  {      hierarchy = new List<cNodes>();      List<Account> tempparent = [Select Id,Name from Account];      for (Integer i =0; i< tempparent.size() ; i++)      {          List<Contact> tempchildren = [Select Id,FirstName,LastName,(Select Id,CaseNumber,Subject from Cases) from Contact where AccountId = :tempparent[i].Id];          hierarchy.add(new cNodes(tempparent[i],tempchildren));       }         return hierarchy;  }     }


Step 3:

Create a Visualforce Page "TreeViewDemo" and paste the below code.



  <apex:page sidebar="false" controller="treenodes" showheader="false">  <!-- Include the Jquery Script files -->      <link rel="stylesheet" href="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.css')}"/>      <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.js')}" type="text/javascript"></script>      <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.cookie.js')}" type="text/javascript"></script>      <script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.js')}" type="text/javascript"></script>  <!-- End of Javascript files -->  <script type="text/javascript">          $(function() {              $("#tree").treeview({                  collapsed: false,                  animated: "medium",                  control:"#sidetreecontrol",                  persist: "location"              });          })  </script>  <br/> <br/> <br/>  <!-- Tree -->  <div class="treeheader" style="height:0px;">&nbsp;</div>  <div id="sidetreecontrol"><a href="?#"><font style="color:blue;">Collapse All</font></a> | <a href="?#"><font style="color:blue;">Expand All</font></a></div>  <ul id="tree">      <apex:repeat value="{!mainnodes}" var="parent">          <li><strong><apex:outputtext style="color:blue;" escape="false" value="{!parent.gparent.Name}"/></strong>               <ul>                   <apex:repeat value="{!parent.parent}" var="child">                      <li><span class="formattextcon"><apex:outputtext style="color:green;" escape="false" value="{!child.LastName}"/></span>                          <ul>                              <apex:repeat value="{!child.Cases}" var="gchildren">                                 <li> <span class="formattextcon"> <apex:outputtext escape="false" style="color:red;" value="{!gchildren.CaseNumber}"/> <b>||</b> &nbsp;<apex:outputtext escape="false" value="{!gchildren.Subject}"/> </span> </li>                              </apex:repeat>                          </ul>                             </li>                   </apex:repeat>                 </ul>            </li>      </apex:repeat>  </ul>  <!-- End of Tree -->         </apex:page>




Note: You may modify the hierarchy by replacing the Objects and the queries with your required ones. Also, you may have to optimize the apex class to handle more than 100 queries as this demo has a SOQL query within a FOR loop (An Example of bad programming practice).

.Net Web Service with Salesforce.com

Part 1 – Update Salesforce Recod using .Net Application
  • Step 1:
    • Create a field TestAccount [Text] in Account.
    • Step 2:
      • Create a .Net application that extracts salesforce's objects records (In this case, Accounts) and update TestAccount field with its Parent Account field.
      • You have to add Web Reference of your enterprise WSDL in this .Net Application.
      • To generate WSDL:  Setup | Develop | API| Generate Enterprise WSDL | Generate.
      • Right Click on it and Save Enterprise WSDL and Import into you .net Application using Webrefernce.
        • If you don't know how to add Webrefernce. (Click here)
  • Now Refer to "Walk Through the Sample Code" in Web Services API Developer's Guide :http://www.salesforce.com/us/developer/docs/api/apex_api.pdf
  • This Walkthorugh Application is a very simple app you can easily query data from the querySample() method. So Query that record by passing a hardcoded record Id e.g. :
    • QueryResult qr = null;
    • string recordId = "01pP00000004kUC"; //SampleID
    • qr = binding.query("SELECT Id, Name, ParentId FROM Account where Id = '" + recordId + "'");
  • In The 2nd part of this App we will update this recordId which will get Id from Outbound Message.
  • To update record we need to use SaveResult and sObject to Update. Here is a sample code to update it. This will Update TestAccount field and populate the Value of ParentId into it.
    • for (int i = 0; i < qr.records.Length; i++)
    • {
    •    Account acc = (Account)qr.records[i];
    •    acc.TestAccount__c = acc.ParentId;
    •    SaveResult[] saveResults = binding.update(new sObject[] { acc }); // updating results in salesforce.
    • }
  • Now Run and Test it whether it is Updating that record or not.
  • How to Import WSDL into .net APP
    • In Solution Explorer Right Click on Application name and click on Add Service Reference.
    • Now Click Advanced a new window will pop up and Now Click on Add Web Reference.
    • Again a window will pop up here you need to specify the path of you Enterprise WSDL e.g. : C:\Users\Administrator\Desktop\enterprise.wsdl
    • Now Click on Add reference and that's it your webrefernce is added into you App.
    • In order to use it you have to add a name space e.g. :  using ApplicationName.WebserviceName;
Part 2 – Outbound Message to invoke .Net Application
Step 3:
Create a Web Service that calls your .Net Application.
Add reference of your .Net application to the Web Service.
Sample Code:
Below is the code of web service file .asmx that implements class WebService in namespace testWebservice
<%@ WebService Language="C#" CodeBehind="~/App_Code/WebService.cs" %>
Below is the code of a Class Webservice
using System;  using System.Collections.Generic;  using System.Web;  using System.Web.Services;  using ConsoleApplication5;    namespace testWebservice  {      [WebService(Namespace = "http://theinsidecloud.org/")]      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]      public class WebService : System.Web.Services.WebService      {          public WebService()          {              //Uncomment the following line if using designed components              //InitializeComponent();          }          [WebMethod]          public void HelloWorld(String id)          {              Program app = new Program();              app.Accountid = id;              app.run();          }      }  }

Step 4:
  • Now host this Web Service.
Step 5:
  • Create a workflow to send an outbound message that will send Account Id. Specify end point URL where you have hosted your web service.
  • Select a field to be sent as a parameter for the Web Service.
Step 6: 
  • After saving the out bound message you will have its detail page. Click on Click for WSDL.
  • Add web reference of this WSDL in your Web Service.
  • After Adding WSDL to your WebService , Host the updated application to the Web.
So whenever your Workflow fires, it will hit the hosted Web Service with some parameter (in this case Id). Web Service will call .Net application and update a particular record that matches with the parameter.

Encrypting Salesforce Password


Thursday, June 21, 2012

Search for Duplicates Validation Rule

A common problem for Salesforce users is the accidental creation of duplicate records. Validation rules are often used to check the condition of a record before it is saved. Here is a validation rule we use to prevent the creation of a new record with the same name (unfortunately it only works on custom objects).

It uses the VLOOKUP salesforce formula function which is only available for validation rules (unfortunately). This validation rule has two parts:

1) It looks for a record of the same name
2) It makes sure that the record isn't the exact same record as opposed to just a duplicate. This will happen when a record is edited, the name already exists (as itself) and when saved will trigger the part 1 result.

Here is the rule. Simply replace the object name and field name (which can both be entered automatically when using the formula editor)


and(
    Name = VLOOKUP
       ($ObjectType.Service__c.Fields.Name , $ObjectType.Service__c.Fields.Name, Name ),

    not(
     Id=VLOOKUP
         ($ObjectType.Service__c.Fields.Id , $ObjectType.Service__c.Fields.Name, Name ))) 

Salesforce.com Roll-up Summary Fields

Perhaps you've run into a limitation with the Salesforce.com Rollup Summary field functionality. While this is an incredibly useful function, roll up summary fields can only be used in very specific architectures.  You must come up with some other way to replace the functionality of a roll up summary field when you don't have the prerequisite architecture or other needs of the system can't permit that architecture. I'll show you below how to get around the limitations.

You should use a rollup summary field when you have a set of child records to a parent record and you want to total some value from those child records.

Roll-up Summary Limitations

Here are a few of the limitations of a roll-up summary field (there are probably others):
- you must be in a master-detail relationship in order to use them
- the field being rolled up cannot be a formula field.
- you can only put 10 roll-up summary fields on an object

So what do you do when you can't comply with one of the above?

Write a trigger!

A trigger can conveniently overcome all of the limitations identified above. (with the one complicating factor being that you can only write a trigger in Enterprise/Platform/Unlimited editions of Salesforce.com)

To replace the rollup summary functionality, put the trigger on the child object and have it fire whenever a record of that object type is saved. When the trigger is executed, it should collect the value that is to be totaled from the originating record, then go up to the parent object (which now does not need to be in a master-detail relationship), and collect that same value from every other child record. Do the math, then place the result in a custom field on the parent record.

An Example

So for example, imagine a company that uses a Unit custom object (kind of like Products) against their Opportunities to list what clients are buying. They have a Vendor Order record (custom object) also where they order those units from their vendor. The Unit object is child to the Vendor Order object also. So the Unit is the child in a master detail relationship to the Opportunity but in a lookup relationship to the Vendor Order. Unit can't be in a master-detail relationship with Vendor Order because the Vendor Order record doesn't exist when the Units are added to the Opportunity. In master detail relationship, parents must exist before children.

If the unit record contains a Price to the customer, that can be conveniently totaled on the Opportunity using a roll-up summary field. The unit will also have a Vendor Price to record what it costs to buy the unit from the vendor. But a rollup summary field isn't available on the Vendor Order because it isn't in a Master-Detail relationship. So the Vendor Order total price isn't possible via rollup summary field.

By placing a trigger on the Unit object however, we can get our total. That trigger can execute each time the Unit record is saved, then take the Vendor Price from that Unit record, get the Vendor Price from every other Unit record associated with that Vendor Order, do the math, then save that value in the Vendor Order, Vendor Order Total Price field.


Get Help from Snapptraffic Consulting

Obviously, the challenge a typical salesforce.com customer faces is getting the trigger written. You'll need a development environment and someone who knows how to write in APEX. If you don't have those resources available to you. Feel free to contact us, we'd be glad to help. A trigger like the one noted about takes us about 3 hours to produce. (You can find our current rates on our website, noted below). Generally we can have it written within a day or two of your request.

Salesforce Portal Development

Do You Need A Portal for Your Salesforce.com System?

Salesforce.com comes out of the box pre-configured with Self-Service, Customer, and Partner Portals. Beyond that, Salesforce sells licenses for completely custom portals. Not only can Salesforce offer you portals for your customers and for your partners, but they also host websites on their system called "Salesforce.com Sites".

In addition to the portals, Salesforce Sites makes it possible for you to make information stored in your organization's instance of Salesforce.com publically visible on the internet. A common example is that of "Job Openings". A database in Salesforce.com of Job Openings for the company can be listed on the internet in a way that the general public can view them.

Authenticated Sites and Custom Portals

You may want to authenticate visitors to the site though. For example, if you want to permit someone to submit a resume against one of the listed Job Openings, you may want to authenticate them. This essentially becomes a "portal."

So while Salesforce.com offers portals that require no programming, but rather just "point & click" configuration, some applications don't fit that provided functionality. In the example "Job Openings Resume Submission System", it would probably be better suited to a custom portal built on a Salesforce.com Site.

Custom Websites Built on Salesforce.com Data

As more companies adopt Salesforce.com for their main business data management and CRM platform, they are finding that they want to build websites and portals based on the data in their system. Deciding on the correct approach can be daunting. There are customer portals, partner portals, self-service portals, publically visible Salesforce.com sites, and an entire range of custom portal solutions.

Learning about Salesforce Licensing and Salesforce.com Portal Options

You may know that you need to give your customers or partners access to your Salesforce data in some way, but unsure of the best portal option, or the best Salesforce.com licensing option. There is a BIG difference between the pricing models offered by Salesforce.com, some licenses are as much as $35/mo/user, others as inexpensive as a few pennies - some free. Picking the correct licensing option is critical.

In general, there are 4 general categories of Salesforce.com Portals:


  1. Partner Portals
  2. Customer Portals
  3. Authenticated Sites
  4. Salesforce.com Sites
 In each of these you are giving access to your salesforce.com data to people who are not users of your salesforce system. 


Salesforce Partner Portal: the idea behind a partner portal is that your partners who resell your products & services can login to a system tied to your salesforce.com organization where they can record their leads, keep track of their accounts and contacts, and advance the opportunities that they are pursuing on behalf of your company. It gives them a place to share their progress with you. Main functional distinction: it gives the users access to multiple accounts and contacts - its access extends ACROSS your organization - fully controlled of course by sharing rules and the role hierarchy.

The Salesforce.com Partner Portal is a SYSTEM within Salesforce. Meaning, it already exists, you simply buy licenses for it and configure it. You can do custom Salesforce.com development with APEX and visualforce pages to add functionality to it, but that is not required. You can simply configure it the way you want it and give your partners licenses. 


Licenses for Partner Portals cost about $35/user/mo - although you can probably work a deal with Salesforce depending on the number you are purchasing.


Salesforce Customer Portal: the idea here is that your customers can login to a system to see information that relates to them as a customer of your organization. A salesforce customer portal gives a user access to THEIR account data, so in distinction to the partner portal, it is not CROSS organizational. And like the Salesforce Partner Portal, it is a system in Salesforce that can simply be configured and deployed.

These licenses cost under $10/user/mo depending on the number and plan.


Although salesforce provides a customer portal system, you can override this system and deploy an entirely custom salesforce.com portal. We often use these licenses, but deploy a custom website instead. The customer portal license gives us the ability to authenticate and encrypt the session on the custom website (see note below about authentication and encryption).


Authenticated Sites: Salesforce provides this licensing option for the times when you will be displaying data from salesforce in an entirely custom way and only displaying information from accounts, contacts, and custom objects. Check with your account manager at Salesforce for the pricing. It can be confusing, there are many options.


Salesforce.com Sites: Salesforce offers a "guest-user" license that essentially makes it possible for a developer to produce a website displayed on a page hosted by salesforce that displays salesforce.com data to the general public. No licenses are needed - no additional expense except for the licenses you already purchase for your users.


A Note about Authentication and Encryption: to authenticate means to ensure that the correct person is viewing data within your system. Encryption means that the authenticated user is viewing that data securely - through an "encrypted" session in the browser, evidenced by the HTTPS in the address and usually a little padlock displayed somewhere in the browser. 


We can authenticate users on Salesforce.com Sites without buying a Salesforce License. You just store a username and password somewhere in salesforce and only present applicable information after those have been entered correctly. So you know you have the correct person viewing the system - BUT - it isn't encrypted this way - the information is being displayed in a non-secure session (HTTP, not HTTPS in the address bar). This is sufficient for many applications. 


However to encrypt a session, get the HTTPS and padlock displayed - you must have a salesforce.com license of some kind. You can't get into a secure session without a salesforce license. You can authenticate with no license, but you can't encrypt with no license.


Therefore - a Salesforce.com Sites page can be authenticated if it is needed and the developer writes the code to verify the user's identity. It will not be encrypted. But you can display any data from your salesforce.com system out to the general public using Sites. If you want to encrypt that data, then you'll need to get an Authenticated Sites or Customer Portal license for the people who will be using that system. 


Note: all the licensing and portal options above are available only in the Enterprise & Unlimited Editions of Salesforce.com. 


Need Help?


If you want help determining the right license type for your application or need help building your custom website or setting up your portal, feel free to contact us. Snapptraffic has a great team of developers and lots of expertise when it comes to building and deploying custom Salesforce.com sites and portals. You can reach us through our website at:

Differences between Files, Salesforce CRM Content, Salesforce Knowledge, Documents, and Attachments

Differences between Files, Salesforce CRM Content, Salesforce Knowledge, Documents, and Attachments

To send Email from Apex using email Template

To use an Email Template from Apex Class in order to send an email:
In order to send an email from apex class, you can use any of the below messaging objects.
Single Email Messaging :
Instantiates the object to send single email message.
Ex: To send single email to a selected Contact.
public void SendEmail()
{
contact con=[Select id from contact limit 1];
EmailTemplate et=[Select id from EmailTemplate where name=:'EmailTemplatename'];
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setTargetObjectId(con.Id);
mail.setSenderDisplayName('Charan Tej');
mail.setTemplateId(et.id);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
For other object methods of Single Email Messaging, Click Here
Note: Do remember that we can send only 10 emails in method invocation of Apex class using SingleEmailMessage.
Mass Email Messaging:

Instantiates the object to send mass email message.
Ex: To send mass email to a Contacts.

public void SendEmail()
{
List<contact> lstcon=[Select id from contact limit 200];
List<Id> lstids= new List<Id>();
for(Contact c:lstcon){
lstids.add(c.id);
}
EmailTemplate et=[Select id from EmailTemplate where name=:'EmailTemplatename'];
Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
mail.setTargetObjectIds(lstIds);
mail.setSenderDisplayName('Charan Tej');
mail.setTemplateId(et.id);
Messaging.sendEmail(new Messaging.MassEmailMessage[] { mail });
}

For other object methods of Mass Email Messaging, Click Here

Displaying Salesforce data in Google Image Charts

Displaying Salesforce data in Google Image Charts.
We have a requirement to display the accounts
i) having cases more than 5 in red color.
ii) having cases equal to 5 in yellow color.
iii) having cases less than 5 in green color.
Client needs two buttons monthly and weekly.
If client clicks on Monthly, it should show the month report and when clicked on Weekly it should show the past week report.
For this, we need to develop a VF page with a custom controller in Salesforce.
Here is the Apex class where we build URL. to which we need to hit the google.
public class googlechartcls{        public googlechartcls(ApexPages.StandardController controller) {      dt=System.now().addDays(-7);      System.debug('-----dt is+'+dt);      lstcase =[Select account.name,casenumber, origin, reason,status,status__c,subject,LastRespondedDateTime__c,Age__c  from Case WHERE CreatedDate >=: dt and status != 'Closed' and account.name!=null];      List<AggregateResult> aggres = new List<AggregateResult>();      aggres=[Select account.name,count(id) from Case WHERE CreatedDate = THIS_Week and status != 'Closed' and account.name!=null  group by account.name];      chart(aggres);      }        public List<case> getLstcases() {          return lstcase;      }        public List<case> lstcase;      public datetime dt{get; set;}      public void tdays() {          dt=System.now().addDays(-30);          aggres=[Select account.name,count(id) from Case WHERE CreatedDate >=: dt and status != 'Closed' and account.name!=null  group by account.name];          lstcase =[Select account.name,casenumber,origin, reason,status,status__c,subject,LastRespondedDateTime__c,Age__c from Case WHERE CreatedDate >=: dt and status != 'Closed' and account.name!=null];          chart(aggres);      }        public void sdays() {      dt=System.now().addDays(-7);      aggres=[Select account.name,count(id) from Case WHERE CreatedDate = THIS_WEEK and status != 'Closed' and account.name!=null  group by account.name];      lstcase =[Select account.name,casenumber,origin, reason,status,status__c,subject,LastRespondedDateTime__c,Age__c from Case WHERE CreatedDate = THIS_WEEK and status != 'Closed' and account.name!=null];      chart(aggres);      }    List<AggregateResult> aggres;    public googlechartCls(){  }    public void chart(List<AggregateResult> aggres){      imgurl='';      System.debug(aggres);      imgurl='http://chart.apis.google.com/chart?chxt=x,y&chbs=a&chbh=a&chds=0,15&chs=450x250&chdlp=b|l&cht=bvg&chxs=0,68228B,12|1,68228B&chdls=330033,12&chtt=Account+Status+Report';      string chco='';      string chd='';      String chxr='';      String chxl='0:|';      String chm='';      String chdl='';      String chxs='';      Integer s;      for (integer i=0; i<aggres.size();i++){          s = Integer.valueOf(aggres[i].get('expr0'));          System.debug('----------->'+aggres);          if(i<aggres.size()-1){                 if( s > 5){                      chco+= 'ED1B0E|';                      chd += aggres[i].get('expr0')+',';                      chxl += string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10|';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name')+'|';                    }                  else if(s == 5){                      chco += 'FDD017|';                      chd += aggres[i].get('expr0')+',';                      chxl +=string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10|';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name')+'|';                    }                  else{                      chco+= '41A317|';                      chd += aggres[i].get('expr0')+',';                      chxl +=string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10|';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name')+'|';                  }          }          else{          System.debug('Else Part');                  if( s > 5){                      chco+= 'ED1B0E';                      chd += aggres[i].get('expr0');                      chxl +=string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name');                    }                  else if(s == 5){                      chco += 'FDD017';                      chd += aggres[i].get('expr0');                      chxl +=string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name');                    }                  else{                      chco+= '41A317';                      chd+= aggres[i].get('expr0');                      chxl +=string.valueof(i+1)+'|';                      chm +='t'+s+',0000FF,0,'+i+',10';                      chdl+=string.valueof(i+1)+'='+aggres[i].get('Name');                  }          }      }        imgUrl+='&chco='+chco+'&chd=t:'+chd+'&chxl='+chxl+'|1:|0|5|15|20&chm='+chm+'&chdl='+chdl;    }    public string imgurl{get; set;}    }
**************************************************************************************************
Visual Force page:
<apex:page standardController="case" extensions="googlechartcls" showHeader="false" sidebar="false">  <script>      function redirect(){          window.open('/apex/googlechartingreport','_blank');      }  </script>  <apex:form >  <div align="center">      <br/>      <apex:image value="{!imgurl}" onclick="redirect()"/>      <br/>      <br/>      <br/>      <apex:CommandButton value="7 Days" action="{!sdays}"/> &nbsp;&nbsp;&nbsp;&nbsp;      <apex:CommandButton value="30 Days" action="{!tdays}"/>      </div>      <br/>      <br/>      <apex:pageblock >          <div style="overflow:auto; height:290px">          <apex:pageBlockTable value="{!lstcases}" var="c">                    <apex:column headerValue="Case Number">                  <apex:outputlink value="/{!c.id}">{!c.casenumber}</apex:outputlink>                  </apex:column>                    <apex:column headerValue="Account Name" >                  <apex:outputlink value="/{!c.accountid}">{!c.account.name}</apex:outputlink>                  </apex:column>                    <apex:column value="{!c.origin}"/>                  <apex:column value="{!c.reason}"/>                  <apex:column value="{!c.Status}"/>          </apex:pageBlockTable>          </div>      </apex:pageblock>  </apex:form>  </apex:page>


Here is the output:


I think this will help to give start with google charts .

Apex Callout

In short how to do an apex callout from Class..
Apex class:
*******************************************
global class with sharing ApexCallout{
public void callout()
{
//Construct a HTTP Request
HttpRequest req = new HttpRequest() ;
string strUrl='**********Place your Remote Site Address here**********";
//Before making this callout, you need to add Remote site address in the Remote Site Settings of your Organization..
//Setting Endpoint URL to HTTP request
req.setEndpoint(strUrl);
//Set the request type
req.setMethod('GET');
//HTTP object creation
Http http = new Http();
//Sending the Req throgh HTTPResponse object.
HTTPResponse res = http.send(req);
//System.debug(res.getBody());
//System.debug(res.getStatus());
}
}
If you need to pass some parameters in the method, you can do it..
by changing the method to method with arguments.
You can call this method from trigger also..

MVC architecture in Salesforce

In Cloud Computing, generally Database is provided by the Service providers only..
Tables in SQL are Objects in Salesforce.
We develop Visual Force pages in Salesforce and we will control the pages with the help of controllers coded in Apex.
Apex is an in-house technology as well as language, which is a subset of Java.
It inherits all the OOPS concepts of Java.
So, we can conclude that
Model : Objects
View : Visual Force Pages
Controller : Apex classes

Difference between Portals in Salesforce

There are 3 types of  Salesforce.com Portals.
  •  Customer Portal
  •  Partner Portal
  • Self  Service Portal
The feature differences are that Partner Portal exposes the Leads and Opportunity objects whereas the Customer Portal does not.
Customer Portal is to support for your customers.
Partner Portal is to support your Partners. Partner users are Salesforce users with limited capabilities. They are associated with a particular partner account, have limited access to your organization's data, and log in via a partner portal.
But when compared, Partner portal is costlier than Customer Portal.
Self-Service provides an online support channel for your customers – allowing them to resolve their inquiries without contacting a customer service representative.
A Salesforce.com Customer Portal is similar to a Self-Service portal in that it provides an online support channel for your customers—allowing them to resolve their inquiries without contacting a customer service representative.
However, a Customer Portal provides significantly richer functionality than a Self-Service portal. This is because a Customer Portal has functionality similar to Salesforce.com. With a Customer Portal, you can customize and deliver a visually stunning user interface to your customers, and use the following Salesforce.comfeatures to help you and your customers succeed:

Friday, June 1, 2012

GROUP BY - Count Method in Apex Controller

Scenario:
Need to do Totals of Stages in Opportunity for the entire org.

Thought Process:
  1. What are the columns involved? Answer: StageName and Count or Total
  2. What methods will we utilize to achieve these results? Answer: Group By SOQL Statement with Count.
  3. What UI to built this neat logic? Answer: Apex Controller and VisualForce Page
  4. Need to achieve this type of reporting for the user:

    Solution:
    1. Use Eclipse IDE or SOQL Explorer to create your SOQL Statement.
    2. SELECT StageName, Count(Name) ce 
      FROM Opportunity GROUP BY StageName
    3. Second create  Apex Controller name what you like I named it TTL_Lesson, with your logic
    public class TTL_Lesson{
    //Define your variables
    public class OppStageHolder {
        public String OPP {get; set;}
        public Integer TTL_Opp {get; set;}
    //Empty Array    
    public OppStageHolder (){}
    }
    //Results will be placed within this List
    public List queryResults{ get; set; }
    
    //Your Page
    public PageReference TTL() {
    
    AggregateResult[] groupedResults = [SELECT StageName, 
         Count(Name) ce FROM Opportunity 
         GROUP BY StageName];  
    System.Debug('zzavg ' + groupedResults.size());
    //Define your List
    queryResults = new List();
    
    for (AggregateResult ard : groupedResults)  {    
        OppStageHolder myObject = new OppStageHolder();    
        myObject.OPP = String.valueOf(ard.get('StageName'));    
        myObject.TTL_Opp = (Integer) ard.get('ce');         
        queryResults.add(myObject);    
    }
    return Page.TTL;
    }

    }

    Now create your VF Page to call this and display it whenever the user clicks on this page:

    <apex:page controller="TTL_Lesson" action="{!TTL}" showHeader="false" sidebar="false">
        <apex:dataTable value="{!queryResults}" var="a" id="theTable" border="2" cellpadding="1" cellspacing="1" bgcolor="#A9D0F5" >
                    <apex:column >
                            <apex:facet name="header">Stage</apex:facet>
                            <apex:outputText value="{!a.OPP}"/>
                    </apex:column>                
                    <apex:column >
                            <apex:facet name="header">&nbsp;&nbsp;&nbsp;Count</apex:facet>
                            <apex:outputText value="{!a.TTL_Opp}"/>
                    </apex:column>
        </apex:dataTable> 
    </apex:page> 

    End result is the image on top

    How to use rowClasses in a dataTable or PageBlockTable in VisualForce

    Scenario:
     To have a table that would shade each alternative row.

    Solution:
    In your css file or even in the visualforce page place in the following:
    1. In CSS:
      1. .odd {
        background-color: #FCF7F7;
        }
        .even {
        background-color: #E3DCDB;
        }
    2. Inside the VF Page:
    So the Apex Visualforce page would look like this:
                    <apex:page standardcontroller="Contact">
                    <apex:form id="reportform"> <!-- Start of ReportForm-->
                    <apex:dataTable value="{!queryResult}" var="r" id="ttable" border="0" rowClasses="even,odd">
                     <!--yourcode here-->
                     </apex:dataTable>
                     </apex:form>
                     </apex:page>

    Now you have each other row shaded gray/white.

    How to use apex variable for total records in Visualforce

    Scenario:
      I came across a issue where visualforce does not allow one to Count or Sum records in a page.
    One solution would be to add more code to the controller to do a count of the records. Which is ok.
    A simple solution is to use the apex variable function in Visualforce.

    Solution: 
    1. Lets do it off Contacts
    2. In your Apex Controller : Create a SOQL query as is:
    public class countcontroller{
                public List<Contact> queryResult {get;private set;}
                public String qryString {get;set;}
                public PageReference query(){
                qryString =  'SELECT Name, Email, Phone from Contact';
                queryResult = Database.query(qryString);
                 return null;
           } 
    }  

    Pretty Simple and Straight Forward.
    Now for the VF Page and Magic:
    You will see I use the apex variable function to do a couple of things:
    
    
    create a variable run the query inside that variable counting all the records by 1 within a repeat tag calling the variable with the total Kind of like a for Loop but in Visualforce instead of controller. 
    
    
    <apex:page standardcontroller="Contact" extensions="countcontroller">
    <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0">
    <tr height="5">
        <td width="35%" class="outsideround_head" align="right">
            Total Contacts Returned:&nbsp;
        </td>
        <td width="8%" class="outside_round_head_value">
            <apex:variable var="call" value="{!0}" />
            <apex:repeat var="countitall" value="{!queryResult}" >
            <apex:variable var="call" value="{!call+1}"/>
            </apex:repeat>
            <apex:outputText value="{!call}"/>
        </td>
    </tr>
    </table>
    </apex:page>



    Output: Total Contacts Returned: 10

    Dynamic SOQL and SOSL


    Dynamic SOQL and SOSL:
    Dynamic SOQL/SOSL is nothing but the creation of a SOQL/ SOSL string at runtime with an Apex script. Dynamic SOQL enables you to create more flexible applications means developer can pass parameters dynamically. For example, you can create a search based on input from an end user, or update records with varying field names on different objects.
    Following are the steps to create a dynamic SOQL query at runtime, use the database query method, in one of the following ways:
    1. Return a single salesforce Object when the query returns a single record:
    Code: sObject S = Database.query (string_limit_1);
    Database query methode return number of sObjects.
    2. Return a list of sObjects when the query returns more than a single record of the object:
    Code: List ListofObject= Database.query(string);
    The database query method can be used wherever an inline SOQL query can be used, such as in regular assignment statements and for loops. Results are processed in much the same way as static SOQL queries are processed.
    Live example Dynamic SOQL Code:
    public String getSearchQuery(){
    companyName = inputFieldValue.Company+'%';
    cityName = '%'+inputFieldValue.City__c+'%';
    countryName = inputFieldValue.Address_Country__c;
    String Operator='='
    dist = 'Distributor';
    partnerStatus ='Active';
    locationType = 'Headquarters';
    String Query;
    if(countryName !=null && countryName !=''){
    Query='Select Id,Name,City__c,Country_list__c , State_LIst__c, Location_Type__c, BP_Link_Id__c from Account where Name like: distributorName and Partner_Type_New__c = :dist and Location_Type__c = :locationType and Status__c = :partnerStatus and Country_list__c= :countryName'
    }else{
    Query='Select Id,Name,City__c,Country_list__c , State_LIst__c, Location_Type__c, BP_Link_Id__c from Account where Name like: distributorName and Partner_Type_New__c = :dist and Location_Type__c = :locationType and Status__c = :partnerStatus'
    }
    return Query;
    }
    Description:
    Above code snippet method return Dynamic SOQL where we are passing some fields value at run time and also written some condition on if Country name is blank.