Andy in the Cloud

From BBC Basic to Force.com and beyond…


Leave a comment

Doing more work with the Unit Of Work

In a previous post I introduced the Unit Of Work class, which is part of the Apex Enterprise Patterns series. As the original post describes it helps you simplify your code when it comes to performing multiple DML statements over related objects, as well as providing a bulkification and transaction management. In this post i would like to share information on a new feature that adds some extensibility to the fflib_SObjectUnitOfWork class.

This new feature addresses use cases where the work you want it to do, does not fit with the use of the existing registerDirty, registerNew or registerDeleted methods. But you do want that work to only be performed during the commitWork method, along with other registered work and within thesame transaction it manages.

Some examples of such situations are…

  • Sending Emails
    You want to register the sending an email once the work has completed and have that email only be sent if the entire unit of work completes.
  • Upsert
    You want to perform an upsert operation along with other insert, update and delete operations performed by the existing functionality.
  • Database class methods
    You want to utilise the Database class methods for additional functionality and/or granularity on some database operations, e.g. emptyRecycleBin, convertToLead, or perform an insert with allOrNothing set to false.
  • Self referencing objects
    You want to perform DML work relating to self referencing objects, something which is currently not supported by the registerNew and registerRelationship methods.
  • Nested Unit Of Works
    Though generally not recommended, if you do happen to have created another fflib_SObjectUnitOfWork instance, you might want to nest another unit of work instance commitWork call with another.

In these cases the class now contains a new Apex Interface, called IDoWork, it is an incredibly simple interface!

/**
* Interface describes work to be performed during the commitWork method
**/
public interface IDoWork
{
   void doWork();
}

To use this interface you implement it and register an instance of the implementing class through the new registerWork method. When the commitWork method is called it will callback on the doWork method for each registered implementations once it has completed the work given to it by the existing methods. In other words after all the DML on the dirty, new or deleted records have been processed.

A SendEmailWork implementation of this interface actually resides internally within the fflib_SObjectUnitOfWork class and is used to support another new method called, registerEmail. I added this to experiment with the feature during development but felt its worth leaving in as an added bonus feature if your writing code thats doing DML and sending emails!

The following example integrates the upsert method on the Database class (which needs a concreate SObject list), but you can really do anything you want in the doWork method!

	public class UpsertUnitOfWorkHelper implements fflib_SObjectUnitOfWork.IDoWork
	{ 		
		public Database.UpsertResult[] Results {get; private set;}
		
		private List<Account> m_records;
		
		public UpsertUnitOfWorkHelper()
		{  
			m_records = new List<Account>();
		}
		
		public void registerAccountUpsert(Account record)
		{
			m_records.add(record);
		}
		
		public void doWork()
		{
			Results = Database.upsert(m_records, false);				
		}
	}

The following is an example of this in use…

		// Create Unit Of Work as normal
		fflib_SObjectUnitOfWork uow =
			new fflib_SObjectUnitOfWork( 
				new Schema.SObjectType[] { 
					Product2.SObjectType, 
					PricebookEntry.SObjectType, 
					Opportunity.SObjectType, 
					OpportunityLineItem.SObjectType });
		
		// Register some custom work
		UpsertUnitOfWorkHelper myUpsertWork = new UpsertUnitOfWorkHelper();
		uow.registerWork(myUpsertWork);
				
		// Do standard work via...		
		
		// uow.registerNew(...)
		
		// uow.registerDeleted(...)
		
		// uow.registerDirty(...)
		
		// Register some custom work via...
		myUpsertWork.registerAccountUpsert(myAccountRecordToUpsert);
		
		// Commit work as normal
		uow.commitWork();
		
		// Optionally, determine the results of the custom work...
		List<Database.UpsertResult> myUpsertResults = myUpsertWork.Results;		

