Andy in the Cloud

From BBC Basic to Force.com and beyond…


Leave a comment

Packaging and Installing Rollups

Since v2.0 of the Declarative Rollup Tool, it is now possible to use Custom Metadata to store rollup configurations. Not only does this make it easy to transfer those you have setup in Sandbox via Change Sets, you can also use Salesforce packaging to capture those you’ve created and install them over and over into other orgs, like a reusable Change Set!

InstallRollups

Create and set up your Packaging Org

To do this, you need a Developer Edition org from Salesforce, this will act as your master org for your common rollup definitions. Here you can install the rollup tool package itself as minimum. Then also create common fields or objects used by your rollups if you wish. You can also install any other packages, such as the NPSP packages. Basically prepare and test everything here as you would normally in Sandbox or Production.

DESignup

Creating your Package

Under the Setup menu navigation to Create and then Packages. Create a new Package with an appropriate name. Click Add to components, components are anything from Custom Objects, Fields, Apex Triggers and Apex Tests to the Rollup definitions themselves. As a minimum you will need to add the following components for rollups.

  • Apex Classes for the rollup/s (starting dlrs)
  • Apex Triggers for the rollup/s (starting dlrs)
  • Lookup Rollup Summary definition/s

The platform adds a few other dependent things as you can see in the screenshot below, but don’t worry about these. You should have something like this…

PackagingRollups

Tip: After creating your rollups, go to Setup and Custom Metadata, and find your rollup definition, edit it and locate the Protected checkbox, then hit Save (at present this checkbox is not shown in the custom UI for rollups). This checkbox prevents users or other admins from changing your rollup definition once installed. You also need to use the managed package route though, as described below.

Choosing Unmanaged or Managed Packages

This choice depends on if you want to manage several updates / releases to your rollups over time, adding or updating as you improve things. An umanaged package is basically like just installing a template of your rollups, once installed thats it, they are no longer linked to your package. If however you want to install updates to them and/or stop people from editing your rollups (see protected mode above), you want a managed package.

Setting a namespace for your Managed Package

If you decided you only want an unmanaged package, skip this bit. Otherwise on the Packages page, under Setup then Create. Click Edit button and follow the prompts to enter a namespace, this is a short mnemonic that describes your package, like a unique ID. Once set it cannot be changed. Next find your Package detail and click Edit, selecting the Managed checkbox on hitting Save.

Uploading your Rollup Package!

PackagesRollups

This process basically builds your installer, by actually placing a copy of what you’ve done in the AppExchange servers. All be it as a private listing. This gives you an install link to use over and over as much as you like. Install it in the sandbox and production as needed.

Click on your package and then the Upload button, give it a name and version of your choose. Be sure to select the Release mode, in most cases for this packaged content worrying about Beta vs Release mode is not a concern. Press Upload and wait.

PackageUpload.png

RollupPackageSummary

Rinse and Repeat?

Keep in mind if you went with the managed package route. You can go back to your packaging org, make some improvements, add more rollups etc, then repeat the upload process to get a new version of your package. Simply then go to any existing org with your prior release installed and upgrade.

NOTE: To ensure your rollup definitions are upgraded they must be marked as protected. If you don’t care about this and only want new rollups to be added, retaining subscriber (installed org) changes, don’t worry about Protected rollups.

 

 


1 Comment

Apex Sharing and applying to Apex Enterprise Patterns

Apex Sharing can be a bit of mystery to new developers as well as seasoned ones from other platforms. This blog is not for those wanting to understand sharing as such, there are plenty of excellent articles and Salesforce docs on that. Here i wanted to talk about how first I came to understand it and how it fits into Apex Enterprise Patterns.

I recall one really basic thing that took me by surprise was the name, Sharing? Of course this is an end user based way of describing what as an engineer, I effectively understood as row level security. I was also blown away to know that this applied in and outside of code, for example when reporting is used, very cool! Row level security is certainly for me a more accurate way to describe it and certainly helps when i have been talking to others new to the platform but have experience on other platforms.

The second thing that i learn is that in order to control it, it is required to be considered in the way one annotates code at design time. And less so about a default runtime or a configured at runtime context. Since sharing is not enabled by default in Apex (except for Anonymous Apex contexts), it needs to be enabled via opt-in by the developer. Salesforce helps remind us of this through tools like the Salesforce Security Scanner and best practices here, well worth a read.

