Total Pageviews

Tuesday, September 29, 2015

What is Apttus?

If you google "What is Apttus"?
The first result you get says:-

Apttus is one of the fastest growing Silicon Valley technology companies. Apttus provides Cloud Computing solutions that encompass Quote-to-Cash and Procure-to-Pay solutions to the Global 500 and mid-market marketplace. Apttus is salesforce.com's leading native Salesforce1 application partner.

Though its good to know about background of Apttus , we the developers are more interested in the solutions/products provided by Apttus.
The major solution catered by Apttus is the comprehensive solution for :-
  Quote - to- Cash

Going by the online documentation provided by Apttus  its - The only choice to intelligently configure, price and quote new deals, add-on sales and renewals – all inside Salesforce.

So far so good, but you as a developer are inquisitive to know more about this product . What are challenges which one will encounter while suggesting it as a solution? What are the user cases which are deemed fit to adopt Apttus (QTC) as a solution?
What is the Quote -to-Cash journey?
It is essentially all the activities right from:-
a. cold calling / hot calling
b. lead management / opportunity management
c. suggesting products and services to the prospective customers
d. getting all approvals for the solution/ product combination suggested
e. generating contracts, doing the redlining of the contract, maintaining version of different contracts
f. renewals / amendments / termination , etc.

For clarity please refer to the diagram below:-


Apttus provides a suite of solutions which is 100% native to salesforce for automating the full quote to cash journey.
If most of the "Pre-Sales processes" and "Sales Processes" are carried out in salesforce you can consider using Apttus for CPQ and Contract management.
One needs to install the requisite "Managed Packages" provided by Apttus to have the solution up and running in your salesforce orgs.
The main packages which you might need to install are shown in the diagram below:-

I will talk about the basic features provided by them in a follow-up blog.
Functionally Apttus solution can be compartmentalized into the following divisions:-



We will cover each of these segments in days to come, keep watching this space for more.



Saturday, September 26, 2015

Why is Apttus stealing the march over Zuora?

Salesforce is a vibrant platform which caters to most of the housekeeping activities of any standard business.
Those activities/ processes may be :-
  • Pre Sales / Marketing
  •  Sales
  •  After Sales Service / Support
  •  Knowledge Base Management
  •  Website for popularizing products or taking information about product & services to potential clients



Having said that one realizes that there is no OOB (Out of Box) CPQ module or Configure - Price - Quote Module in salesforce.


What is CPQ?
CPQ, or Configure Price Quote Software is a sales tool or a set of tools designed to help companies produce accurate and highly configured quotes making all of the complex product, pricing, and business rules centralized, automatic and available in real-time, so that sales has all the information they need while making sales handy.
Since Salesforce doesn’t provide a module / tools dedicated for CPQ, what are the options. Some of the options are:-
1.  One can build a CPQ solution using some custom objects and other customization ( which no wonder is a cumbersome process)
2.   The other option is to leverage the existing CPQ solutions.
       i.  Some are on premise systems hence perhaps not the best choice
       ii.  Others are on the cloud but integration between the different cloud ecosystems is sometimes not that easy. Remember why salesforce is such a hit because of the ease with which one can learn the platform nitty-gritties and develop solution. Unfortunately many of the earlier cloud based CPQ solution have very cumbersome API based integrations, which at times might not be so easy to grasp.
In the IInd category let’s take the example of Zuora which is a cloud based CPQ solution (among other solutions like billing engine) and an ideal candidate for adoption in the cloud eco-system.
So what is Zuora?
Zuora for Salesforce lets one sell and nurture subscriptions without breaking one’s sales and customer care processes.
Zuora for Salesforce provides two native Force.com applications:
·         Quotes to enable direct assisted sales of your subscription offerings
·          360 Sync to provide full visibility in Salesforce into key Subscriber activity and into opportunities that exist to foster deeper subscriber relationships
Despite being fully on cloud one gets a sense that implementing Zuora at times poses some challenges.
i.                     The API at times is not very well documented for a new developer to implement, also unlike salesforce the training resources are not freely available.
ii.                   Also one should be a partner to get a Zuora org/ instance; hence one cannot easily play around with it.
iii.                  The fact that Accounts and some other associated data reside both in salesforce and Zuora give a semblance of data duplication though the 360 sync ensures that both the copies always reflect the same information.
iv.                 The fact that despite both environments being on cloud the fact that the cloud are different and need some kind of hand-shake for the information to flow also brings in some complexity thus impeding adoption.