In summary, the unit of work helps co-ordinate many things we do that in essence are part of a transaction of work we want to happen as a single unit. This enhancement helps integrate other “work” items your code might have been performing outside the unit of work into that single unit of work and transaction. It also helps bridge some gaps in the unit of work that exist today such as self referencing objects.

Please let me know your thoughts on this new feature and how you see yourself using it!


4 Comments

FinancialForce Apex Common Updates

This blog starts a series of updates leading up to Dreamforce 2014, where I am pleased to announce that my Advanced Apex Enterprise Patterns session has just been selected! In the coming series of blogs I will be covering enhancements to the existing base classes supporting the Apex Enterprise Patterns and highlighting some of the more general classes from within the FinancialForce Apex Common repository both reside in.

This time I will be highlighting some excellent contributions from fellow Force.com MVP Chris Peterson who has recently added more general utility classes to support security and dynamic queries. As well as some improvements from myself to the existing Domain and Selector classes.

In a following blog I’ll be going over in more detail the current results of some experimental work I’ve been doing relating to generic Field Level Security enforcement within the patterns base classes, meanwhile enjoy the new fflib_SecurityUtils class..

New fflib_SecurityUtils.cls

SecurityUtilsThe Salesforce Security Review currently requires that both object level and field level security is enforced by your code. The later of which, field level security has recently stirred up quite a lot of discussion and concern in the ISV community, more on this in the follow up blog post! In the meantime if you read the two Salesforce articles (here and here) describing the requirement and how to implement it in your Apex code (Visualforce offers some built in support for you). If like me, you’ll quickly realise the sample code provided is in reality somewhat verbose for anything more than a single object or field usage!

Enter the fflib_SecurityUtils class! As you can see from the UML representation shown here it’s methods are pretty simple and thus easy to use, an Apex exception is thrown if the user does not have access to the given object and/or fields. Here are some examples of it in use, you can choose to check individually or in bulk a set of fields and the object, covering both CRUD and Field Level Security.


fflib_SecurityUtils.checkObjectIsInsertable(Account.SObjectType);

fflib_SecurityUtils.checkInsert(
   Account.SObjectType,
   new List<Schema.SObjectField>{
      Account.Name,
      Account.ParentId, } );

fflib_SecurityUtils.checkUpdate(
   Lead.SObjectType,
   new List<Schema.SObjectField>{
     Lead.LastName,
     Lead.FirstName,
     Lead.Company } );

This class will also help perform object and field read access checks before making SOQL queries, though you may want to check out the features of the QueryFactory class as it also leverages this utility class internally.

New fflib_QueryFactory.cls

QueryFactory

The key purpose of this class is to make building dynamic SOQL queries safer and more robust than traditional string concatenation or String.format approaches. It also has an option to automatically check read security for the objects and fields given to it.

If your using Fieldsets in your Visualforce pages you’ll know that it’s generally up to you to query these fields, as you can see from the UML diagram, the class supports methods that allow you to provide the Fieldset name and have it automatically include those fields for you in the resulting query.

 

Chris has done an amazing job with this class not only in its feature and function but in its API design, leveraging the fluent model to make coding with it easy to use but also easy to read and understand. He first presented in at the FinancialForce DevTalks event this month, his presentation can be found here. In the presentation he gives some examples and discusses when you should use it and when not. So if your writing code like this currently…

String soql = ‘SELECT ‘;
for(Integer i = 0; i< fieldList.size(); i++){
  soql += fieldList + ‘, ‘;
}
soql = soql.substring(0,soql.length()-2);
soql += conditions != null && conditions.trim().size() > 0 ?  ‘ WHERE ‘ +
    soqlConditions : ‘’;
soql += limit != null && limit.trim().size() > 0 ? ‘ LIMIT ‘+limit;
List<Contact> nonBobs = Database.query(soql);

In it’s simplest form it’s use looks like this..

String soql =
  new fflib_QueryFactory(Contact.SObjectType)
    .selectField(Contact.Name)
    .setLimit(5)
    .toSOQL();