You may have noticed that the Apex Enterprise Patterns classes providing implementations of your Service layer always have with sharing specified. This sets the default context for all code, in the Domain, Selector or other classes that are executed from then on to run in this mode. Such classes do not need to and should not generally need to qualify any with sharing or without sharing keywords either.

global with sharing class OpportunitiesService 
{		
	global static void applyDiscounts(<ID> opportunityIds, Decimal discountPercentage)
	{
		// This code and any it calls runs as 'with sharing'
	}
}

So what happens if you really want to run without sharing (great article here on reasons for this)? Do you apply it to your Domain or Selector class definition? Well actually neither, since not all the code in these classes may warrant sharing being disabled for example. What i prefer to do is keep the execution of running in this mode as short and contained as possible, to avoid any other inadvertent execution of other code running in this mode.

The basic approach is to leverage an inner class that contains just the code that needs to run without sharing. Typically this code would run in the Selector layer, though can be used elsewhere inside a service method implementation or domain class method. The point is its scoped to a method or specific execution path.

public class OpportunitiesSelector extends fflib_SObjectSelector
{
    public List<Opportunity> selectById(Set<Id> idSet) {
        // This method simply runs in the sharing context of the caller
        // ...
        return opportunities;
    }

    public List<OpportunityInfo> selectOpportunityInfo(Set<Id> idSet) {	
        // Explicitly run the query in a 'without sharing' context
        return new SelectOpportunityInfo().selectOpportunityInfo(this, idSet);
    }

    private without sharing class SelectOpportunityInfo {
        public List<OpportunitiesSelector.OpportunityInfo> 
                 selectOpportunityInfo(OpportunitiesSelector selector, Set<Id> idSet) {
            // Execute the query as normal
            // ...
           return opportunityInfos;				
        }
    }
}

So do we still need it specify with sharing elsewhere? Well yes, controllers for sure is still good practice, indeed Selectors can end up being called from these. I personally also consider any class that is invoked as an Apex entry point, such as Invocable Methods, Batch Apex, Scheduled Apex etc in this category.

If your following a service orientated design most of these entry points delegate to the Service layer, so it feels like your doubling up at times, but thats no bad thing when security is concerned. Finally keep in mind, if you choose to expose your Service layer as an API, it feels equally important to ensure the default sharing mode is enabled regardless of what mode the caller is running in.

The general approach here, is enable sharing, then make the code, developer and business/solution analyst justify why it needs to be switched off for a system level operation that requires it. If you put aside the Apex Enterprise Patterns, this is in fact not that different from the general guideline of having with sharing on all your controllers, the main difference here is by putting it on your service layer, your ensuring not just your controller entry points are covered.

 


13 Comments

Visual Flow with List View and Related List Buttons

Last years blog Clicks not Code with Visual Flow Custom Buttons has continued to be quite well received, so i thought i would explore what more could be done and address a few questions that have come up since. This blog does make some assumptions that you are already familiar with the approach from my previous blog.

This time i want to focus on using Visual Flows with list Custom Buttons, such buttons can be placed on List View layouts and Related List sections on Detail layouts. Salesforce also provides a means for the user to select specific records to process. These buttons apply to both Salesforce Classic and Salesforce Lighting Experience.

AccountFlowListView

As before we are keeping in the spirit of Clicks not Code, well with a little bit of reusable Visualforce code. But don’t worry you can easily copy and paste to adapt with a few changes. Critically with this approach you don’t need to resort to JavaScript based Custom Buttons, which will no longer be supported in Lighting Experience.

Handling Record Lists from Custom Buttons

First things first, ensure you have created a SObjectCollection variable in your Flow and ensured its designated as Input. For this blog we are simply going to display a step in the UI for each selected record. Using the Loop and Screen elements. One thing to keep track of is the fields your referencing within the Flow, in this case i’m using Account Name and Annual Amount.

SelectedAccountsFlow

List View Custom Button Example

Lets get started with a Custom Button on the Account List View. When adding a List Custom Button you have two choices, do you want the user to be able to select records or not? If not, then your button will pass all the records in the List View (currently limited to 2000).

So if when creating your Custom Button you plan to select the Display Checkboxes (for Multi-Record Selection) option. Then create the following Visualforce page, changing the object name and list of fields accordingly. This will ensure selected records are passed to your Flow.

<apex:page standardController="Account" tabStyle="Account" recordSetVar="AllAccounts" >
    <!-- Add below each field you reference in your Flow -->    
    <apex:repeat value="{!AllAccounts}" var="row" rendered="false">
        {!row.Name}
        {!row.AnnualRevenue}
    </apex:repeat>
    <!-- Runs your Flow -->    
    <flow:interview name="SelectedAccounts" 
          finishLocation="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">
        <apex:param name="SelectedRows" value="{!Selected}"/>
    </flow:interview>
