Thursday, 19 July 2018

How to run future method in test class


We have to use future method inside the  startTest/stopTest:

Test.startTest();
myClass.futuremethod( someID );
Test.stopTest();

Test.stopTest() does not return until your future method has completed.

Tuesday, 17 July 2018


Customize error message for trigger and display error message below the field

This Post demonstrates how to display error message in particular field level.

SObject SomeRecord;
SomeRecord.SomeField__c.addError('Custom Message');
//or
SomeRecord.someField__c.addError(someException);

Note:

We cannot add it to a field dynamically. This error mapping can only be done with a hard-coded field.


List has no rows for assignment to SObject  error

 Consider following query:
   
      id p;
      user u = [SELECT Id from user where Name = :username];
      if (u != null)
      p = u.Id;

  •  The above code will fail if there is no user record with the matching username. It doesn't actually return a null.


 It would be safer to do the following:

    id p;
     user[] userlist = [SELECT Id from user where Name = :username];
     if (userlist.size() > 0)
       p = userlist[0].Id;

Monday, 16 July 2018


Trigger for Adding and removing User to Permission set based on User roles


trigger AssignPermissionSet on User (after insert,after Update) {
    PermissionSet pereset = [SELECT Id FROM PermissionSet WHERE Label ='SBU Impact Visible'];
    Set<ID> addIds = new Set<Id>(),
            removeIds = new Set<Id>(),
            roleIds = new Map<Id, UserRole>([
        SELECT  Id FROM UserRole
        WHERE   Name LIKE '%E&C%' OR Name LIKE '%Commerical Ops%' OR Name LIKE '%Energy & Chemicals%' OR Name LIKE '%All Fluor%'
    ]).keySet();
    for(User record: Trigger.new) {
        (record.IsActive && roleIds.contains(record.UserRoleId)? addIds: removeIds).add(record.Id);
    }
   
    PermissionSetAssignment[] permissionSetList = new PermissionSetAssignment[0];
    addIds.removeAll(new Map<Id, AggregateResult>([SELECT AssigneeId Id FROM PermissionSetAssignment
       WHERE AssigneeId = :addIds AND PermissionSetId = :pereset.Id GROUP BY AssigneeId]).keySet());
   
    for(Id userId: addIds) {
        permissionSetList.add(new PermissionSetAssignment(PermissionSetId = pereset.id, AssigneeId = userId));
    }
    upsert permissionSetList;
    delete [SELECT Id FROM PermissionSetAssignment WHERE AssigneeId = :removeIds AND PermissionSetId = :pereset.Id];
}

Friday, 6 July 2018

                            PermissionSetAssignment:



  • Use the PermissionSetAssignment object to query permission set assignments to find out which permission sets are assigned to which users.
  • Each user may be assigned to many permission sets and each permission set may be assigned to many users.
  • Each PermissionSetAssignment ID represents the association of a single user and single permission set.

For example, to search for all of the permission sets assigned to a particular user:

SELECT Id, PermissionSetId
FROM PermissionSetAssignment
WHERE AssigneeId = '005600000017cKt'

To search for all users assigned to a particular permission set:

SELECT Id, AssigneeId
FROM PermissionSetAssignment
WHERE PermissionSetId = '0PS30000000000e'

Note:

You can also create a new permission set assignment, or use delete to remove a permission set that's assigned to a user. To update an assignment, delete an existing assignment and insert a new one.

Possible Errors:



Solution:

When assigning a permission set, if the PermissionSet ​ has a UserLicenseId, its UserLicenseId and the Profile ​UserLicenseId must match.


If Permission set is already present for user.Following Error will occur.




Wednesday, 23 May 2018

   DML Statement in 'after trigger' and not in 'before trigger'?


According to document, first Before trigger fire and then after trigger fire.In between of these events all the records saved to database but doesn't committed yet
  • Before insert event
  • Data committed to database
  • After insert event

Means when you use before insert operation records are not committed to database so If we change the trigger context record's value then we don't need perform DML (This is Id is not generated because it is not committed to database)

  • Once it is committed to database means the record Id is generated and your trigger records in read only mode you can't update the values now(because it is committed to database).That's why we need to perform extra DML for updating records.


Note: If in after event if any error occurs then complete DML operation rollback.

Best way if you want to update the same record in trigger then always go with before event. This way you can skip the extra DML.

Wednesday, 14 March 2018

       System.ListException: Duplicate id in list: 001XXXXXXXXXXXX

Lists can hold duplicate values, but if it contains duplicate sobject IDs and you try to update you'll get the error.

Solution:

1. Create a map of  <id,sobject>
2. Convert the list to Map so that the duplicate IDs are removed.
3. Update the values part of the Map.

Sample code :

// pick up any id from your salesforce org, in this sample it is account id.
id aid = '0017F000002WkkdQAC';

list <account> al = new list <account>();

for(account a : [select id from account where id ='0017F000002WkkdQAC']){
account acc = new account(id = aid);
    al.add(a);
    al.add(acc);
}
//create a map that will hold the values of the list
map<id,account> accmap = new map<id,account>();

//put all the values from the list to map.
accmap.putall(al);
if(accmap.size()>0){
update accmap.values();
}