With object and field read security enforcement and Fieldset support would look like this…

String soql =
  new fflib_QueryFactory(Contact.SObjectType)
    .assertIsAccessible().
    .setEnforceFLS(true).
    .selectFields(myFields)
    .selectFieldSet(Contact.fieldSets.ContactPageFieldSet)
    .setCondition(‘Name != “Bob”’)
    .toSOQL();

The class is fully commented and the associated test class has further examples, also Chris is keen to work on API for the SOQL where clause in the future, i look forward to seeing it!

fflib_SObjectSelector.cls (Selector Pattern) Updates

I have updated this base class used to support the Selector pattern, to leverage the fflib_QueryFactory, in doing so you now have the option (as a constructor argument) to enable Field Level Security for fields selected by the selector. The default constructor and prior constructors are still supported, with the addition of the following that now allows you to control Fieldset, object and field level security enforcement respectively. For example…

OpportunitiesSelector oppsSelector =
    new OpportunitiesSelector(includeFieldSetFields, enforceObjectSecurity, enforceFLS);

NOTE: You can of course implement your own Selector default constructor and enable/disable these features by default within that, if you find yourself constantly passing a certain combination of these configurations parameters.

For custom selector methods you can leverage a QueryFactory constructed and initialised based on the Selector information, leaving you to add the additional where clause for the particular query logic the method encapsulates. Because of this you no longer need to add assertIsAccessible as the first line of your custom Selector methods. Prior to adopting QueryFactory a custom selector method might have looked like this…

public Database.QueryLocator queryLocatorReadyToInvoice()
{
  assertIsAccessible();
  return Database.getQueryLocator(
     String.format('SELECT {0} FROM {1} WHERE InvoicedStatus__c = \'\'Ready\'\' ORDER BY {2}',
     new List<String>{getFieldListString(),getSObjectName(),getOrderBy()}));
}

The updated patterns sample applications OpportunitiesSelector example to use the new newQueryFactory base class method, because this method pre-configures the factory with the selector object, fields, order by and fieldsets (if enabled), the new implementation is simplified and more focused on the criteria of the query the method encapsulates.

public Database.QueryLocator queryLocatorReadyToInvoice()
{
  return Database.getQueryLocator(
    newQueryFactory().setCondition('InvoicedStatus__c = \'\'Ready\'\'').toSOQL());
}

This updated fflib_SObjectSelector base class is backwards compatible from the API perspective, so you can choose to continue with the original String.format approach or adopt the newQueryFactory method accordingly. You can further review the old example here, against the new one here.

fflib_SObjectDomain.cls (Domain Pattern) Updates

This base class has to date had minimal functionality in it other than the routing of trigger events to the applicable virtual methods and object security enforcement. To support better configuration of these features and those in the future, i have added a new Domain class configuration feature, accessed via a new Configuration property.

Despite the focus on enforcing security in the above new features and updates, there are times when you want to enforce this in the calling code and not globally. For this reason the base class can now be configured to disable the object security checking (by default performed during the trigger after event), leaving it up to the calling code to enforce. Methods accessed from the new Configuration property can be used to control this.

public class ApplicationLogs extends fflib_SObjectDomain
{
  public ApplicationLogs(List<ApplicationLog__c> records)
  {
    super(records);
    Configuration.disableTriggerCRUDSecurity();
  }
}

Domain Trigger State

I have also been asked to provide a means to maintain member variable state between invocation of the trigger handler methods. Currently if you define a member variable in your Domain class it is reset between the before and after trigger phases. This is due to the default trigger handler recreating your Domain class instance each time.

If you want to retain information or records queried in the before handler methods in your class member variables such that it can be reused in the after handler methods, you can now enable this feature using the following configuration. The following illustrates the behaviour.

public class Opportunties extends fflib_SObjectDomain
{
  public String someState;

  public TestSObjectStatefulDomain(List<Opportunity> sObjectList)
  {
    super(sObjectList);
    Configuration.enableTriggerState();
  }

