Search

Tuesday, 23 October 2012

Add Values To A MultiPicklist In Apex

How easy is this

Simple as this create a String which separates the individual values with a ';' and assign the picklist to this String

myobj__c.myMultiPicklist__c = 'PicklistA;PicklistB;PicklistC';
update myobj__c;

Reflection In Salesforce

Where and how can we use reflection in Salesforce, well here's a good example

Say you have 3 classes that map values from 1 object to another.

Class A matches 3 fields from Object X to ObjectY
Class B matches 5 different fields from Object X to ObjectY
Class C matches 12 fields, same fields in Class A and B + 4 other fields from Object X to ObjectY

Instead of hard coding this mapping in the code provide it as a lookup to a custom object, which will allow you to change any mappings without having to rewrite and deploy new code. Also, will allow the code to be re-used in future projects.

Custom object Mapping__c
Name
FieldMappingGroup__c

Custom object FieldMappingGroup__c
Name

Custom object FieldMappings__c
Fields
FieldMappingGroup__c
Name - not unique
SourceObject__c
SourceField__c
DestinationObject__c
DestinationField__c


Mapping__c[] listofFieldToCopy = [Select (Select id From FieldMappingGroup__c ) From  Mapping__c where Name='XXX'];

set<id> mapIDs = new set<id>();
for (Mapping__c eachmap: listofFieldToCop){
     mapIDs.add(eachmap.FieldMappingGroup__.id);
}

FieldMappings__c[]  fieldMappings = [Select FieldMappingGroup__c , Name , SourceObject__c, SourceField__c, DestinationObject__c, DestinationField__c From FieldMappings__c where Id In: mapIDs];
For(String fieldName : fieldMappings )
Object1.put(fieldname, Object2.get(fieldname));


After writing all of this I've heard that Salesforce maybe introducing Reflection so this may not be necessary arrrgggghhh

Friday, 7 September 2012

This Best Article About IT I Simply Have Ever Read

I'm not going to introduce this article other than to say if you are even remotely connected to IT, be it an engineer, programmer, analyst, project manager, any manager, and even IT Directors

http://brucefwebster.com/2008/04/15/the-wetware-crisis-the-themocline-of-truth/

Only extra thing I would say to this is, if those in charge have unrealistic information the net affect is they may as well leave the building and never come back. Why? Their job is to direct, hence the name of the their job titles, if they are given inaccurate and unrealistic information they cannot direct affectively and therefore makes their job redundant. This is no fault directly of those who direct, but of those below who supply the information, but it is their fault for breeding an environment where it is the norm to supply inaccurate and unrealistic information to them. If you were to highlight the most important but equally difficult part of a leaders job it is to foster such an environment. This is what creates great leaders.

I've formed this opinion and knowledge only from what many people have told me of their experiences and what I've read.

Saturday, 1 September 2012

Self Evolving Software

I will be launching my long awaited App on the AppExchange in about 8 weeks. Wow how time flies, it's been 2 years + since I started developing my App, Self Evolving Software or SES.


SES is simply the holy grail of software development, the ability for a computer program to understand what is required in English and hunt down functions in the codebase to fulfill a particular requirement.

Development teams commonly duplicate code because they are not aware that the same function has already been developed by another developer, this may be in the same organization or not. Every time this happens an organization loses money in costly developers time and also by unnecessarily delaying IT projects.

SES literally automates the processes of finding relevant functions from the codebase and creating the code using these functions to fulfill the business requirement.

By utilizing crowd sourcing software development in SES is a catalyst to faster, more accurate and efficient software development.

Tuesday, 12 June 2012

Multiple Users on Tasks

Multiple Users on Tasks
Assigning a Task to Multiple Users sounded great. I was looking forward to 1 user out of a Group closing a Task, so whoever got there first would be able to close the Task.

Not quite. The new amazing piece of technology by Salesforce simply creates a Task for every user in the Public Group or Role.
 
Fantastic, not quite

Sunday, 10 June 2012

Salesforce to Salesforce Attachments Documents and Tasks