What is APPTUS CPQ?
As per online Apttus resources- Apttus Configure Price Quote (CPQ) is the choice for Salesforce to intelligently configure price and quote new deals, add-on sales and renewals — all inside Salesforce.
The following screenshot further clarifies what Apttus stands for.



In simple words Apttus is a force.com product built on force.com platform or one can say that its native to salesforce.  Now what does it imply , it means objects like Accounts, contacts , quote won’t be duplicated or in other words in Salesforce and Apttus CPQ there will be only one instance of such objects unlike Zuora.

The Native VS Composite App debate

 Hence despite sharing some of the similar difficulties with Zuora ( from a developer/ implementer point of view) like:-
1. Documentation / Resources not freely available like salesforce.
2. The product cannot be tried by developers in general unless one is a partner 
APTTUS is having fairly good adoption rate in the Salesforce –CPQ space due to being native to salesforce.
                         


Monday, July 6, 2015

Integration Design patterns in Salesforce

Has this been your reaction when trying to navigate your path around design patterns especially when it involves patterns governing integration !! Well to be  honest technical jargon always gets to my nerves , but after the initial jerky reaction I always take it upon me to demystify / simplify it.

So what are "Design Patterns"? 
As per Wikipedia -   design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. 

In layman's language - its a solution approach one should adopt for a certain category of recurring problem statement. For example one has to come up with a "Contingency plan for a natural disaster" what would be the main steps to formulate a strategy?
1. Evaluate the vulnerability of the area under inspection
2. Find the steps to reduce damage and vulnerability
                  3. What would be the precaution each can take.
                  4. Have an advance warning system if possible.
                  5. Formulate a relief and rescue strategy

So be it a earthquake/ floods or any other natural calamity the basic steps will follow above pattern.

What are the main types of design patterns?

  • Algorithm strategy patterns
  • Computational design patterns
  • Execution patterns 
  • Implementation strategy patterns
Another school of thought goes by the following classification:-
  • Creational Design Pattern
  • Structural Design Pattern
  • Behavioral Design Pattern 


 Lets leave the general design pattern and dive into design patterns associated with SFDC Integration.




Broadly all integration design pattern are classified into:-
1. Data - These service the need for taking or synchronizing data from one system to another. Mostly the purpose of these integration is to see that both system have meaningful data. These type of integration are supposed to be the simplest.
2. Process - Here the two different system target and source communicate to service a business process related requirement.These might require complex design and implementation and involve multiple systems, where the one invoking the other systems may be the controller while other act like members of an orchestra .

There are certain things which need to be considered while embarking over a type of design pattern. the main considerations are:-

1. Source / Target systems

2.Type of integration (Data/ Process)

3.. Timing (Synchronous/ Asynchronous)

We would deep dive on those aspects in a followup blog.



Sunday, March 22, 2015

Non-selective query against large object type (Issue)


In life many times simple things pose to be more nagging. Thinking of it why would salesforce be any different? In a age of "Lighting" , "Heroku" and "Mobility" there are minor things on the salesforce platform which might test our nerves. One such trifling issue is getting errors of non-selective query against large objects . We keep raking our heads why it keeps coming (as our memory is not always reliable that we had encountered it earlier too).

Error encountered : System.QueryException: Non-selective query against large object type (more than 100000 rows).
Lets ponder on this a bit!

What is a selective Query as against non-selective query?
A query is selective when one of the query filters is on an indexed field and the query filter reduces the resulting number of rows below a system-defined threshold. The performance of the SOQL query improves when two or more filters used in the WHERE clause meet the mentioned conditions.
What is Large Object Type?
Object having records in excess of 99999

Solutions
  • Consider an indexed filter
  • Contact salesforce.com about custom indexing.
One will need indexes for all of the fields one is using if SOQL . This means that fields in filter must all be marked as External ID or have custom indexes created.

Failing that, one may want to use SOSL, because the search indexer (not to be confused with a database index) will include all of the filter fields in the search.





Thursday, October 9, 2014

Shortie on Analytic Report Chart API

