About Me

My photo
PLANO, Texas, United States

Tuesday, June 18, 2013

Factors that Affect Data Access In SFDC Integration

There are many factors that comes when we are doing some integration with another system.  When using the API, the following factors affect access to your organization’s data:
1. Access:  
     Your organization must be enabled for API access.
2. Choosing a WSDL: 
      Here are two Force.com Web services for which you can obtain WSDL files for API access:                                         
a)  Force.com EnterpriseWSDL
This API is for most enterprise users who are developing client applications for their organization. The enterprise WSDL file is a strongly typed representation of your organization’s data. Note the following when generating the enterprise WSDL:
1)   If new custom fields or objects are added to, renamed, or removed from your organization’s information, you need to re-generate the WSDL file in order to access them.
2) The generated WSDL contains the objects and fields in your organization, including those available in the selected versions of each installed package. If a field or object is added in a later package version, you must generate the enterprise WSDL with that package version to work with the object or field in your API integration.
b)  Force.com Partner WSDL—    
This API is for salesforce.com partners who are developing client applications for multiple organizations. As a loosely-typed representation of the Salesforce object model, the partner WSDL can be used to access data within any organization.
3. User Permissions: 
   A user attempting to access the API must have the permission “API Enabled” selected. It’s selected by default.
4. Object Properties: 
      To create an object with the create() call, the object's createable 
Attribute must be set to true. To determine what operations are allowed on a given object, your client application can invoke thedescribeSObjects() call on the object and inspect the properties in the DescribeSObjectResult.
5. Page Layouts and RecordType:
    Requirements defined in the Salesforce user interface for page layouts and record types are not enforced by the API:Page layouts can specify whether a given field is required, but the API does not enforce such layout-specific field restrictions or validations in create() and update() calls. It’s up to the client application to enforce any such constraints, if applicable.
    Record types can control which picklist values can be chosen in a given record and which page layouts users with different profiles can see. However, such rules that are configured and enforced in the user interface are not enforced in the API. For example, the API does not validate whether the value in a picklist field is allowed per any record type restrictions associated with the profile of the logged-in user. Similarly, the API does not prevent a client application from adding data to a particular field simply because that field does not appear in a layout associated with the profile of the logged-in user.
6. Object-Level and Field-Level Security:                                                                                                        The API respects object-level and field-level security configured in the user interface. You can access objects and fields only if the logged-in user's permissions and access settings allow such access. For example, fields that are not visible to a given user are not returned in a query() or describeSObjects() call. Similarly, read-only fields can't be updated.


Monday, June 3, 2013

Excel Common Error

Hi Everyone,
I got a very strange issue while updating Customer Number Field from the Data Loader in salesforce. Actually I was uploading Contacts from the Data Loader and there is a custom field Customer Number on Contact. I have to add two leading zeros in the number and make it 10 digit number. e.g if If customer Number is 98765432 then I had to upload as 0098765432. So when I am filling this value in CSV Column, it automatically remove leading two zeros. So here is the workaround for this :

1. Right Click on the Column in which you want to add leading zeros and make it as Text:
















2. Fill the value in the column whatever you want and save it in CSV format.
3. Now upload the CSV file. But always remember, never open the CSV file because if you open that file leading zero automatically will remove so try to upload without open that CSV file.

Tuesday, May 28, 2013

MIXED_DML_OPERATION

“MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Contact

You can easily run into this error if you are trying to perform DML on setup and non-setup objects in the same transaction. Non-Setup objects can be any one of standard objects like Account or any custom object, whereas a “setup" object is one that must be edited from the setup or builder area of the platform. These objects include the User object, Organization object, Email templates and so on. Here are few examples of the Setup Objects
1.     Group1
2.     GroupMember
3.     QueueSObject
4.     User2
5.     UserRole
6.     UserTerritory
7.     Territory

Error Conditions :
You can get this error in two blow conditions
1.     Non-Test code (Non-Test code means any Apex code that is not written for test cases)
2.     Test Code
      For Non-Test Class  
      Use Future method to resolve this issue.
      I got this error few month back when I was writing the Trigger on Contact whenever someone make Contact Inactive then its associated Owner become inactive.  
 trigger UpdateContactTrigger on Contact (after update)
 {
       List<User> lstUser = new List<User>();
       for(Contact oContact : Trigger.New){
          if(oContact.isActive__c == false && oContact.isActive__ c! =     Trigger.oldMap.get(oContact.Id).isActive__c){
             User oUser = new User(Id=oContact.OwnerId);
             oUser.IsActive = false;
             lstUser.add(oUser);}
            }
                   if(lstUser != null){
                    update lstUser;
               }
         }
       Below are the workaround for this Trigger:
 Trigger :