</apex:page>

IMPLEMENTATION NOTE: If you want to avoid bothering with changes between lines 3-6, simply re-query the records in the Flow using the Fast Lookup element. Thought it’s less efficient this way since your not leveraging the query made by Visualforce.

If you don’t want the ability for the users to select records and want all records, the main difference to the above is a change to the line 10, passing in the AllAccounts binding.

    <!-- Runs your Flow -->    
    <flow:interview name="SelectedAccounts" 
          finishLocation="{!URLFOR($Action.Account.Tab, $ObjectType.Account)}">
        <apex:param name="SelectedRows" value="{!AllAccounts}"/>
    </flow:interview>

Don’t forget to add your button to the List View layout, select some records and give it a try!

SelectedAccountRow

Related List Custom Button Example

In this case the Visualforce page is much the same, accept that of course your placing the associated button on the Layout of the parent object by editing the applicable related list section. The following example shows a button on the Opportunities related list on the Account object.

<apex:page standardController="Opportunity" tabStyle="Opportunity" recordSetVar="AllOpportunities">
    <!-- Add below each field you reference in your Flow -->
    <apex:repeat value="{!AllOpportunities}" var="row" rendered="false">
        {!row.Name}
        {!row.Amount}
    </apex:repeat>
    <!-- Runs your Flow -->
    <flow:interview name="SelectedOpportunities" 
          finishLocation="{!$CurrentPage.parameters.retURL}">
        <apex:param name="SelectedRows" value="{!Selected}"/>
    </flow:interview>    
</apex:page>

RelatedListFlowButton

IMPLEMENTATION NOTE: Note that the above Visualforce page code uses a URL parameter retURL, which is not available in Lighting Experience. It still works, but leaves the user on the finish page.

Summary

For more information on passing values to Flows using Visualforce check out the docs here. With the exception of the retURL hack above, i’m pleased to see support in Classic and Lighting Experience. Though the later, has yet to obtain support for providing the record selection support, so only the all records use case is available.

At present Visual Flow styling does not quite look at home either in Lightning Experience, which made me wonder about trying SLDS styling with Flow’s CSS customisation abilities (i will let everyone known how successful this is!)…

AccountFlowListViewLEX

FlowInLEX

Finally both these approaches will also work equally well with Automation Flows (aka Headless Flows), just in case, as with the example in my earlier blog you just want to do some kind of calculations without prompting the user.


6 Comments

Supercharging Salesforce Report Subscriptions with Apex and Flow

In the Spring’15 release Salesforce provided the ability to subscribe to reports. This is done through a new Schedule button shown below. Users can schedule reports with criteria based on the report contents. When the platform runs the report, the criteria gets evaluated and if met will result in notifications sent to the user. The usual Email and Chatter options are available, as well Mobile Notifications for Salesforce1 mobile users, pretty cool!

ReportSubscribe

It is the last notification option that caught my interest. Described simply as Execute Custom Action. This is in fact the gateway to many more possibilities, as it is essentially a peace of any Apex code. When the report is run and the criteria is met the platform will call your Apex code, a bit like an Apex Trigger but for Reports. Given the capabilities of Apex and what users can do with Salesforce Reports, thats not just pretty cool, that’s super cool!

Subscription

Once the user saves the subscription the platform creates a scheduled entry that can be seen and deleted by administrators under the All Scheduled Jobs page under Setup, classified as Reporting Notification scheduled job type. The job will then run under the user context of the user that setup the subscription. Note that each user can only setup up to 5 report subscriptions presently.

Creating a Custom Action with Apex

In order for your Apex class to appear in the above UI for selection you must implement a platform provided Apex interface. The Reports.NotificationAction Apex interface is pretty simple, with just one execute method.