  public override void onBeforeInsert()
  {
    System.assertEquals(null, someState);
    someState = 'Something';
  }

  public override void onAfterInsert()
  {
    System.assertEquals('Something', someState);
  }
}

This feature is also aware of trigger recursion, meaning if there is such a scenario a new Domain class instance is created (since the records it wraps are new).


14 Comments

More power to your Flows in Summer’14

Since an earlier blog post describing how to hookup a Flow to a Custom Button, I have been promoting this #clicksnotcode platform feature further at my local DUG and recently the Salesforce1 World Tour London and internally within FinancialForce, the response has been great.

I have also been working on some new use cases showing the use of Flow from Workflow which is capability in pilot for Spring’14. Then before i knew it I had i had found even more new Flow features in my hands delivered via the upcoming Summer’14 release! You can read all about these features in the excellent Visual Workflow Implementation Guide. This blog provides step by step guide as to how I’ve explored these new features and a summary of their current and general availability. Note: The Flow Trigger functionality looks to remain in Pilot beyond Summer’14.

Flow SObject Collections Summer’14 (GA)

NewElements

Lets take a look at two new Resource types in Flow and how they work in conjunction with four new Data elements, known as Fast Create, Fast Read, Fast Update and Fast Delete. With these new elements you can drag them onto the Flow canvas as with the previous ones. The difference is these allow you to basically manage multiple records at once, or in bulk to use Apex term.

NewVariables

The Fast prefix comes from a reflection on what you would have to have done in the past to manipulate several records of the same object. The previous alternative was to create your own loop around the existing Create element creating a single record at time. Which in general is much slower and gives greater rise to hitting platform governors around the number of database operations that can be performed in a single Flow execution. Flow is grow up for greater volumes!

EnterAmountTo illustrate these new features i decide to implement in Flow something i have previously written using Apex code. The following use case is to Apply a user entered discount to selected Quote Line Items from the Related list. The flow will prompt the user for the Discount amount and they apply it, before returning the user back to the Quote detail page.

ApplyDiscount

Here is the high level steps i took to achieve this.

  1. Created a Flow that exposes an Input only variable of type SObject Collection and used by the new  Loop and Fast Update elements to perform the calculations and update the rows passed in.
  2. Created a Visualforce page (no Apex required) that uses the standard platform Selected field to pass in the users selected records (from a List View or Related List). This was a little more Visualforce than i wanted personally, but is still a pretty good template for other use cases with minimal changes required.
  3. Created a List View Custom Button and associated it with the above Visualforce page.
  4. Edited the Quote layout to add the above button the Quote Line Items related list

 

Lets take a look at the Flow I created and then I’ll go into some more detail on the Visualforce page needed to call it. First things first is to create an SObject Collection variable of the appropriate object type, in this case QuoteLineItem.

SObjectCollection

Keep a note of the Unique Name used, it will be important when we create the Visualforce page to call this flow. The next step is to loop over the SObject (or QuoteLineItem) records and apply the discount. The new Loop element is super easy to use, it has two arrows, one for each iteration and another arrow to point to the next step once all records in the collection have been processed.

ApplyDiscountFlow

The following screenshots show the elements in more detail. The Loop element uses new SObject Variable QuoteLineItem, for each record, which allows you to operate at the field level using the existing Assignment element. I also used the existing Formula functionality in Flow to perform the discount calculation. After this i added the record to a another SObject Collection variable that i would later pass to the Fast Update method.

The Visualforce page that runs the Flow looks similar to the one i used in the previous blog to invoke a Flow from the Detail Page Custom Button. The difference is passes in multiple record from those selected by the user via the Selected binding. There is some magic above the flow:interview element that ensures the fields used by the Flow are queried by the platform, otherwise an error occurs when the Assignment steps are executed stating the UnitPrice field has not been queried (I’m open to better ways of resolving this!).