trigger MakeUserInactiveTrigger on Contact (after update) 
{
    List<Id> sUser = new List<Id>();
   for(Contact oContact : Trigger.New){
       if(oContact.isActive__c == false && oContact.isActive__c !=Trigger.oldMap.get(oContact.Id).isActive__c) {
           sUser.(oContact.OwnerId);
       }
    }
    UpdateUserUtil.updateUser(sUser);
}

Future Class to handle this Exception:

global class UpdateUserUtil
{
    @future    
    public static void updateUser(List<> userId) 
    {     
        List<User> lstUser = new List<User>();
        for( User oUser : [select IsActive,Id   from User  where Id=:userId]) 
        {
                  User u = new User(Id=oUser.Id);
                  u.isActive = false; 
                  lstUser.add(u);
        }
        if (lstUser != null) 
        {    
            upadate lstUser;
        }
}

In this way, we can resolve the issue. So use future method to resolve this error.

     For Test Class  
     Use system.runAs() Method to resolve this issue.
      In Above method, We are using the currently updated User ID in Creation in the Sony Account  Team(Custom Object)
     Public static testMethod void EmailAddressLookup() {
            Test.startTest();
            User uID=SFE_UtilForSFE.CreateUser('newUser','newuserTY@testorg.com','Testing','newuser@testorg.com');
            uID.IsActive = true;
            update uID;
            Account oAccount = SFE_UtilForSFE.CreateAccount('Test Account','678906',null,'AE11');
            Contact oContact = SFE_UtilForSFE.createContact('testContact',oAccount.ID );
            oContact.Email = 'newcontact@testorg.com';
            update oContact;
            Sony_Account_Team__c oSAT=SFE_UtilForSFE.Create_Sony_Account_Team('Testsat',oAccount.id,uID.ID );
           Test.stopTest();
    }
  
So Once I run the test class I got MIXED_DML_OPERATION, DML error and to resolve this error, I used System.RunAs() like below :

public static testMethod void EmailAddressLookup()
{
       Test.startTest();
       User uID=SFE_UtilForSFE.CreateUser('newUser','newuserTY@testorg.com','Testing','newuser@testorg.com');
       uID.IsActive = true;
       update uID;
       List<User> lstUsers = [select Id, ContactId, AccountId from User where Id =:uID.Id];
       if(lstUsers != null && lstUsers.size() > 0)
       {
            User userInstance = lstUsers[0];
            system.runAs(userInstance)
            { 
                Account oAccount = SFE_UtilForSFE.CreateAccount('Test Account','678906',null,'AE11');
                Contact oContact = SFE_UtilForSFE.createContact('testContact',oAccount.ID );
                oContact.Email = 'newcontact@testorg.com';
                 update oContact;
                Sony_Account_Team__c oSAT=SFE_UtilForSFE.Create_Sony_Account_Team('Testsat',oAccount.id,uID.ID );
            }
       }
      Test.stopTest();
}   

So this is what I came out from this error.

Hope this will help in understanding or learning purpose. 

Thanks










Sunday, May 19, 2013

Insufficient Access On Cross_reference_entity Error

I was stuck in my code and getting insufficient_access_on_cross_reference_entity error while writing the trigger and creating the the Account Team Member from the trigger. After spending lot of time and got some good blogs and good information, Finally, i got it sorted out and i hope this post helps someone understand and solve as well.

When does this error happen?
This error normally happens when a DML operation is performed. Meaning that, whenever an Insert or Update is performed. You won't see this error when you save your APEX class or TRIGGER, because this error happens at RUNTIME.

What does this error mean?
This error means that you are trying to do an operation which is not supposed to be done, or the operation you are about to perform is not permitted according to the Sharing and Security settings defined. This error message does NOT always mean that you lack access to do the operation, even though it might be the case sometimes. So, even if you are an ADMINISTRATOR you may get this message.

Possible Causes:
Let's take some scenario's and analyze.

 Scenario 1:  Creating a new record (Account/Contact/...) and setting the Owner. Applies to updating records as well.

So, in your code you create some records. By Default the creator of the record is the Owner. You want to change this and you modify the OwnerId column of the newly created records. You make "User X" as the Owner. Now when you run the code, you get the Error below:
System.DmlException: Insert failed. First exception on row 2; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
Things to check:
  *Check that the Running user (in this case you) has access to the object being operated. Check that he has CREATE privileges on the object. This is optional, but is always better to start from here
  *Check that the Owner ie User X has CREATE permission on the object. Check that his profile has the CREATE permission on the particular object. He might not be having it, grant him permission and the issue is resolved.

 Scenario 2:
Creating or Updating an Opportunity (just for an example,  might be any object). Setting the related Account of the Opportunity.

So, let's say that you create 5 Opportunities and you set the Owner to "User X". You set the Account to "Account X". When your code tries to insert these 5 opportunities, it fails and you get the same error message.
System.DmlException: Insert failed. First exception on row 2; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
Reason:
This is because "User X" does not have access to "Account X". When you try to create an Opportunity for "Account X" that he does not have access to the code fails. Either grant access to "User X" for "Account X" manually or through code and then do the Insert.

Scenario 3:
The Sharing Object.

This is a bit complex to get at. atleast for me. You might be aware that every object has its own Shareobject. So, Account has AccountShare and Customobj__c has Customobj__Share
When you insert or update records in this object you might receive the same error message. There are a number of reasons for this to happen. 

    *If you are trying to share "Record X" with "User Y" and you yourself do not have access to "Record x", this error happens.
    *If you are trying to share "Record X" with "User Y" and "User Y" does not have access to the object (the profile level permission, create read edit delete), this error happens.
    *If you are trying to share "Record X" with "User Y" and "User Y" already has access to "Record X" this error happens.

Saturday, May 18, 2013

WebService Fuctions

Apex Web Service

Apex class methods can be exposed as custom Force.com Web services API calls. This allows an external application to invoke an Apex web service to perform an action in Salesforce.com. Use the Webservice keyword to define these methods. For
Example:
global class MyWebService {
webService static Id makeContact(String lastName, Account a) {
Contact c = new Contact(lastName = 'Weissman', AccountId = a.Id);
insert c;
return c.id;
}
}
A developer of an external application can integrate with an Apex class containing webService methods by generating a WSDL for the class.To generate a WSDL from an Apex class detail page:
1. In the application navigate to Your Name  Setup  Develop  Apex Classes.
2. Click the name of a class that contains web Service methods.
3. Click Generate WSDL.

Considerations for Using the WebService Keyword:

  • You cannot use the webService keyword when defining a class. However, you can use it to define top-level, outer class methods, and methods of an inner class.
  • You cannot use the webService keyword to define an interface, or to define an interface's methods and variables.
  • System-defined enums cannot be used in Web service methods.
  • You cannot use the webService keyword in a trigger because you cannot define a method in a trigger.
  • All classes that contain methods defined with the webService keyword must be declared as global. If a method or inner class is declared as global, the outer, top-level class must also be defined as global.
  • Methods defined with the webService keyword are inherently global. These methods can be used by any Apex script that has access to the class. You can consider the webService keyword as a type of access modifier that enables more access than global.
  • You must define any method that uses the webService keyword as static.
  • You cannot deprecate web Service methods or variables in managed package code.
  • Because there are no SOAP analogs for certain Apex elements, methods defined with the webService keyword cannot take the following elements as  parameters.While these elements can be used within the method, they also cannot be marked as return values.
    • Maps
    • Sets
    • Pattern objects
    • Matcher objects
    • Exception objects
  • You must use the webService keyword with any member variables that you want to expose as part of a Web service. You should not mark these member variables as static.
  • Salesforce.com denies access to Web service and execute anonymous requests from an AppExchange package that has restricted access.
  • Apex classes and triggers saved (compiled) using API version 15.0 and higher produce a runtime error if you assign a String value that is too long for the field.
To know about other integration API at a glance, pls Click here
To know more about the security aspect of integration, pls Click here

Change Set Deployment Steps

What is Change Set?
Change Set is the deployment tool by which Salesforce Developer/Administrator can upload/deploy the changes to Sandbox (Test Environment) to Production. You can go in Setup>Deploy>Select any option of deployment. You can deploy changes in between Sandbox to Sandbox also.
There are three main topics and steps to understand first before deployment:
1. Outbound Change set:
This is first step to the deployment through Change set. Outbound change set is nothing but creation of connection or select the changes you done in Sandbox like Object, Custom Fields, Validation, Workflow, Classes, Trigger etc. For that you have to follow below steps.
· Login in to Sandbox account of Salesforce.com.
· Go to Setup>Deploy>Outbound Change set: It will show you information on Change set and Outbound/Inbound change set information.
· Press Continue button on this page.
· Click on New button and create the outbound change set. Enter the Name of outbound change set and description of this and Click on Save.
· Once you get outbound change set detail page click Add button on Change Set Components.
· This page will show you Component Type (App, Analytical Snapshot, Apex Class, Apex Sharing Reason, Apex Trigger, Button or Link, Custom Fields, Custom Label, Object, Report Type, Custom Setting, Dashboard, Document, Email Template, Field Set, Folder, Home page Component etc.) Select any of above part and Click on Add To Change Set Button.
· After above step you will get the list of components added on change set component section.
· You can view or add dependencies in this section.
· Click on Add Profile in Profile Setting for included components means you can ass profile your can see or share the changes whatever you have done.
· After completing above steps click on Upload button. This will do the actual deployment to the Production/other Sandbox.
· Select any option from given list of Sandbox and Production.
· Click on Upload button to selected environment.
· After above step you will get Completion Email on your given email id. Means you have successfully uploaded the outbound change set.
2. Deployment Connection:
This connection step will automatically created by Sales force. Which is allows the customization to be copied from one organization to another organization. Your should be login in Production to check above list.
3. Inbound Change Set:
Inbound change set is automatically created once outbound change set it created inbound change set gets the all changes sent by outbound change set.
· Select on inbound change set and get detail of outbound.
· You can view change set components list and deployment history.
· Click on validate it will show validation history in deployment History.
· Click on Deployment after successful validation and can see Deployment History.

Friday, May 17, 2013

Apex REST API Stuck Points

Let me share my experience with REST.
1.  Apex REST supports both XML and JSON for resource formats sent in REST request and responses. By default, Apex REST uses JSON to represent resources. Now here I got the problem with the size of JSON file because SDFC can accept less than 3 MB file. SO What I did, I removed all blank spaces and also we suggested third application developer to send the file less than 3 MB if the file is larger than they will split the file into a smaller size. That helps us a lot.
2.  Always tried to map the exact api name of the field in the JSON that you are accepting from the other side. Otherwise, you need to deserialize the parameter in the method that will unnecessarily increase the complexity.
Ø  For example Below are two formats of JSON and used to update account :
   1.
            {
                 "Name" : "ParentUpdate Manoj11",
                 "Industry" : "Consultant",
                 "Phone" : "9891798737“
            }
  2.
          {
                 "Account_Name" : "ParentUpdate Manoj11",
                 "Account_Industry" : "Consultant",
                 "Account_Phone" : "9891798737",
         }
•So both will work fine but In first we no need to deserialize the JSON because we are mapping with the same API but In the second JSON we need to make this JSON deserialize. That will  unnecessarily make the method complex.

Data Rollback in Apex


Hi Everyone,
I want to share my experience of current problem. Basically it is the minor thing however it’s always good to share your experience with other. First Let  me tell you my scenario. I have three SFDC Custom Object Call Report, Meeting Attendee and Action. Now I have to save these three object on button click on VF page.
So my code was like below:

try {
 insert oCallReport;
  insert oMeetingAttendee;
 insert oAction;
} catch (Exception e) {
  ...
}

This is still alright if there is any error occurs in the first DML insert statement as the error will be caught and the second DML insert statement won't be execute. But, what if there is a problem occurs on the second DML insert statement? This will cause some bad data in your Salesforce if the data in the “oCallReport″ should not be inserted if there is any error occurs on “oAction″.
To overcome this issue, you can implement transaction control into your code as following:

Savepoint sp = Database.setSavepoint();
try {
  insert oCallReport;
  insert oMeetingAttendee;
  insert oAction;
} catch (Exception e) {
  Database.rollback(sp);
}

By doing this, Salesforce will helps you to revert data back to the state before the first DML insert statement is executed. But again I got one issue that salesforce.com sets the ID of a record before the insert as you can’t set values after inserts as the object would become read-only. To overcome this issue I have created clone the record without preserving the Id and assign this clone back to the original object .Something like this:

Savepoint sp = Database.setSavepoint();
try{                        
insert oCallReport;
  insert oMeetingAttendee;
 insert oAction;
}catch(exception e){
                Database.rollback(sp);
              oCallReport = oCallReport.clone(false);
                return null;                        
}

The false parameter in the clone method makes an exact copy of the object without preserving the Id. So the next time the user attempts to save, the Id is null, and there should be no issues.