Its a busy world and everyone wants all the important information at the click of a button, and that too in a single screen. Salesforce used dashboards  to showcase multiple information in one screen, but different people have different needs. Many people wanted charts to be combined with their normals screens hence salesforce provided "Apex Analytics API and Report Chart Component" to enable developers to build snazzy interfaces coupled with:-
1. Widgets
2. Charts (Based on reports)
3. Usual VF components

The Analytics API has been made available in Apex in the Spring ’14 release (API version 30).

We can use Analytics API along with the Visualforce component <analytics:reportChart>  to build informative and pictoral UIs.
<analytics:reportChart> had been made Generally Available (GA) in the Spring ’14 release .
 Use <analytics:reportChart> component to add Salesforce report charts to a Visualforce page. One can filter chart data to show specific results. The component is available in API version 29.0 or later.

Syntax to use report charts in VF page

<analytics:reportChart reportid="{The unique ID of the report you want to display}"  size="{tiny/small/medium/large/huge}"  showRefreshButton="{A Boolean indicating whether to add a refresh button to the chart.}" hideOnError="{Use the attribute to control whether users see a chart that has an error.}" filter="{Most Important Attribute so lets discuss this in detail}"/>



Filter Attribute of analytics:reportChart component

The attribute is used to filter a report chart by fields in addition to field filters already in the report to get specific data. 
Note that a report can have up to 20 field filters. 
A filter has these attributes in the form of a JSON string: 
  1. column: The API name of the field that you want to filter on. 
  2. operator:The API name of the condition you want to filter a field by. For example, to filter by "not equal to," use the API name "notEqual." 
  3. value: The filter criteria.

Syntax:

<analtics:reportchart reportid="" size="tiny" filter="[{column:'STAGE_NAME',operator:'equals',value:'Prospecting'}]"/>


Many times while defining the filter you may mention the API names of the fields and on running the page you will encounter "Filter exceptions".
Please note API name on the field and the API name of Column to be used in filter attribute may be different.

Ex.g. 
Column does not exist or is not filterable

To get the API name of the field and the operator, make a describe request via the Salesforce1 Reporting REST API or Salesforce1 Reporting Apex Library as shown in following examples (I used the 2nd option in developer console and got it printed):

  • Salesforce1 Reporting API {OrgURL}/services/data/v29.0/analytics/reports/00OD0000001ZbNHMA0/describe
  • Salesforce1 Reporting Apex Library                                    First,get report metadata from a describe request:      Reports.ReportManager.describeReport(00OD0000001ZbBBFFF)
I got output as follows and searched for the column name which I wanted in my case it was a field Account__c and in the output below it was displayed as "IB_Asset__c.Account__c.Id":-


