Salesforce Problems and Solutions
Workflow Rule Time Action
Problem:
Basic issue in Time based workflow is after criteria match
and action in Queue however after some time condition not equal than after user
will get ACTION triggered through workflow.
Description:
We have faced one issue related with time based workflow. For
example we have created Time based workflow and perform field update action
after 48 hours time. We have inserted record and which satisfied the workflow
rule condition. However after 2 hour of record insertion we have edited record
and now this workflow condition not satisfying the criteria. Therefore as
logically we don’t get any update after 48 hour time however time based
workflow not recalculating the criteria once gets in workflow QUEUE. So this is
the one of the limitation of time based workflow.
Solution:
We could solve time based workflow recalculation issue using
following steps:
•
We could update the record manually and save
it. It would be matched the latest criteria of workflow rule. However we have
like hundreds of records to update that it will create problem than Follow
below step 2.
•
We can code and update the records:
•
Write code on After Update Trigger on Object
•
Call class on above trigger and having @Future
method. (Issue we can’t update the record in Update trigger of itself object.)
•
In this future method write logic and update
the record.
We
can monitor the time based workflow in Monitor on Setup>Monitor>Time
Based Workflow Monitor.
Conclusion: Use
the above steps to solve the issue of Time Based Workflow.
1. Group by feature:
Salesforce Developers are the aware of with “GROUP BY” word
in SQL (Stucture Query Language)/SOQL (Salesforce Object Query Language). This
key word returns count of records which are selected.
We can put the count to
filter the records. My requirement is that if email is duplicates in contact’s
record then I need to exclude those records. Following is the code for that,
may it will help you too.
SOQL Code:
AggregateResult[] groupedRs =
[Select c.Email from Contact c where email =emailed@gmail.com’ group by Email
having count(Email)<2];
Description:
As above SOQL checks the email address and group by Email
field count is less than 2. So using the above SOQL we could checks how much
records are fetching in result set.
2. Salesforce Object initialization feature:
Up till now process to update
any sobject was to first query that object using its Ids, and than we used to
update that list.
Now if we are having Id of
sobject than we need not do any SOQL. For ex-
Code:
Opportunity
tempObj = new Opportunity (id = '0063000000Xh92q');
tempObj.name='Test
123';
Update
tempObj;
Description:
This above code will update
opportunity with Id=’ '0063000000Xh92q'’. Using this approach we can save many
SOQL queries.
Issue –
Client want the all new records of an object to submitted to an Approval
Process, however you do not want to rely on users to manually click ‘Submit for
Approval’ button after creating all records on Object.
Proposed Solution –
Got to on Object and Create and test the Approval Process for that go through
steps:
Setup > App Setup > Create >
Workflow & Approvals > Approval Processes >
Implement the simple Apex
Trigger (the following example is for the Account object).
For this we need to write
Code on Object and you will also need to create the test method to ensure code
coverage of our application. You can also add try / catch statements to ensure
that the exceptions are caught and handled properly.
Code of Trigger:
trigger accountApprovalSubmitAction on Account (after insert)
{
for (Account a : trigger.new)
{
Approval.ProcessSubmitRequest appAction = new
Approval.ProcessSubmitRequest();
appAction.setObjectId(a.id);
Approval.ProcessResult resultAction =
Approval.process(appAction);
}
}//
END OF TRIGGER
Other Example: We
can add some other conditions on after update or after insert.
if(Trigger.isAfter)
{
if
(Criteria condition)
{
system.debug('condition
is right');
Approval.ProcessSubmitRequest
request = new Approval.ProcessSubmitRequest();
req1.setComments('Submitting
request for approvalAction.');
req1.setObjectId(Trigger.old[0].Id);
List userId
= new List {userInfo.getUserId()};
request.setNextApproverIds(userId);
approval.ProcessResult
resultAction = Approval.process(request);
}
Conclusion: Using
above code user can insert the records without any operation of Submit for
Approval Button and use the Approval process methods according process/logic.
Issue on Formula field type conversion into
Text or other field types:
Sales force developers have
faced the issue related with Formula field type conversion into other Field
Type. Reason behind the issue is there are no configurations available to
convert the Formula field type conversion. We can say this is the one the
limitation of Salesforce.com and we can not change the type of formulae field.
To avoid the Formula Type conversion:
We can solve the issue like
there are 4 to 5 formulae fields are used in page layout which populated the
values but earlier requirement was populate the value according to the record
created by Partner users. Now the new requirement has changed and these fields
populate the value according to the either record created by Standard Users or
Partner user.
We could change the formula
according to the created by user however there is more than two level hierarchy
field. Means we cannot use the field of grandparent standard object fields. For
example we need to populate Opportunity’s>Account’s>Contact data. This is
not feasible to do populate so we could do this by using of Code.
OLD Formula is
Link ID = CreatedBy.Contact.Account.BP_Link_Id__c
Used the following steps to
overcome the above issue.
•
We need to create new text fields name like
formulae fields. Like Link_Id__c (Formulae) Link_Ids__c (Text), etc.
•
Than write the code in to Trigger and initiate
the value in to new fields. For this we do SOQL on Opportunity and Oppty
Partners to fetched the partner’s name and other values.
•
Trigger
Code:
Map mapOpptyPartner = new Map();
Opportunity opp= new Opportunity();
Map oppMap = new Map([Select Id, Name,
OwnerId, Owner.Name from Opportunity WHERE Id in: Trigger. newMap.Id]);
mapOpptyPartner.put(opp.Opportunity__c,
opp); //Add Oppty into Map
for(Sale__c saleObj: trigger.new){
if(saleObj.Opportunity_Name__c!=null){
salesObj. field11__c =
mapOppPartner.get(salesObj.Opportunity_Name__c).Role__c;
salesObj.field22__c =
mapOppPartner.get(salesObj.Opportunity_Name__c). r_name;
salesObj. field33__c =
mapOpptyPartner.get(salesObj.Opportunity_Name__c).name;
salesObj. field44__c =
mapOppPartner.get(salesObj.Opportunity_Name__c).City;
}}
Description:
Above
code fetched all records of the Oppty on Sales record and populated value in
these fields.
•
After instantiate the new Fields value use the
these fields into Formula field and populate the current correct value in to
the Formula fields. Like
Old formulae field the
value Link ID = CreatedBy.Contact.Account.BP_Link_Id__c
New Value on formulae Link
ID = Field11__c; etc
Conclusion:
Hence
above steps will solve the issue of Formula conversion in to other field type.
Issue:
DML Exception update failed FIELD_FILTER_VALIDATION_EXCEPTION
(You cannot violate field integrity rules) exception in Sales force.
Description:
I have faced the issue related with
FIELD_FILTER_VALIDATION_EXCEPTION on field. It will occur when I update the
records through specific Role/Profile.
Solution:
I have analyzed the issue of field filter validation
exception and get the solution. I have logged in with Global Role and update
the record in that I have change the value of Look up. This Look up field
created and configuration with filter criteria.
Before giving more
information I want to share some knowledge about Look up field configuration.
Look up Options:
Related To: User and Child
Relationship: SObject means it is related with user object and sObject. For
example we have created Look up field on standard/visual force page. When any
user clicks on this user it will show the list of User. However we need to show
specific users like System Admin only. So we can use look up Filter and write
the condition like Profile equal System Admin and save it.
Now any user click on Look up
them will get list of System Admin users only. Filter Type written some message
like Value does not exist or does not match filter criteria and enable this
filter.
So issue was when any profile
user update the record gets FIELD_FILTER_VALIDATION_EXCEPTION error. Because of
we have written filter for System Admin only. Means System Admin user only can
change the value of the lookup field. Update record we are changing the look up
fields value. Hence we get the error on filter validation.
Conclusion:
Look up filter criteria
display the specific users lists like System Admin and these users only change
the value of this lookup field other wise you will get
FIELD_FILTER_VALIDATION_EXCEPTION error.
Technical Requirement:
We have enhancement request
in our project and requirements are select number of records in View and change
the owner of the selected record.
Description:
As above technical requirement we want to create action from
Button and update the records.
Steps to solve above requirement:
1. Create Custom button or Link Named Assign and behavior
execute JavaScript.
Code on button:
{!REQUIRESCRIPT("/soap/ajax/14.0/connection.js")}
// declare the Js connection
{!REQUIRESCRIPT("/soap/ajax/14.0/apex.js")} //
declare the Js apex
{!REQUIRESCRIPT("/js/dojo/0.4.1/dojo.js")} //
declare the Js dojo
var ids='';
for(j=0;j< document.forms.length;j++)
{
for (i = 0;i
{
if((document.forms[j].elements[i].name=='ids') &&
document.forms[j].elements[i].checked)
{
ids+=document.forms[j].elements[i].value+',';
}
}
}// end of loop
if(ids==''){
alert('No requests selected !!!');
}else{
var returnFlag = '';
returnFlag = sforce.apex.execute("CheckClass" , "methode ", {ids:ids} );
alert('No requests selected !!!');
}else{
var returnFlag = '';
returnFlag = sforce.apex.execute("CheckClass" , "methode ", {ids:ids} );
if(returnFlag== ‘true’){
window.location = '/apex/PageName;
}else if(returnFlag== ‘false){
alert('You do not have permission to do this!')
}
--------------End of Code--------------------
2. Apex class:
global class CheckClass{
WebService static Boolean methode(){
Write the Logic
Return Boolean value
}
}
Technical Requirement:
Post of Salesforce Developer
or Tester getting requirement on Email masking. Email masking is nothing but
append the text to email in Sandbox.
Description:
Every Salesforce project’s
has the Sandbox environment which is the copy of Production. Which contains all
the records of objects like Account and there record like number of records
created in Production. These numbers of records are very high means thousands
and lacks records. So at the time of Sandbox activation it will copy all
records of data from production to Sandbox.
Sandbox is the test
environment where Salesforce developer could do something. However before
working in Sandbox we need to do mask the email fields of different object.
Email field contains the original email id of users and when Salesforce
developer work on this sandbox user will get email.
So we need to append the text
into email field of Account, Contact, Lead, Opportunity etc objects. Like email@company.com so
after email masking it will email@company.com.testfix.
Issue is number of records are too large and we can not do easily. For that we
need Data Loader and Salesforce Explorer tools.
Solution:
Following are steps to solve
the email masking task:
•
We have to fetch the records from sandbox where
emails id contains ‘.com’ text according to Object. We have created SOQL and
use this SOQL in data loader.
SOQL:
Select Id, Email FROM Lead where Email!=null and ( email like
'%a' or email like '%b' or email like '%c' or email like '%d' or email
like '%e' or email like '%f' or email like '%h' or email like '%i'
or email like '%j' or email like '%k' or email like '%l' or email like
'%m' or email like '%n' or email like '%o' or email like '%p' or email
like '%q' or email like '%r' or email like '%s' or email like '%t' or
email like '%u' or email like '%v' or email like '%w' or email like '%g'
or email like '%y' or email like '%z' )
Description of above SOQL:
We are fetching records Id
and Email from Lead object those email not end with ‘x’. Like email@company.com.testfix contains
‘x’ so it will return which is not masked with ‘.testfix’ and this above SOQL
run in to Data Loader.
After getting records in csv
format open the file.
•
Open the downloaded CSV file if file size is
more than lack than use FILE SPLITTER tool in to CVS file.
Open CSV file and add below
formula on second of email column. Like Column A is Email column then after B
column use C column.
Formula: =IF(B2 <>
C2,CONCATENATE(B2,".testfix")," ")
Copy this cell to last cell
means copy this value of cell and past to end to column.
After doing above step copy
the column of masked and Past Specials than select values.
Delete the Email column make
sure new column should be masked.
•
After above steps update this CSV file to Data
Loader with selection on LEAD object.
•
Open Salesforce Explorer and again fire above
SOQL.
Conclusion:
We could do email masking
using above steps.
Scenario: We
faced issue related with pick list which having some values like
‘abc’,’def’,’ghi’,’jkl’etc. And we have to add another value ‘xyz’ in this pick
list on certain condition.
For example we user select
open page (visual force page) with Account. Some other user open same page with
Opportunity button.
Proposed
Solution: We can solve using two ways;
1. Solution: We can do using controller as following code.
Controller:
public
List getPauseReason() {
List options = new
List();
options.add(new
SelectOption('','--None--'));
Schema.DescribeFieldResult
fieldResult = Sales_Support_Request__c.Pause_Reason__c.getDescribe();
List ple =
fieldResult.getPicklistValues();
for( Schema.PicklistEntry f :
ple)
{
options.add(new
SelectOption(f.getLabel(), f.getValue()));
}
if(Callfrom=='Account'){
options.add(new
SelectOption(‘xyz','xyd'));
}
return options;
}
------------- End of
controller-------------
Visual force page:
------------- End of
controller-------------
2. Solution: We can do using JavaScript code in Visual force page code
as given:
Step1. We
have created hidden field which contains where call from like ‘Account’ or
‘Opportunity’.
Step2: We
can call this field id in JavaScript code and write condition.
Conclusion:
Using this solution we can add value in pick list dynamically in
Salesforce.com.
Technical Issue –
User want all new records for an object to be submitted to an Approval Process,
however you do not want to the rely on users to manually click the ‘Submit for
Approval’ button after creating all the records.
Solution – Create and test
necessary Approval Process go through Setup / App Setup / Create / Workflow
& Approvals / Approval Processes, implement this simple Apex Trigger (the
following example is for the Account object). You will also need to create the
test method to ensure code coverage if your current production Apex Classes do
not provide adequate coverage also. You can also the add try / catch statements
to ensure that the exceptions are caught and handled properly.
Code:
trigger accountApprovalSubmit on Account (after insert)
{
// trigger on Account object
for (Account a : trigger.new) {
// to extract all new values on Accounts
Approval.ProcessSubmitRequest app = new
Approval.ProcessSubmitRequest();
app.setObjectId(a.id);
//Add the id of account
Approval.ProcessResult result = Approval.process(app);
//pass Approval request in to approval process result set.
}
}
Other Example:
if(Trigger.isAfter)
{
if(Criteria
matched)
{
system.debug('condition
passed');
Approval.ProcessSubmitRequest
req1 = new Approval.ProcessSubmitRequest();
req1.setComments('Submitting
request for approval.');
req1.setObjectId(Trigger.old[0].Id);
List<id>
userId = new List<Id> {userInfo.getUserId()};
req1.setNextApproverIds(userId);
approval.ProcessResult
result = Approval.process(req1);
}
Conclusion: Using
above code user can insert records without any operation of Submit for Approval
Button.
Issue – Displaying number of
characters remaining on 'Text Area Field' for custom field in the VF Page
similar to standard out of box functionality.
Solution – We need java script
to implement it.
We are passing id
of custom field in function size as first parameter and as second parameter we
are passing the size of custom field i.e. In above case we are passing the size
as 10000 so at the point of first character it displays message 9999 characters
remaining and so on...and it doesn't allow to enter more than 10000 characters,
as third parameter we are passing id of div where we need to display message.
Code:
<apex:page standardController="Case">
<script>
function size(fvalue, size, divid) {
var input_field =
document.getElementById(fvalue);
var msg_count =
document.getElementById(divid);
var char_reamining
= '0';
var char_entered =
input_field.value.length;
if(char_entered ==
0){
msg_count.innerHTML
= '';
msg_count.style.background
= '#F7F7F7';
}else {
if(char_entered
<= size){
char_reamining
= size - char_entered;
msg_count.innerHTML
= char_reamining+ ' remaining';
msg_count.style.background
= 'yellow';
}else{
msg_count.innerHTML
= char_reamining + ' remaining';
msg_count.style.background
= 'yellow';
input_field.value
= input_field.value.substring(0,size);
} } }
</script>
<!—Call the java Script above code in input field--
>
<apex:form >
<div id="msg"
class="ErrorMessageClass">
</div>
<apex:inputField
value="{!Case.Problem_Descriptions__c}" style="width:900px"
onkeyup="javascript:size('{!$Component.formId:pgBlockId:pbs1:tdescription}',10000,'msg');"
id="tdescription" />
</apex:form>
</apex:page>
Scenario: We
have requirement like Account owner change and automatically change Opportunity
owner also change with related object record should update.
Brief Introduction: We
have Account ‘Abc’ and on this account we have more than 20 Opportunities.
Every opportunity contains Sales record doesn’t matter how much. Owner of
Account is ‘John’ and updated to ‘Sam’ so every record must be updated on this
action.
Solution: We
have written code on Opportunity after update trigger and code snippet is given
below.
Trigger:
trigger OpportunityAfterUpdate on Opportunity (after update)
{
//Call the class which contain actual logic code
new UpdateopptyOwner().updateOwnerChanged();
}
Class:
public class SSRUpdatesalesArea{
public void updateOwnerChanged (){
List<String>
opptyIds=new List<String>();
Opportunity
objOppty,oldObjOppty;
List<Sales__c>
updateSales = new List< Sales__c>();
for(Integer
i=0;i<Trigger.new.size();i++){
objOppty=(Opportunity)Trigger.new[i];
oldObjOppty=(Opportunity)Trigger.old[i];
if(objOppty.OwnerId
!= oldObjOppty.OwnerId){
opptyIds.add(objOppty.Id);
}
}
Map<Id, Opportunity> opptyMap = new
Map<Id, Opportunity>([Select Id, Name, OwnerId, Owner.Name from
Opportunity WHERE Id in: opptyIds]);
for(Sales__c objSales
:[Select Id,Opportunity_Name__c, Request_Processor_Name__c,
Opportunity_Owner__c From Sales__c where Opportunity_Name__c in :opptyIds)]){
objSales.Request_Processor_Name__c=((Opportunity)Trigger.NewMap.get(objSales.Opportunity_Name__c)).ownerid;
objSales.Opportunity_Owner__c=((Opportunity)opptyMap.get(objSales.Opportunity_Name__c)).Owner.Name;
updateSales.add(objSales);
}
if(updateSales.size()>0){
database.update(updateSales,false);
}
}
}
Code Description: We
have written condition for owner changed and put in List of String. Written
SOQL and get opportunity Map from Oppty. We get the map of Oppty id’s than we
get Sales records to update and put in list.
After getting list of Sales records update this list.
Conclusion: We
can update number of thousands records on change of owner.
Technical Issue:
We are facing an error on
Custom page time of loading and error is “'Sale_Comments__r' is not a valid
child relationship name for entity Sale. This error comes only for Standard
Sales User profiles.
Description:
We have analyzed
the issue and error comes from related list of child object. We are populating
the related list in this page.
Code line of related list is : <apex:relatedList
list="Sales_Comments__r">.
Analysis:
Given below points for analysis of Parent Child
relation ship:
•
Parent object is Sales__c and child object is
Comment__c.
•
on Comment__c object Request_Id__c field is
Master-Detail and visible to all profiles and API name of child relation ship
is Sales_Comments__r.
•
Checks Standard Sales User profile FLS (Field
Level Security) of both object. Where Parent object giving R/C/E access and
Child object giving R/C access.
•
Checks active users of above profiles
Territory, User Group etc.
•
Login with user and run the visual force page
but it shows above error.
Visual force Code:
<apex:page
standardController="Salest__c">
<apex:relatedList
list="Sales_Comments__r" />
</apex:page>
Solution:
Login with Profiles active user and follow below steps:
•
Run the URL like https://intanceof.com/a1eQ0000000b0EcIAI?nooverride=1
Above URL contains instance of sales force and Id of record.
Where no override is used
to display the override related list.
•
Kindly check there is Comment related list
available or not.
•
If not available than Click on Customized Page
and add related list.
•
Run the /apex/output?id=record_Id and now you
will get output page.
Conclusion:
Use
the no override word in URL and checks there is related list available or not.
Requirement: Our
client has a requirement input field should be visible only when check box
enables otherwise this input field remains hidden.
Description: We
have visual force which contains lots of input field and check boxes. We had
requirement user should select one of checkbox and one of input field should be
visible.
Visual force page:
<apex:page controller="SalesController">
<script>
function checkfieldStatus(lbltag,txtboxtag)
{
var elelbl = document.getElementById(lbltag);
var eletxt =
document.getElementById(txtboxtag);
if(eletxt.style.display
== "block" && elelbl.style.display == "block")
{
eletxt.style.display
= "none";
elelbl.style.display
= "none"
}
else
{
eletxt.style.display
= "block";
elelbl.style.display
= "block";
}
}
</script>
<apex:form id="ipage">
<apex:pageBlock id="iPBlock" >
<apex:pageBlockSection title="Details">
<apex:inputCheckbox value="{!
}" id="" onclick=" checkfieldStatus
('j_id0:ipage:iPBlock:j_id163:j_id164:j_id165:j_id167:lblCustomerChannel','j_id0:ipage:iPBlock:j_id163:j_id164:j_id165:j_id167:CustomerChannel');"/>
<apex:pageBlockSectionitem
>
<apex:outputLabel
value="Customer Channel
" id="lblCustomerChannel"
style="display:none;font-weight:bold;"></apex:outputLabel>
<apex:outputPanel
style="display:none;" id="CustomerChannel" >
<apex:inputField
value="{!sales.Customer_Channel__c}" id="Customer_Channel"
/>
</apex:outputPanel>
</apex:pageBlockSectionitem>
As
above visual force page having JavaScript code which called on click of Check
box. We are passing the id of input field and label. We can see the JavaScript
id view source of page.
Issue: We have faced the issue
on sharing access whenever we click on recent item.
Technical Description:
We have two records and link is in visual
force page when we click the any record than record will populate fine. However
when we click on Recent Item of record it will show “Inefficient Privileges”
error message page.
Technical Solution:
We analyzed the record Standard Button
‘View’ overridden functionality and sharing access to this user. Finally we got
the issue in manual sharing access which is given by code. We are passing the
sharing to record on after update trigger however we are just inserting the
record that’s why it will show me “Inefficient Privileges” error message page.
So we have updated the record and
give the sharing through code.
Trigger of sharing on Sales object:
trigger setAccessSSR on Sales__c (after update) {
for(Integer
i=0;i<Trigger.new.size();i++){
request = Trigger.new[i];
try{
Sales__Share share
= new Sales__Share();
share.ParentId =
request.Id;
share.AccessLevel
= 'Edit';
share.UserOrGroupId=request.OwnerId;
insert share;
} catch(Exception
e){}
}//end of for loop
}// end
of trigger
Issue: We have the requirement
add validation on Opportunity where Stage is above 2 and Maintain ace attached
file ‘Yes’ than there should be Support Product in product list.
Description:
Requirement is if Opportunity having Stage is 2 and
above Maintain ace attachment ‘Yes’ than there should be Support Product in
related list of Product. Otherwise user get error message like first add the
Product in product list.
Solution:
As above requirement we had written validation
code in before update trigger. We have also tried to created validation rule
however we can not access product variable in validation rule because of much
level relationship.
We have faced another issue of Data clean up
because given below condition Oppty Stage and Maintain ace Attachment. So we
have added one more condition this validation would be only when Oppty created
date is 15-June-2011.
SOQL:
Select id,name from Opportunity where StageName!='01 -
Pre-Qualified' and Maintenance_Attach__c = 'Yes' and
Product_of_Interest__c!='Support Product' and
CreatedDate>=2011-06-15T00:00:00Z
Trigger Validation Code:
trigger OpporunityBeforeUpdate on Opportunity (before update)
{
for(Integer i=0;i<Trigger.new.size();i++){
Datetime myDate
=datetime.valueOf('2011-06-15 00:00:00');
if(Trigger.new[i].StageName!='01 -
Pre-Qualified' && Trigger.new[i].Maintenance_Attach__c == 'Yes'
&& Trigger.new[i].CreatedDate>=myDate)
{
List<Products__c>
products = [Select p.Monthly_Rate__c, p.Months__c, p.Opportunity__c,
p.Product_Family__c from Products__c p where Opportunity__c=:Trigger.new[0].Id
and Product_Family__c=:'Support Product'];
if(products.size() == 0){
trigger.new[i].addError(‘First
add Support Product in related list of Product.');
}
}
}
}
Issue: We have faced the issue of
field cannot see by Guest user in site form.
Technical Description:
We had site form where any user can see and fill
the form of Lead. We have created new field and add in this visual force page.
However Guest User not able to see or fill this field value.
Solution:
As sites come under got to
Develop>Sites>Lead Generation etc. where Default Web Address is the
visual force page and open in instance of sandbox/production with page
like http://company.Test.cs3.force.com/LeadGenerationPage
We
can see FLS of fields click on Public Access Setting and Click on Object and
Tab or view Object. Search the fields which is created and set enable the
checkbox of edit and create.
Developer is facing the issue of Authorization Required which
occurred due to FLS setting of fields. To solve this issue we have to edit the
fields and enable the edit/create/delete check boxes as per requirement or
based on profile/role.
Question: How do you use
composition and define tags in templates?
Answer:
Composition tag used to embed template in our
visual force page. Means we can create visual force having only form and page,
controller tag and just used insert tag in this page. Another (where this is
going to invoke the first template) visual force page defining this inserts tag
by using composition tag.
<apex: composition> tag
must contains at least one or more <apex: define> tag. We can write in
define output label, text fields etc. For example:
<apex:page
controller="CompositionController">
<apex:composition
template="{!myTemplate}">
<apex:define
name="First Name">
<apex:outputLabel
value="First Name"/>
<apex:inputText
id="fname" value="{!fname}"/>
</apex:define>
</apex:composition>
</apex:page>
Another page:
<apex:page
controller="CompositionController">
<apex:form >
<apex:insert
name="First Name"></apex:insert>
<br/><br/>
</apex:form>
</apex:page>
Above
example calls dynamic template name through getter define in controller.
Use Case
We have to read data through XML from third party API and
capture it in SFDC object as html formatted text.
Those texts are in html format with html tags
embedded with it and when it is displayed over the standard details page, they
display those HTML Tags.
Challenge comes in the case on how to remove
the Html tags and represent the whole content as plain text.
I felt a requirement of a generic class which
can be plugged to any SFDC Project, to any module where the business
requirement is to replace and convert the html content to plain text body.
This is best suited for Salesforce data content
shown as multi line texts.
Solution
Prepare a generic global class which can be plugged with any
module and which would take the HTML Embedded text content as string as input
parameter and return plain text.
Developed the following generic global class which can be
plugged together with any module for any project where they require removing
embedded tag and representing the content as simple text.
Global Class
/*
Problem Statement
During
creating a test class for a functionality found an unusual exception, here is
the case:
Create a lead whose owner should be a queue.
We started with this:
We started with this:
Group grp = new Group(Name = 'Queue', Type = 'Queue');
insert grp;
Lead lead = new Lead(LastName = 'testLastName', company = 'test', OwnerId = grp.Id);
insert lead;
But when we run the class we got the below exception:
System.DmlException: Insert failed. First exception on row 0; first error: INVALID_OPERATION, Queue not associated with this SObject type: []
Solution
There
is an object named "QueueSobject" that represents the mapping between
a queue Group and the sObject types associated with the queue, including custom
objects.
So whenever we want to have a group as an owner for a record, QueueSObject should be there to map that record with the Group:
Group grp = new Group(Name = 'Queue', Type = 'Queue');
insert grp;
QueueSobject mappingObject = new QueueSobject(QueueId = grp.Id, SobjectType = 'Lead');
System.runAs(new User(Id = UserInfo.getUserId()))
{insert mappingObject;}
Lead lead = new Lead(LastName = 'testLastName', company = 'test', OwnerId = grp.Id);
insert lead;
So whenever we want to have a group as an owner for a record, QueueSObject should be there to map that record with the Group:
Group grp = new Group(Name = 'Queue', Type = 'Queue');
insert grp;
QueueSobject mappingObject = new QueueSobject(QueueId = grp.Id, SobjectType = 'Lead');
System.runAs(new User(Id = UserInfo.getUserId()))
{insert mappingObject;}
Lead lead = new Lead(LastName = 'testLastName', company = 'test', OwnerId = grp.Id);
insert lead;
Problem Statement
The Force.com REST API provides you with a
powerful, convenient, and simple Web services API for interacting
with Force.com.
To use the REST API, it is essential to have valid Access
token/Session Id for each call but SFDC documentation does not explain how to
get access-token using username/password with the oAuth.
Following solution explains how to obtain the access token using
username/password and fetching the profile details along with User count.
Advantage with REST API is does not have SOQL governor limit
with the Aggregate query.
Solution
Step1: Create Remote Access Setting into SFDC
Step2: Create Token Request by using username/password
Javascripts
Var authinfo ;
Ext.Ajax.request({
method : 'POST',
async:false,
params : {
grant_type : 'password',
client_id:
'3MVG9FS3IyroMOh5h26EVC_527mrgPtXMObqfIKg2vd5xdClvP2_I0kIEOAIk3MgZ0Yxz6Giui9ozkKWuUiNQ',
// Consumer Key
client_secret: '4323324214295565712', // Consumer Secret
username : username, //UserName
password : password //Password (if your IP address is not white listed then
user Security token with the password)
},
success : function(response) {
console.log(response.responseText);
authInfo = response.responseText;
},
fail:function(response){
status=false;
}
});
This will return instance url and Session key that are used
into next REST API call.
1. instance_url
2. access_token
Step3: REST CALL to fetch Profiles name with user
count.
Ext.Ajax.request({
url: authinfo.instance_url +
'/services/data/v24.0/query?q=select+count(id)+userCount,+profile.name+from+user+group+by+profile.name'
,
method: 'GET',
async:false,
headers: { 'Content-Type' : 'application/json', 'Authorization' : 'OAuth '
authinfo.access_token },
success: function(response){
var text =
response.responseText;
},
fail: function(response){
Ext.Msg.alert('Error!','Some Error in Loading profiles.',Ext.emptyFn);
}
});
Problem Statement
Soap based webservice can be directly called using standard
javascript ajax call or HTTP call.
The difference is only the request body Webservice only
accept the SOAP format, so this call requires a valid SOAP envelop to make
call.
In the below solution, I have used SFDC ‘Reset Password’ call
which takes userid and reset user’s password.
Solution
SOAP Envelop
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:partner.soap.sforce.com">
<soapenv:Header>
<urn:EmailHeader>
<urn:triggerAutoResponseEmail>1</urn:triggerAutoResponseEmail>
<urn:triggerOtherEmail>1</urn:triggerOtherEmail>
<urn:triggerUserEmail>1</urn:triggerUserEmail> <!—This headers
has the value(0/1) to set if email notification should be generate for
the activity - - >
</urn:EmailHeader>
<urn:SessionHeader>
<urn:sessionId>SESSIONID</urn:sessionId> <!-- SessionId
-- >
</urn:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<urn:resetPassword>
<urn:userId>USERID</urn:userId> <!—User Id, for which the
password is to be set -- >
</urn:resetPassword>
</soapenv:Body>
</soapenv:Envelope>
Javascript Code Snippet
resetPassword:function(userId){
var currObject=this;
var responseArray=new Array();
var post_xml_request = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:partner.soap.sforce.com">'
+ '<soapenv:Header>'
+ '<urn:EmailHeader>'
+ '<urn:triggerAutoResponseEmail>1</urn:triggerAutoResponseEmail>'
+ '<urn:triggerOtherEmail>1</urn:triggerOtherEmail>'
+ '<urn:triggerUserEmail>1</urn:triggerUserEmail>'
+ '</urn:EmailHeader>'
+ '<urn:SessionHeader>'
+ '<urn:sessionId>' + MyApp.connection.AjaxCallInitiator.access_token +
'</urn:sessionId>'
+ '</urn:SessionHeader>'
+ '</soapenv:Header>'
+ '<soapenv:Body>'
+ '<urn:resetPassword>'
+ '<urn:userId>' + userId + '</urn:userId>'
+ '</urn:resetPassword>'
+ '</soapenv:Body>'
+ '</soapenv:Envelope>'
Ext.Ajax.request({
url: MyApp.connection.AjaxCallInitiator.instance_url + '/services/Soap/u/24.0
HTTP/1.1' ,
async: false,
headers: { 'Content-Type' : 'text/xml; charset="utf-8"','SOAPAction':
'/services/Soap/u/24.0'},
params: post_xml_request,
success: function(response){
responseArray.push(true);
responseArray.push(response.responseText);
},
fail: function(response){
responseArray.push(false);
responseArray.push(response.responseText);
}
});
return responseArray;
}
Note:
Have used EXT-Js for the javascript call to avoid Cross browser support
Requirement: Need
to populate the currency field value only in USD format.
Technical:
We have requirement Currency field should populate the
USD Dollar value only. When user create/update the record currency field take
the value from users Currency like user from Germany and users Currency is EURO
then user can see two values in Currency field of record like USD 5,645,646.00
(EUR 4,544,745.03) or EUR 4,544,745.03 (USD 5,645,646.00).
Solution:
As above Currency Conversion issue Salesforce has
provides the live value of Currency however limitation is Currency field of
record will populate both the values.
So we have overcome this issue from output visualforce
page. Means we have done JavaScript code on page load and at the time of
loading we convert the USD 5,645,646.00 (EUR 4,544,745.03) in to 5,645,646.00.
Below code explain the Currency in USD only and set to field
in visualforce page.
JavaScript code in VF page:
var
QuoteValue= USD 5,645,646.00 (EUR 4,544,745.03);
if(QuoteValue
!= null || QuoteValue > -1){
var a =
(QuoteValue.indexOf("USD"))+3;
var b =
QuoteValue.length;
if(QuoteValue.lastIndexOf(")")>-1){
b=b-1;
}
var
s=QuoteValue.slice(a,b);
var
s1=s.indexOf(".");
s=s.slice(0,s1+3);
FieldValue
= s;
}
Requirement: We
have requirement when lead saved/created by Partner user then show popup alert
message like Lead is saved not submitted.
Technical:
Partner portal user creates Lead and Save it so it will open Lead standard
page. So we need to add Alert message on this Standard page. We have two
options given below:
Open 1: We can override the Lead’s View which is in
Setup>Object (Lead)>Standard Button and
Link>View>Edit
First you have to create visualforce page which is getting
the window on load alert message. Add this page to View override in Lead.
Open 2: We have another option like if we have visualforce
page and add in to Page Layout. Which checks the Lead Status = ‘Draft’and Lead
Category = ‘Opportunity Registration’ then show alert message to Portal user.
We have created Visualforce page which satisfy above criteria and show alert
message.
Visualforce Page OppRegAlertPage:
<apex:page standardController="Lead"
tabStyle="Lead" >
<apex:form >
<apex:inputHidden
value="{!Lead.Lead_Category__c}" id="LeadCategoryId"/>
<apex:inputHidden value="{!Lead.Status}"
id="StatusId"/>
</apex:form>
<script language="javascript">
var LdCategory;
var LdStatus;
LdCategory=document.getElementById('j_id0:j_id1:LeadCategoryId').value;
LdStatus=document.getElementById('j_id0:j_id1:StatusId').value;
window.onload = function() {
if( LdCategory == 'Opportunity Registration'
&& LdStatus =='Draft'){
alert(‘Lead
Saved but not Submitted!');
}
}
</script>
</apex:page>
Setting>Go to Lead> Page Layout>Select page layout
for Portal user>Edit
Click on Edit Layout> Click on Visualforce pages>Select
page > Drag and Drop in to Page section>Double click on Page>
Open Visualforce Page Properties> Width (in pixels or
%)s=10%
Height
(in pixels) = 0
Save Page Layout.
Recursive
triggers in Salesforce
Suppose there is a scenario where in one trigger perform
update operation, which results in invocation of second trigger and the update
operation in second trigger acts as triggering criteria for trigger one.
Solution:
Class:
Solution:
Class:
public class Utility
{
public static boolean isFutureUpdate;
}
Trigger:
trigger updateSomething on Account (after insert, after update)
{
/* This trigger performs its logic when the call is not from @future */
if(Utility.isFutureUpdate != true)
{
Set<Id> idsToProcess = new Se<Id>();
for(Account acct : trigger.new)
{
if(acct.NumberOfEmployees > 500)
{
idsToProcess.add(acct.Id);
}
}
/* Sending Ids to @future method for processing */
futureMethods.processLargeAccounts(idsToProcess);
}
}
Class:
public class FutureMethods
{
@future
public static void processLargeAccounts(Set<Id> acctIDs)
{
List<Account> acctsToUpdate = new List<Account>();
/* isFutureUpdate is set to true to avoid recursion */
Utility.isFutureUpdate = true;
update acctsToUpdate;
}
}
{
public static boolean isFutureUpdate;
}
Trigger:
trigger updateSomething on Account (after insert, after update)
{
/* This trigger performs its logic when the call is not from @future */
if(Utility.isFutureUpdate != true)
{
Set<Id> idsToProcess = new Se<Id>();
for(Account acct : trigger.new)
{
if(acct.NumberOfEmployees > 500)
{
idsToProcess.add(acct.Id);
}
}
/* Sending Ids to @future method for processing */
futureMethods.processLargeAccounts(idsToProcess);
}
}
Class:
public class FutureMethods
{
@future
public static void processLargeAccounts(Set<Id> acctIDs)
{
List<Account> acctsToUpdate = new List<Account>();
/* isFutureUpdate is set to true to avoid recursion */
Utility.isFutureUpdate = true;
update acctsToUpdate;
}
}
Introduction :- Salesforce
to Salesforce enables you to share records among the business partners.
Step1:-
To
establish connection from one organization to another salesforce organization
,we need to enable settings first in both organizations.
Set
up--> AppSetup-->Customize-->Salesforce to Salesforce--> Settings.
After
enabling settings we need to add another salesforce organization Name and it's
Email as Contact in to parent salesforce organization.
Step2:-
Now
you can find Tab 'Connections', add that Tab to Tabs bar.
Step3:- Sending
Invitation to another organization.
Now
click on 'Connection Tab',click on New--> Select the contact ,that we
have created as per in earlier step--> Click on Save&Send Invite.
Then
Email will send to Email,which is associated in that contact.
Step4:-
In
that Email,we can get an Link,Click on link and give the login details of
client (add contact sales force organization login details).Now you
can see the connection invitation in child salesforce organization.
Click
on Accept,Now this allows you to share lead, opportunity, account,
contact, task, product, opportunity product, case, case comment, attachment, or
custom object records with your business partners. With Salesforce to
Salesforce, you can share records with one or more connections, and each connection
can accept records you share with them - even if other connections have
accepted the same record.
Step 5:- I want to share Accounts
First
publish this object from parent connection,for that
Click
connection detail page,there you can find the Related list "Publish
Object",there you can find button 'publish/unpublish'.Click on that button
,then in new window you can see all the available objects for connection.select
Account click on Save.
Now goto
business partner Organization,on Connection Detail page you can find
related list for Subscribe object, click on button
'subscribe/unsubscribe',click on that button,select object from pick
list and click on save. Now to share account records goto parent
Salesforce organization ,select Account records from list view of Account
records and click on 'Forward to Connections', there you can find list of
Available connections in your organization,select organization and
click on save.
Then
that Account record will be created in Account object of the business partner.
In
this way we can share account records from parent org to business partner
organization.
Step 5:- I want to share contact and
opportunities associated with an Account record
We
can achieve this by publishing contacts and opportunity objects to business
partner and he must subscribe to that objects also.Now send the account record
which is associated with above contact and opportunity objects as we discuss in
earlier step.
Questions
1. My organization Having 15000 records in
Accounts object, can we transfer all the records in one step?
---> Yes,
you can achieve this by writing Apex class. I am giving code for this
please go through once you can under stand easily.
Controller:-
global class SendOldRecord
{
public void
sendrec(list<Account> ls)
{
//This list
declaration for PartnerNetworkrecords
List<PartnerNetworkRecordConnection> lstShareRecords = new
List<PartnerNetworkRecordConnection>();
//This list
declaration for the Connections with this Organization.
List<PartnerNetworkConnection> connMap=[select Id, ConnectionStatus,
ConnectionName from PartnerNetworkConnection
where ConnectionStatus = 'Accepted' and ConnectionName='Appshark
Software Pvt Ltd'];
//This for is to
loop all the connections
for(PartnerNetworkConnection network : connMap)
{
for(Account acc:ls)
{
//object declaration for PartnerNetwork
PartnerNetworkRecordConnection newrecord = new
PartnerNetworkRecordConnection();
system.debug('Second for loop');
newrecord.ConnectionId = network.Id;
newrecord.LocalRecordId = acc.id;
newrecord.RelatedRecords = 'Contact';
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
//All the Records are added to the PartnerNetwork
lstShareRecords.add(newrecord);
}
}
system.debug('List\n'+lstShareRecords);
//These
Records are inserted into Partnernetwork
//using
lstShareRecords.
insert
lstShareRecords;
}
}
in the case of bulk records , we need to handle them in Batch
process,for i have implemented following batch class and pass to list of
accounts at every run,
Batch Controller:-
global
class RecordBatchApex implements Database.Batchable<Account>
{
global
list<Account> start(Database.BatchableContext bc)
{
list<account> lstAcc = [select Id from Account];
return lstAcc;
}
global
void execute(Database.BatchableContext bc,List<Account> lstAccount)
{
system.debug('*******************Execute
of Batch Apex***********');
system.debug(lstAccount);
sendoldrecord
od=new sendoldrecord();
od.sendrec(lstAccount);
}//BatchApex
Completes
//
execution with this finish method
global
void finish(Database.BatchableContext BC)
{system.debug('****Finished*****');
}}
Once
run that code even from System log,then you can find all the records in
business partner login.
2. I want to insert newly created Account in to partner's
organization.
In
this Scenario we will go for Apex trigger to create newly inserted account into
partner's Organization.
Trigger
autoforwardAccount on Account(after insert)
{
String UserName = UserInfo.getName();
String orgName = UserInfo.getOrganizationName();
List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>(
[select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted']
);
System.debug('Size of connection map: '+connMap.size());
List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();
for(Integer i =0; i< Trigger.size; i++)
{
Account acc = Trigger.new[i];
String acId = acc.Id;
System.debug('Value of AccountId: '+acId);
for(PartnerNetworkConnection network : connMap)
{
String cid = network.Id;
String status = network.ConnectionStatus;
String connName = network.ConnectionName;
String AccountName = acc.Name;
System.debug('Connectin Details.......Cid:::'+cid+'Status:::'+Status+'ConnName:::'+connName+'AccountName:::'+AccountName);
if(AccountName !=Null)
{
PartnerNetworkRecordConnection newrecord = new PartnerNetworkRecordConnection();
newrecord.ConnectionId = cid;
newrecord.LocalRecordId = acId;
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
System.debug('Inserting New Record'+newrecord);
insert newrecord;
}}}}
3. Can we insert Contact or Opportunity related for an account,while inserting contact or opportunity ?
Yes, We can, for that we need to trigger on Contact/Opportunity ,here we are inserting contact/opportunity related to an account for that we need to specify account Id also.
We PartnerNetworkRecordConnection object for sharing records between salesforce to salesforce.
It contains filed 'ParentRecordId',to that filed we need to assign that account id.I have written trigger on conatct , i am giving code for that,you can implement same thing for opportunity also.
Trigger autoforwardContact on Contact(after Insert)
{
String UserName = UserInfo.getName();
String orgName = UserInfo.getOrganizationName();
List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>( [select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted'] );
System.debug('Size of connection map: '+connMap.size());
List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();
for(Integer i =0; i< Trigger.size; i++)
{
Contact con = Trigger.new[i];
String conId = con.Id;
System.debug('Value of ContactId: '+conId);
for(PartnerNetworkConnection network : connMap)
{
String cid = network.Id;
String status = network.ConnectionStatus;
String connName = network.ConnectionName;
String ContactName = con.LastName;
String Accountid = con.Accountid;
System.debug('Connectin Details.......Cid:::'+cid+'Status:::'+Status+'ConnName:::'+connName+'ContactName:::'+COntactName);
System.debug('Account ID************'+Accountid);
if(ContactName!= NULL)
{
System.debug('INSIDE IF');
PartnerNetworkRecordConnection newrecord = new PartnerNetworkRecordConnection();
newrecord.ConnectionId = cid;
newrecord.LocalRecordId = ConId;
newrecord.ParentRecordId= Accountid; // here we are specifying Account ID
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
System.debug('Inserting New Record'+newrecord);
insert newrecord;
}} } }
{
String UserName = UserInfo.getName();
String orgName = UserInfo.getOrganizationName();
List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>(
[select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted']
);
System.debug('Size of connection map: '+connMap.size());
List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();
for(Integer i =0; i< Trigger.size; i++)
{
Account acc = Trigger.new[i];
String acId = acc.Id;
System.debug('Value of AccountId: '+acId);
for(PartnerNetworkConnection network : connMap)
{
String cid = network.Id;
String status = network.ConnectionStatus;
String connName = network.ConnectionName;
String AccountName = acc.Name;
System.debug('Connectin Details.......Cid:::'+cid+'Status:::'+Status+'ConnName:::'+connName+'AccountName:::'+AccountName);
if(AccountName !=Null)
{
PartnerNetworkRecordConnection newrecord = new PartnerNetworkRecordConnection();
newrecord.ConnectionId = cid;
newrecord.LocalRecordId = acId;
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
System.debug('Inserting New Record'+newrecord);
insert newrecord;
}}}}
3. Can we insert Contact or Opportunity related for an account,while inserting contact or opportunity ?
Yes, We can, for that we need to trigger on Contact/Opportunity ,here we are inserting contact/opportunity related to an account for that we need to specify account Id also.
We PartnerNetworkRecordConnection object for sharing records between salesforce to salesforce.
It contains filed 'ParentRecordId',to that filed we need to assign that account id.I have written trigger on conatct , i am giving code for that,you can implement same thing for opportunity also.
Trigger autoforwardContact on Contact(after Insert)
{
String UserName = UserInfo.getName();
String orgName = UserInfo.getOrganizationName();
List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>( [select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted'] );
System.debug('Size of connection map: '+connMap.size());
List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();
for(Integer i =0; i< Trigger.size; i++)
{
Contact con = Trigger.new[i];
String conId = con.Id;
System.debug('Value of ContactId: '+conId);
for(PartnerNetworkConnection network : connMap)
{
String cid = network.Id;
String status = network.ConnectionStatus;
String connName = network.ConnectionName;
String ContactName = con.LastName;
String Accountid = con.Accountid;
System.debug('Connectin Details.......Cid:::'+cid+'Status:::'+Status+'ConnName:::'+connName+'ContactName:::'+COntactName);
System.debug('Account ID************'+Accountid);
if(ContactName!= NULL)
{
System.debug('INSIDE IF');
PartnerNetworkRecordConnection newrecord = new PartnerNetworkRecordConnection();
newrecord.ConnectionId = cid;
newrecord.LocalRecordId = ConId;
newrecord.ParentRecordId= Accountid; // here we are specifying Account ID
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
System.debug('Inserting New Record'+newrecord);
insert newrecord;
}} } }
Using
Above Trigger we can Send newly inserted record in to Partner's organization.
Question:
* There are two sObjects A and B.
* For A sobject user has access, For
B he dont have access.
* If he write a Trigger on A sobject
which intern want to access B sObject What will happen?
Answer:
*
Triggers run in the system context (unless you hand over to a class decorated
as 'with sharing') so I'd expect the trigger to be able to access object B as
long as the user's license type covers that object.
Question:
I have to call to an external
webservice everytime a new account is created. My question is, what is the best
way to do so?
I
thought about creating an after create trigger that will invoke the method in
the class that was generated from the WSDL import. Would that make sense?
If
so, how can I import a class into a trigger to use its methods?
Is
it the same with Http request or can i make the http request directly from the
trigger?
Solution:
Currently
in Salesforce we cannot make callout from trigger directly , You need to write
a future class that will invoke the callout using wsdl generated classes. So in
fact this call will be asynchronous call rather than realtime callout.
For
example- you have a wsdl generated class
named "WSDlGeneratedClass" , And you will have to write a future
method like -
public
class future class
{
@future(callout=true)
public static void calloutMethod()
{
// write code to invoke
"WSDlGeneratedClass" class methods to make callout
}
}
Now
this method you will need to call from trigger.
Yes
its also with HTTP callout (cannot make
any kind of callout from trigger directly).
how to remove a value from list without
using its index?
"list<string>options=new
list<string>{'a','b','c','d','e','f','g','h'};"
from
this list i want to remove "e" (lets assume that 'i have dont know
its index')
Solution:
*
Just add all list values to a SET.
*
We can directly remove values from set using remove() method.
*
After that add this set to a particular list.
How can we read and save body and
attachments in Salesforce of email?
Trigger:
trigger sendEmail on Employee__c (after insert, after update)
{
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(Employee__c e : trigger.new)
{
Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
attach.setContentType('application/pdf');
attach.setFileName('Employee.pdf');
String body;
body = '<html><h1 style=\"text-align:center;\">Employee Information</h1><br/><br/><table align=\"center\"><tr><td>Employee Name</td><td>' + e.Name + '</td></tr><tr><td>Age</td><td>' + e.Age__c + '</td></tr><tr><td>State</td><td>' + e.State__c + '</td></tr><tr><td>City</td><td>' + e.City__c + '</td></tr></table></html>';
System.debug('HTML is ' + body);
attach.Body = Blob.toPDF(body);
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new String[] { e.Email__c });
mail.setSubject('PDF Generation');
mail.setHtmlBody('PFA');
mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attach });
mails.add(mail);
}
if(!mails.isEmpty())
{
Messaging.SendEmail(mails);
}
}
trigger sendEmail on Employee__c (after insert, after update)
{
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(Employee__c e : trigger.new)
{
Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
attach.setContentType('application/pdf');
attach.setFileName('Employee.pdf');
String body;
body = '<html><h1 style=\"text-align:center;\">Employee Information</h1><br/><br/><table align=\"center\"><tr><td>Employee Name</td><td>' + e.Name + '</td></tr><tr><td>Age</td><td>' + e.Age__c + '</td></tr><tr><td>State</td><td>' + e.State__c + '</td></tr><tr><td>City</td><td>' + e.City__c + '</td></tr></table></html>';
System.debug('HTML is ' + body);
attach.Body = Blob.toPDF(body);
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new String[] { e.Email__c });
mail.setSubject('PDF Generation');
mail.setHtmlBody('PFA');
mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attach });
mails.add(mail);
}
if(!mails.isEmpty())
{
Messaging.SendEmail(mails);
}
}
How
to bulkify trigger
The term bulkifying Apex
code refers to the concept of making sure the code properly handles more than
one record at a time. When a batch of records initiate Apex, a single instance
of that Apex code is executed, but it needs to handle all of the records in
that given batch.
Here is an example of poorly written code that only handles one record:
trigger accountTestTrggr on Account (before insert, before update)
{
//This only handles the first record in the Trigger.new collection
//But if more than 1 Account initiated this trigger, those additional records
//will not be processed
Account acct = Trigger.new[0];
List<Contact> contacts = [select id, salutation, firstname, lastname, email
from Contact where accountId = :acct.Id];
}
The issue is that only one Account record is handled because the code explicitly accesses only the first record in the Trigger.new collection by using the syntax Trigger.new[0]. Instead, the trigger should properly handle the entire collection of Accounts in the Trigger.new collection.
Here is a sample of how to handle all incoming records:
trigger accountTestTrggr on Account (before insert, before update)
{
List<String> accountNames = new List<String>{};
//Loop through all records in the Trigger.new collection
for(Account a: Trigger.new){
//Concatenate the Name and billingState into the Description field
a.Description = a.Name + ':' + a.BillingState
}
}
Notice how this revised version of the code iterates across the entire Trigger.new collection with a for loop. Now if this trigger is invoked with a single Account or up to 200 Accounts, all records will be properly processed.
Here is an example of poorly written code that only handles one record:
trigger accountTestTrggr on Account (before insert, before update)
{
//This only handles the first record in the Trigger.new collection
//But if more than 1 Account initiated this trigger, those additional records
//will not be processed
Account acct = Trigger.new[0];
List<Contact> contacts = [select id, salutation, firstname, lastname, email
from Contact where accountId = :acct.Id];
}
The issue is that only one Account record is handled because the code explicitly accesses only the first record in the Trigger.new collection by using the syntax Trigger.new[0]. Instead, the trigger should properly handle the entire collection of Accounts in the Trigger.new collection.
Here is a sample of how to handle all incoming records:
trigger accountTestTrggr on Account (before insert, before update)
{
List<String> accountNames = new List<String>{};
//Loop through all records in the Trigger.new collection
for(Account a: Trigger.new){
//Concatenate the Name and billingState into the Description field
a.Description = a.Name + ':' + a.BillingState
}
}
Notice how this revised version of the code iterates across the entire Trigger.new collection with a for loop. Now if this trigger is invoked with a single Account or up to 200 Accounts, all records will be properly processed.
•
The Situation is I
do have two Check boxes (Checkbox A & Checkbox B).And My condition is to
allow any one of the check box is true ,not the two at a time.
If checkbox A is true , Check box B should be False and
IF Checkbox B is true , Check box B should be False , Both should not be
TRUE.
use
the Validation rule to do this and display the error if both are
checked
In Error Condition
Formula
AND(checkboxA,checkboxB)
In ERROR
MESSAGE:select only once checkbox
How will you handle 10001
SOQL problems in apex?
10001 error means
“Too many query rows”
Public
static integer getTotalVotes()
{
integer totalIdea = [SELECT count()
FROM Vote where Parent.Type='Idea' limit 501];
return totalIdea ;
}
what is the use of SeeAllData=true in isTest?
In test class and methods, we can access data in the organization. Prior to it
we can just access test data. Using this we can access organization data.
For Apex code saved using Salesforce.com API version 24.0 and later, use the isTest(SeeAllData=true) annotation to grant test classes and individual test methods access to all data in the organization, including pre-existing data that the test didn’t create.
Starting with Apex code saved using Salesforce.com API version 24.0, test methods don’t have access by default to pre-existing data in the organization. However, test code saved against Salesforce.com API version 23.0 or earlier continues to have access to all data in the organization and its data access is unchanged.
For Apex code saved using Salesforce.com API version 24.0 and later, use the isTest(SeeAllData=true) annotation to grant test classes and individual test methods access to all data in the organization, including pre-existing data that the test didn’t create.
Starting with Apex code saved using Salesforce.com API version 24.0, test methods don’t have access by default to pre-existing data in the organization. However, test code saved against Salesforce.com API version 23.0 or earlier continues to have access to all data in the organization and its data access is unchanged.
Unit Testing
for Triggers
Sample
Trigger:
trigger DuplicateMemberCheck on Member__c
(before insert)
{
for(Member__c memb:trigger.new)
{
List<Member__c> mem = new List<Member__c>();
String email = memb.E_Mail_Id__c;
String sql = 'SELECT E_Mail_Id__c FROM Member__c';
mem = Database.Query(sql);
for(Member__c tempMember:mem)
{
if(tempMember.E_Mail_Id__c == email)
{
memb.E_Mail_Id__c.addError('Duplicate Record');
}
}
}
}
{
for(Member__c memb:trigger.new)
{
List<Member__c> mem = new List<Member__c>();
String email = memb.E_Mail_Id__c;
String sql = 'SELECT E_Mail_Id__c FROM Member__c';
mem = Database.Query(sql);
for(Member__c tempMember:mem)
{
if(tempMember.E_Mail_Id__c == email)
{
memb.E_Mail_Id__c.addError('Duplicate Record');
}
}
}
}
Sample
Test Class for Sample Trigger:
@isTest
public
class TestDuplicateMemberCheckClass
{
static
testMethod void test()
{
Date
birthday = Date.valueOf('2000-12-20');
Member__c
mem = new Member__c(Name = 'Test', E_Mail_Id__c = 'magulan.d@igatepatni.com',
Mobile_Number__c = '99966663322', Birthday__c = birthday);
Member__c
mem1 = new Member__c(Name = 'Test', E_Mail_Id__c = 'magulan@igatepatni.com',
Mobile_Number__c = '99966663322', Birthday__c = birthday);
try
{
insert
mem;
insert
mem1;
}
catch(DMLException
e)
{
System.assert(e.getMessage().contains('Duplicate
Record'));
}
}
}
How to use multiple
substitute function in Salesforce?
We
have to use nested SUBSTITUTE() methods for multiple replacing of characters.
Example:
SUBSTITUTE(SUBSTITUTE(Name," ", ""),"-","" )
In this example, we can remove "-" and space.
Example:
SUBSTITUTE(SUBSTITUTE(Name," ", ""),"-","" )
In this example, we can remove "-" and space.
Validation rules for Country
codes(USA, Mexico, Argentina, Canada, Australia) in Salesforce
Example:
OR(
AND(
ISPICKVAL( Country_Code__c , "USA"),NOT( REGEX( Pincode__c , "\\d{5}(-\\d{4})?") )
),
AND(
ISPICKVAL( Country_Code__c , "MEX"), NOT(REGEX( Pincode__c , "\\d{5}")), NOT(REGEX( Pincode__c , "\\d{6}"))
),
AND( ISPICKVAL( Country_Code__c , "AUS"), NOT(REGEX( Pincode__c , "\\d{4}"))
),
AND( ISPICKVAL( Country_Code__c , "CAN"), NOT(REGEX( Pincode__c , "[a-zA-Z]{1}[0-9]{1}[a-zA-Z]{1}\\s[0-9]{1}[a-zA-Z]{1}[0-9]{1}"))
),
AND( ISPICKVAL( Country_Code__c , "ARG"), NOT(REGEX( Pincode__c , "[a-zA-Z]{1}\\d{4}[a-zA-Z]{3}")),NOT(REGEX( Pincode__c , "\\d{4}"))
)
)
OR(
AND(
ISPICKVAL( Country_Code__c , "USA"),NOT( REGEX( Pincode__c , "\\d{5}(-\\d{4})?") )
),
AND(
ISPICKVAL( Country_Code__c , "MEX"), NOT(REGEX( Pincode__c , "\\d{5}")), NOT(REGEX( Pincode__c , "\\d{6}"))
),
AND( ISPICKVAL( Country_Code__c , "AUS"), NOT(REGEX( Pincode__c , "\\d{4}"))
),
AND( ISPICKVAL( Country_Code__c , "CAN"), NOT(REGEX( Pincode__c , "[a-zA-Z]{1}[0-9]{1}[a-zA-Z]{1}\\s[0-9]{1}[a-zA-Z]{1}[0-9]{1}"))
),
AND( ISPICKVAL( Country_Code__c , "ARG"), NOT(REGEX( Pincode__c , "[a-zA-Z]{1}\\d{4}[a-zA-Z]{3}")),NOT(REGEX( Pincode__c , "\\d{4}"))
)
)
Salesforce Problems and Solutions
Reviewed by dasfrogpractice
on
01:25
Rating:
The information which you have provided is very good. It is very useful who is looking for salesforce online training in Hyderabad
ReplyDeleteFind Here Best Salesforce Certification Sample Papers, Platform Developer 1 Dumps, We are Providing Salesforce Sample Questions, Salesforce Dumps, Service Cloud Sample Papers, Sales Cloud Sample Papers, We have online courses for Salesforce Administrators as well as Developer Certification. Details of the same are available.
ReplyDeleteBundle Offer 2020:
We are new offering. Buy any two papers and get third free. Offer available for for all courses available online. You can pick and choose certifications which are relevant to you and complete the certifications at your pace.
More Info: http://www.salesforcecertifications.com/
Quick! Book Your Spot for Wednesday[4th March, 11 AM(IST) | 4 PM(GST) | 11:00 AM(EST)] WEBINAR on topic: How to Perform Bulk Operation in Salesforce using BOFC App?
ReplyDeleteYou'll learn
How to Bulk Compare Multiple Profiles and Permission Sets and Export in XLS, Manage Record Types in Bulk, Clone Multiple Custom Fields and Objects.
Quick! Book Your Spot for Wednesday[25th March, 11 AM(IST) | 4 PM(GST) | 11:00 AM(PDT)] WEBINAR on topic: Bulk Export Operations in Salesforce using BOFC App
ReplyDeleteYou'll learn
How to Export Multiple Page-Layouts & Fields Presence Matrix, Export Multiple Objects & Rules, Process Builders & Flows, etc.
Thanks for sharing Salesforce problems and solution. Here are the benefits of Salesforce CRM
ReplyDeleteDr.Agbazara is a great man,this doctor help me to bring back my lover
ReplyDeleteJenny Williams who broke up with me 2year ago with his powerful spell
casting and today she is back to me so if you need is help contact him on
email: ( agbazara@gmail.com ) or call/WhatsApp +2348104102662. And
get your relationship problem solve like me
Dr.Agbazara is a great man,this doctor help me to bring back my lover
ReplyDeleteJenny Williams who broke up with me 2year ago with his powerful spell
casting and today she is back to me so if you need is help contact him on
email: ( agbazara@gmail.com ) or call/WhatsApp +2348104102662. And
get your relationship problem solve like me
Thanks for sharing great post about saslesforce problem and solution. Keep it post!
ReplyDeleteSalesforce Integration Services
Salesforce Consulting Services
Salesforce Customization Services
Salesforce Implementation Services
Thanks for sharing such a great post about Salesforce Problems and Solutions. Choose the perfect partner for your Salesforce needs
ReplyDeleteThanks for sharing Great info...Nice post.
ReplyDeleteSalesforce course
Thanks for sharing great post about saslesforce. Keep it post!
ReplyDeleteSalesforce Integration Services
Thanks for Sharing This Article. It was a valuable content. I hope these Commenting lists will help to my website.
ReplyDeleteAmazon web services Training in chennai
Amazon web services Course in chennai
ReplyDeleteTechforce services is a Salesforce Consulting Services in Australia Specialising in delivering end to end Salesforce solutions ,Consulting, Implementation DevOps partners in australia We deliver applications and services more rapidly and reliably, but it’s more than a methodology – it cuts to the very core.Salesforce Data Analytics let us help you become a data driven organisation and ensure your data is working hard for your business This includes implementi
Salesforce consulting companies
Salesforce Services
Staff augmentation companies
Salesforce integration companies
Salesforce Implementation services
Salesforce DevOps partners
Salesforce DevOps
<a href="https://techforceservices.com.au/salesforce-australia-managed-projects-techforce-services/
We are a leading Salesforce Development Company in India & USA , creating tailored Salesforce CRM and cloud computing solutions for companies and organizations of different sizes. We endeavor to become a trusted salesforce advisor and have a focus on delivering phenomenal salesforce service. We help clients become more buoyant, valuable and responsive by empowering them with cloud, mobile and social technologies. We have successfully completed over 500 engagements assisting clients design, develop and manage a wide range of solutions based on Salesforce.com.
ReplyDelete