Ive blogged about Salesforce to Salesforce before and how to programmatically pass records from 1 org to another, but I wanted to blog about specifically how to pass over certain records, such as Attachments and Tasks etc


        list<PartnerNetworkRecordConnection> newrecords = new list<PartnerNetworkRecordConnection>();
        List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>();
        connMap=[select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted' and ConnectionName=<<connection>> LIMIT 1] ;
Account[] acc =[Select id From Account where Name = <<account>> limit 1];
Attachment[] attaches =[Select id,IsPartnerShared,Name  From Attachment where Parentid=: acc[0].id and IsPartnerShared=false limit 1];

               if (attaches.size() > 0){
                   Set<id> newfunctions = new Set<id>();
                   for(Attachment thisattach: attaches) {
            PartnerNetworkRecordConnection newrecord = SearchFunctionUtils.addPartnerNetworkRecordConnection(connMap);
                       if (!Test.isRunningTest()){
                        newrecord.LocalRecordId = acc[0].id ;
newrecord.RelatedRecords = 'Attachment';
                        newrecords.add(newrecord);
                       }
                       newfunctions.add(thisattach.id);//Attachments to be uploaded
                   }
                   insert newrecords;
 
}

The key difference is you have to set RelatedRecords and the LocalRecordId  is not the id of the Attachment but Id of the Account. There are also other standard objects which also require to use this method, which I have found are poorly documented. The best way of identifying which objects is probably by trial and error, but the Document object is another such object.

For Tasks SendClosedTasks and SendOpenTasks properties are important.


Seefor more details
http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_partnernetworkrecordconnection.htm

Saturday, 2 June 2012

How to extract as much performance improvement as possible from unit tests

I urge everyone to start adopting the following unit testing methodology because it will save a huge amount of time in your deployments and ensure quality coding simultaneously.

Some people like Paul Battisson have done a lot of work on using Mock objects to avoid doing DMLs to create test data for your unit tests, but isn't exclusively to help in this area,but this is what I want to concentrate on.
However Pauls work at the moment doesn't help the situation where you want to test your Triggers. Testing Triggers properly should involve bulk testing of 200 record DMLs. The only problem in doing this is every time you deploy every unit test of every Trigger will run 200 record DMLs, this is of course very expensive and will slow down your deployments.
So what we need is a combinationof using Mock objects to test the bulk of your code, but to test your Triggers on first deploy we should test a full 200 record DMLs, and on subsequent deploys to just test a handful of records, say 10 records, which is less expensive and so will speed up your deployments. But with the built in ability to increase the number of DMLs whenever you need to.

It is likely that your trigger tests cumulatively account for 90% + of the DMLs that go on in all your test classes. So adddress this issue and you address the issue around deployment times being so long.

First of all look at Pauls work on Mock objects
https://github.com/pbattisson/Advanced-Force.com-Testing 


Testing Triggers by Luke Emberton and Steven Fouracre 

When deploying a trigger for the first time set a custom setting to 200,
so that up to 200 records are created in your unit test, after
deployment lower this to 10, so that future deployments are not slowed
down but the unit tests are still tested. If you are currently in an
empty sandbox, then the unit test needs to be written to populate the custom setting
with a default value of say10 to test 10 DMLs.

First step is to setup our Triggers correctly. Have a look at this article about the Trigger Pattern
 http://www.embracingthecloud.com/2010/07/08/ASimpleTriggerTemplateForSalesforce.aspx

By testing the trigger I will indirectly test the class, so
you could just test the trigger, but that is not unit testing, because
what happens if the class is called from other classes and the trigger and unit test to the trigger is
removed, there is now potentially nothing covering the class. Also I like to make it obvious where the
unit test is that tests the trigger and class.

So testing the trigger, you need to test bulk DMLs, for the class just test for 1 record. To setup the test data I use the same function to test both trigger and class, or for you classes you could use Pauls Mock objects.

The following example is to test update and deletion triggers, but can be slightly modified for inserts as well, by ensuring whatever value is entered in the CS the number of new records is created.


public static void setupData(integer createData){

cLines = <<do soql>>; //find out how many records exist in this org


if (
createData > cLines.size()){//there isnt enough records in this org, so you need to create more records
 

 for (integer i=1; i<=(createData - cLines.size()); i++){
          ……..blah blah……create any extra records required
  }
 

}
else{
//there are enough records in this org you don't need to create any more
}


}



createData tells the function how many records to setup. The code in the If statement only
creates however number of extra records are required to be created to test the trigger or class.

Of course this means you need to use @istest(SeeAllData=True)

The actual testmethod will likely be very similar for both tests for the trigger and class, except the number you are passing to
setupData()


When testing the class the integer createData is set to 1, when testing the Trigger it is taken from a custom setting ( CS ) in the org. So when you are deploying your project, the CS is set to 200 to fully test your trigger, then it is lowered to say 10, so the Trigger is still tested for bulk operations, but future deployments are not slowed down by trying to create 200 DMLs. Of course the CS can be changed whenever you like for future upgrades to your trigger.

Create a CS called Test_Triggers__c , with field Records__c.
In your trigger test

                    Test_Triggers__c testTrigs = Test_Triggers__c.getinstance(<<object name>>);
                    integer recordCreate = (Integer)((testTrigs != null) ? testTrigs.Records__c : 10);
Now pass recordCreate to setupData()

If your CS is empty it will just set it to 10, otherwise it will pass the number of records to create to setupData(), and this function will soql the number of existing records in the org and work out how many more is needed to create. So after deployment lower your CS from 200 to 10 to continue testing your triggers for bulk operations.

Efficient, easily manageable and quality testing by Luke Emberton and Steven Fouracre
Enjoy!