DEBUG|Reports.ReportDescribeResult[reportExtendedMetadata=Reports.ReportExtendedMetadata[aggregateColumnInfo={RowCount=Reports.AggregateColumn[acrossGroupingContext=null, dataType=INT_DATA, downGroupingContext=null, label=Record Count, name=RowCount]}, detailColumnInfo={IB_Asset__c.Account__c.Name=Reports.DetailColumn[dataType=STRING_DATA, label=Account: Account Name, name=IB_Asset__c.Account__c.Name], IB_Asset__c.Japan_Modality__c=Reports.DetailColumn[dataType=STRING_DATA, label=Modality, name=IB_Asset__c.Japan_Modality__c], IB_Asset__c.Name=Reports.DetailColumn[dataType=STRING_DATA, label=IB Asset Name, name=IB_Asset__c.Name], IB_Asset__c.Product_Code__c=Reports.DetailColumn[dataType=STRING_DATA, label=Product Code, name=IB_Asset__c.Product_Code__c]}, groupingColumnInfo={IB_Asset__c.IB_Asset_Age__c=Reports.GroupingColumn[dataType=STRING_DATA, groupingLevel=0, label=IB Asset Age, name=IB_Asset__c.IB_Asset_Age__c]}], reportMetadata=Reports.ReportMetadata[aggregates=(RowCount), currencyCode=USD, detailColumns=(IB_Asset__c.Name, IB_Asset__c.Account__c.Name, IB_Asset__c.Japan_Modality__c, IB_Asset__c.Product_Code__c), developerName=IB_Asset_By_Age, groupingsAcross=null, groupingsDown=(Reports.GroupingInfo[dateGranularity=NONE, name=IB_Asset__c.IB_Asset_Age__c, sortAggregate=null, sortOrder=ASCENDING]), historicalSnapshotDates=null, id=00Of0000000PQbgEAG, name=IB Asset - By Age, reportBooleanFilter=null, reportFilters=(Reports.ReportFilter[column=IB_Asset__c.Account__c.Id, operator=equals, value=]), reportFormat=SUMMARY, reportType=Reports.ReportType[label=@IB Assets, type=IB_Assets__c]], reportTypeMetadata=Reports.ReportTypeMetadata[categories=(Reports.ReportTypeColumnCategory[columns={IB_Asset__c.Account_City__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account City, name=IB_Asset__c.Account_City__c], IB_Asset__c.Account_Country__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account Country, name=IB_Asset__c.Account_Country__c], IB_Asset__c.Account_Public_Private__c=Reports.ReportTypeColumn[dataType=PICKLIST_DATA, filterValues=(Reports.FilterValue[label=Yes, name=Yes], Reports.FilterValue[label=No, name=No]), filterable=true, label=Public Account, name=IB_Asset__c.Account_Public_Private__c], IB_Asset__c.Account_Region__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account Region, name=IB_Asset__c.Account_Region__c], IB_Asset__c.Account_Site__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account Site, name=IB_Asset__c.Account_Site__c], IB_Asset__c.Account_State__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account State, name=IB_Asset__c.Account_State__c], IB_Asset__c.Account_Zone__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account Zone, name=IB_Asset__c.Account_Zone__c], IB_Asset__c.Account__c.Id=Reports.ReportTypeColumn[dataType=ID_DATA, filterValues=null, filterable=true, label=Account: Account ID, name=IB_Asset__c.Account__c.Id], IB_Asset__c.Account__c.Name=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account: Account Name, name=IB_Asset__c.Account__c.Name], IB_Asset__c.Account__c.UltimateParentId__c=Reports.ReportTypeColumn[dataType=STRING_DATA, filterValues=null, filterable=true, label=Account: UltimateParentId, name=IB_Asset__c.Account__c.UltimateParentId__c], ...}, label=IB Assets])]]

This is how I used the ReportChart tag

<analytics:reportChart reportid="00OD0000001ZbBBFFF"  size="tiny"  showRefreshButton="truehideOnError="false" filter="[{column:'IB_Asset__c.Account__c.Id',operator:'equals',value:'{!AccountId}'}]"/>





Thursday, September 4, 2014

Salesforce Summer 14 Developer Release Exam Important Info

Summer ‘14 Certification Maintenance for Developer


To prepare for the exam, Salesforce.com Certified Force.com Developer Summer ‘14 Certification Maintenance,

Access the Release Training here:
http://www.salesforce.com/customer-resources/releases/summer14/release-training.jsp

Download the Release Notes here:
https://na1.salesforce.com/help/pdfs/en/salesforce_summer14_release_notes.pdf

You will have 3 attempts to pass the exam. There are 5 exam questions and the passing score is 80%.

Last Date:
October 31, 2014, prior to the next release (Winter ‘15).

Please visit the schedule page for exact details: http://certification.salesforce.com/schedules.

Folks and Friends dont forget the important dates ...

Sunday, August 17, 2014

Curious Case of Parent Account and Child Accounts!!

Parent-Child Accounts in Salesforce

Account Hierarchy






















Each one of us might have been plagued by the question of "Extracting an Account and all its children, grand-children ,etc.. accounts in a single query" . Did u find any easy answers?
Well first of all you would wonder what should be format of such a query? 
Okay! lets says what about something like:-

Select id,name, (Select id, name, parent.name from Parent ) from Account

I am penning this blog after wadding a lot in the search results thrown by google. So you will find many pointers but it will take a while to figure out the answer.
The above query will not work as the name of the Relation between Account and a Parent Account is "ChildAccounts"




















     So by corollary the following query should work:-

Select id,name, (Select id, name, parent.name from ChildAccounts ) from Account

Well the above query gets us the immediate children but fails to get the grandchildren and so on...
So what should be the query like? Consider the following
select id,name, parent.name  from account where parent.name='Parent' or parent.parent.name='Parent' 
The above query will give you 2 levels of child records of a Parent Account.
You can define the levels of Hierarchy Allowed in a custom setting and use it to define the parent.name clause dynamically and get the desired results in a single query.