<apex:page standardController="QuoteLineItem" recordSetVar="Quotes">
    <apex:repeat value="{!Selected}" var="SelectedRow" rendered="false">
        {!SelectedRow.QuoteId}{!SelectedRow.UnitPrice}
    </apex:repeat>
    <apex:variable var="QuoteId" value="{!Selected[0].QuoteId}"/>
    <flow:interview name="ApplyDiscount" finishLocation="/{!QuoteId}">
        <apex:param name="SelectedQuoteLines" value="{!Selected}"/>
    </flow:interview>
</apex:page>

Flow Triggers via Spring’14 (Pilot)

CreateElementThe use case I chose here was one i found on IdeasExchange, it related to someone who wanted to use Workflow to create a new child record when a parent record was inserted. In this demo i create a new Task child record whenever an Account is created, this could be for example, to ensure a follow up is made on the Account. The Flow i created was insanely simple, just one Flow variable (set to Input Only) and a Create element!

RecordCreate

Once this is created in my pilot org i found a new Workflow Action, called Flow Trigger. This Workflow action allowed me to pick the Flow and define any parameters i wanted to pass in. In this case the WhatId parameter which would later be used by the Flow when populating the Task fields to associate the task with the Account being created. Finally (not shown) i linked this new Workflow Action with a Workflow Rule to try it out.

FlowTriggers
FlowTriggerEdit

Any that was it! I created a new Account and sure enough my new Task appeared, no Apex code in sight!

TaskChild

Some thoughts and observations…

  • No UI Flows. Flow’s used in this context cannot use any Screen elements, and are thus known sometimes as “Headless” flows. The platform will automatically validate for this and prevent you assigning a UI Flow to a Flow Trigger.
  • Bulkification of Flow Triggers or not? Normally when doing things at a record level Apex developers have it drummed into them to think about bulk or multiple record situations (for example Data Loader use cases) not just a single record at a time. However you will notice this was not the case above? I did expect the new SObject Collection to take a role here but not so. What Salesforce attempts to do is internally bulk insert Tasks for you by running your Flow in parallel and synchronising the executions at the time they all need to insert a record to ensure it’s done optimally. This is cleverly transparent from the Flow designer and i think intentionally so, as it is quite an advanced topic for the target user of Flow. However i do wonder how well this will stand up to more complex Flow’s. No doubt why Salesforce is being so careful over how long this remains in Pilot.

When are these features available (Safe Harbour)?

FlowRoadmap


7 Comments

MavensMate Templates and Apex Enterprise Patterns

mavensmateI’ve been using MavensMate as alternative IDE for coding on Force.com for the past 6 months and loving it more and more to be honest, it receives a strong stream of updates, feels modern, responsive (as much as the underlying platform API’s permit) and is light weight. I’m also getting to grips with the power of the Sublime Text editor (which hosts MavensMate) and it’s excellent find and replace tools for example.  Recently i’ve been working on a feature with the help of the author of this fantastic tool Joe Ferraro.

One of the cool social features of MavensMate is it’s template engine, when ever you create a Apex class, Apex trigger, Visualforce Page or Visualforce Component, you can elect to start editing from scratch or pick one of a growing number of templates, ranging from Batch Apex, Controllers, Schedulers to Unit test templates, including a new one from a new friend in the push for BDD on Force.com, Paul Hardaker (also a FinancialForce.com employee btw). The whole thing is driven by a GitHub repository, if you contribute to that repository (and your pull request is merged) your template is instantly live across the world! Now that’s a social IDE!

I set about developing templates for the Apex Enterprise Patterns and quickly bumped into a gotcha! The previous template engine only took one parameter, the name of the Metadata component (Apex class or trigger name for example). When creating Domain classes or Selectors, the name of the class and the underlying custom object is required. After a quick Twitter conversation and GitHub issue, Joe had already nailed the design for a new feature to fix this situation! You can read more about how to use it here.

DomainTemplate