public with sharing class MyReportNotification 
	implements Reports.NotificationAction {

	public void execute(Reports.NotificationActionContext context) {
	    // Context parameter contains report instance and criteria
	    Reports.ReportResults results = context.getReportInstance().getReportResults();
	    // In the above subscription case this is the 'Record Count'
	    System.debug(context.getThresholdInformation().getEvaluatedConditions()[0].getValue();
	    // You can also access the report definition!
	    System.debug(results.getReportMetadata().getName());
	}
}

If your familiar with the Analytics Apex API, you’ll soon feel quite at home with the information provided by the context parameter. The context parameter passes in an instance of the report itself, as in the records of the report. As well as a reminder of the criteria behind the subscription (as entered in the UI above) and the aggregate values that caused the criteria to be met. Also the report definition (its metadata), useful if you wanted to write a generic handler for example.

What about Clicks not Coders?

Now i love Apex coding, but i also know that this platform has not got where it has from just providing a programming language. Having a declarative means to deliver solutions rapidly with more pervasive skills is the corner stone of what makes the platform so successful. Tools like Process Builder and Visual Flow are a great example of this.

So you may think Salesforce have missed an opportunity here, by not providing a means to use for example an Autolaunched Flow as a Report subscription. I personally think so, hence i’ve raised this Idea Exchange idea here, please up vote if you agree. Meanwhile, all is not lost!  As i’ve previously blogged there is a means to invoke Flow’s from Apex. So this got me wondering if Apex could be the glue between Salesforce Report Notifications and Flow?

Here is the result of a basic experiment of calling a Flow from an Apex Report Notification…

public with sharing class MyReportNotification 
	implements Reports.NotificationAction {

	public void execute(Reports.NotificationActionContext context) {
		// Context parameter contains report instance and criteria
		Reports.ReportResults results = context.getReportInstance().getReportResults();
		// Construct some parameters to pass to the Flow
		Map<String, Object> params = new Map<String, Object>();
		params.put('ReportName', results.getReportMetadata().getName());
		params.put('RecordCount', context.getThresholdInformation().getEvaluatedConditions()[0].getValue());
		// Call the Flow with the parameters
		Flow.Interview.MyReportNotificationFlow reportNotificationFlow = 
			new Flow.Interview.MyReportNotificationFlow(params);
		reportNotificationFlow.start();		 
	}
}

Implementation Note: The only drawback so far i can see is sadly you cannot pass the whole context parameter “as is” into Flow, as its variable types are quite limited, to make this more generic you would have to be quite inventive as to how you pass information.

The following shows the Autolaunched Flow called in the above example. It’s pretty simple but achieves something the other notification options cannot which is to create Task. If you want to know more see my blog here.

ReportNotificationFlow

This results in a Task being created for the user as shown in the screenshot below. There is certainly a great potential for this type of approach, as it allows for clicks not coders to stretch their declarative skills without having to revisit the Apex code each time a new requirement or change is required.

TaskCreatedByReportFlowNotification

Running, Testing and Debugging

SubscribeSaveAndRunIf you look closely at the UI above you’ll see the button Save & Run Now. As the name suggests this will save the subscription details and run the report immediately. If the criteria is met your Apex class will be called immediately also. This is obviously pretty useful as the most granular scheduling period is on the hour.

ScheduledSubscriptionReportWhen i did schedule the subscription as normal users would. I found oddly no evidence of it in the Apex Jobs page, despite a schedule appearing on the All Scheduled Jobs page. Its pretty obvious the platform runs these async, so i would have expected some evidence of this…

During my testing i found the Debug Logs output as expected (in both execution modes above). Though an important note is any exceptions thrown got swallowed when run from the UI, so always check your debug log if things are not working as expected.

Warning Possible Platform Bug: I did find that if my Apex code threw an exception when i used the UI to run my code it deleted any prior schedules for the report subscription. I had to delete and recreate the subscription to get the schedule entry back. I’ll investigate this a bit further and raise a case with Salesforce.

Writing an Apex Test for Report Notification Actions

Writing Apex Tests for the above is little different than the usual approach, mainly owing to the fact that the Analytics API requires that Apex tests leverage the SeeAllData attribute. This is clearly less than ideal, but is indeed documented as such in the formal Salesforce documentation.

In order to emulate the platform calling your execute method, you’ll need to mock the context parameter, fortunately it seems unlike some system types the context parameter type can be constructed, nice!

@IsTest
private class MyReportNotificationTest {
	
	@IsTest(SeeAllData=true)
	private static void testMyReportNotification() {
	
		// Get an instance of the report
		Report report = [SELECT Id FROM Report WHERE DeveloperName = 'ClosedWon'];
		Test.startTest();
		Reports.ReportInstance reportInstance =
          Reports.ReportManager.runAsyncReport(report.Id, true);
		Test.stopTest();

		// Emulate the platform calling the custom action passing criteria that was met
		MyReportNotification myReportNotification = new MyReportNotification();		
		Reports.NotificationActionContext context = 
			new Reports.NotificationActionContext(
				reportInstance, 
				new Reports.ThresholdInformation( 
					new List<Reports.EvaluatedCondition> {
							/* new Reports.EvaluatedCondition(
								'RecordCount', 
								'Record Count', Double.valueOf(0), Double.valueOf(1), 
								Reports.EvaluatedConditionOperator.GREATER_THAN) */ }));
		myReportNotification.execute(context);

		// Assert accordingly...
		// ...
	}
}

Implementation Note: At time of writing, i found that i could not create a mock instance of the Reports.EvaluatedCondition type without receiving a compilation error claiming the constructor was not found (hence why its commented out). I’ll update this blog if i find out why. This issue will limit the testing of any criteria / threshold references in your code you make.

Summary

I love how Salesforce are opening up more of the platform to support Apex callbacks like this. It adds much more flexibility for developers to really extend the platform and not just solutions on top of it. In this case it also provided some flexibility for us to plug any gaps in the platforms current feature set. Salesforce please keep it up!

 

 


1 Comment

Pillars of Enterprise Development

During 2014 i authored my first full book, entitled Force.com Enterprise Development, it was a long process taking over 8 months, so certainly if your considering such a thing yourself be prepared for a big investment! The opening paragraph is as follows…

2994EN_ Salesforce1 Platform Enterprise Architecture_0Enterprise organisations have complex processes and integration requirements that typically span multiple locations around the world. They seek out the best in class applications that support their needs today and in the future. The ability to adapt an application to their practices, terminology, and integrations with other existing applications or processes is key to them. They invest as much in your application as they do in you as the vendor capable of delivering an application strategy that will grow with them.

Motivation and background to the book

The Salesforce community is diverse, consisting of package developers, in house developers and consultants, each with varying degrees of technical knowledge. While Salesforce documentation can be found to address the needs of each of these types of developers, it is often more of a reference style in nature and can be hard to contextualise. Meaning a clear path to an architecture for enterprise developers to refer can be hard to find and peace together.

I wanted the book to act as flow for all that a developer needs to get the best out of the platform while laying down a strong foundation of development practices and patterns, to allow their application to scale and evolve with the same rapid pace of the platform itself (see some examples of where this has been achieved below).  Existing enterprise Java or .Net developers considering the platform will find some well known enterprise patterns. There has been a significant increase in architecture and best practice questions over the last 2-3 years on the Salesforce forums such as StackExchange and Salesforce Community Answers.

Pillars of Enterprise Development

PillarsWhen planning the outline for the book and thinking about Enterprise development on the platform in general, i had three core beliefs in mind that i wanted to seed within the book.

  • Embrace the whole Platform, The first tenant of the Force.com platform is to combine the power of the declarative programming style with the traditional source code based programming style. Doing so ensures not only the developer is as effective as possible, focusing on coding only where needed, but also the resulting application has strong ‘native’ feel to it, giving its end users access to the platforms rich set of customization, configuration and integration capabilities that enterprise customers demand. I wanted the reader to have a key awareness of the benefits of being ‘native’ on the platform, to keep it in mind always and realize the benefits this combined development approach can be bring to end users.

  • Build Strong Foundations, Enterprise applications are expected to serve their customers for many years to come, as customers build solutions and processes around them, which become a critical part of their businesses. As applications grow in complexity the code base especially needs to not buckle under the pressure, be that the addition features or general maintenance of existing features, made by existing or new developer resources. A strong foundation will ensure that the code base endures this type of change with minimal impact on the rest of the system and the users. I wanted the reader to get a strong sense of the meaning of Separation of Concerns and how it applies to enterprise applications built on the Force.com platform.

    • Lightning Experience was obviously not around at the time and Lightning Components only in Pilot, now they are both GA, but are Services still as applicable to Lighting controllers? You bet!

  • Your Application as Platform, Enterprise customers demand high levels of integration, customization and integration from your application, as they either repurpose or consume the application within a larger business process or integration. So i wanted the reader to gain an understanding of the Force.com platform features they can leverage to ensure that these aspects are considered from an architecture perspective and thus baked into each new application function, such that the resulting application becomes in essence a part of the platform itself.

    • Lightning Process Builder was but a gleam in someones eye a year ago, but can Services be exposed via Invocable Methods to this tool? You bet!

I’m so pleased and proud to see some great reviews of the book and also some great feedback on Twitter. If your interested in taking a deeper look check out the sidebar of my blog, you can get your hands on it both digitally and in good old paper back! Enjoy!

Follow

Get every new post delivered to your Inbox.

Join 343 other followers