I’m pleased to report it worked like a charm the first time, great design and very flexible! The templates have now been submitted and successfully merged by Joe into the repository and are now live and ready to use!

  • DomainClass
  • DomainTrigger
  • SelectorClass
  • ServiceClass

The follow screenshot shows the template selection prompt, just start typing and it narrows the options down as you go, press enter and you are prompted for the template parameters. These parameters default to examples defined in the template configuration file, overwrite these with your own following the examples as a naming convention guide. Press enter again and MavensMate will create your class and present it back to you ready for you to start editing!

NewClassTemplateParametersInvoices

If you want to see a quick from zero to Domain class demo check out my demo video below. Thanks again Joe for such a great community tool and providing great support for it!


Leave a comment

Account Hierarchy Rollups #ClicksNotCode

clicksnotcodeinthesunThe Declarative Lookup Rollup Summary Tool is holding up to quite an onslaught of requirements at the moment. When this one came in, i thought it may have met its match! However it has taken just less than a day in the Spanish sunshine to get my head round it and work with the poster to find a solution!

Use Case: Rollup a Count of Contacts to the related Account (which is pretty straight forward rollup for the tool), but then within the Account hierarchy rollup a Sum of Account Contacts at each level, so each Account shows the total Contacts for itself and all its child Accounts. The Number of Contacts (Inclusive) field shown below shows the Contact count rolled up at each level in the Account hierarchy. Burlington Textiles is the root account in this case.

accountrollups
accounthierarchy

Having realised it is a solution to the general requirement for Account Hierarchy Rollups (or in fact any Custom Object hierarchy type relationship) i thought i would share how it was eventually achieved in true “clicks not code” style! Note that while we are rolling up Contacts per Account here, this could effectively be any numeric field on Account.

First you will need to install the Declarative Lookup Rollup Summary tool from the latest package install link here. Then in the case of Account create the following Custom Field‘s.

accountfields

  • Number of Contacts,
    Results of a Count rollup of the number of Contacts associated with an Account.
  • Number of Child Contacts,
    Results of a Sum rollup of the Number of Contacts on each child Account to the parent Account.
  • Number of Contacts (inclusive),
    Formula field that adds the above two fields together and is actually used as the Field to Aggregate when calculating the Number of Child Contacts rollup.
    numberofcontactsformula

To populate these fields we are actually using two rollups, one to count the Contacts on each Account, then another to Sum the total Contacts on each child Account to each parent Account, any numeric fields on the Accounts will work the same way. Note that both these rollups are done Realtime and that the second rollup is using the Relationship Criteria Fields feature to ensure a change made by the first rollup triggers a recalculation of the second.

rollupaccountcontacts

rollupnumberofchildcontacts

Two rollups have been used here, only because the information we wanted to rollup in the Account hierarchy was not readily available on the Account record itself. So is a more complex setup than it needs to be if your just for example rolling up an existing Account field, such as Annual Revenue. However it does show nicely how two rollups can be used and have one trigger the recalculation of the other.

Scheduled Rollups: I have yet to try this with Scheduled mode, i suspect there maybe some dependency issues in the processing of two rollups in the correct order (something the tool can be taught about in the future if this is proven to be an issue), however a single independent rollup will work just fine in Scheduled or Realtime mode.

 


Leave a comment

A Declarative Rollup Summary Tool for Force.com Lookup Relationships

I’ve recently been asked to share the motivation and vision that emerged around an open source package I’ve been developing over the last year or so. It all started with a bunch of code and an API looking for a problem to solve to be honest! Here I will take you through the journey that led to the Declarative Rollup Summary Tool being born and ended up helping to fill a 6 year old platform feature itch. Relating to the desire to roll up values between records related via standard Lookup fields and not just Master-Detail (where platform support already exists), the related Salesforce Idea has over 20k upvotes btw!

Read more at developer.salesforce.com

Figure1_rollup

Follow

Get every new post delivered to your Inbox.

Join 120 other followers