Using VMobile Object Configurations
VMobile Object Configurations (VMOCs) control what objects and records are synced to offline platforms. VMOCs consist of the following main components:
- Object
- Device
- Type
- WHERE clause
Admins can activate or create VMOCs from the VMobile Object Configurations tab in CRM.
Device
Each VMOC is offline device-specific. For each object to be synced down to mobile platforms, an active VMOC must exist for the relevant Device_vod field.
- iPad_vod
- iPhone_vod
- CRM_Engage_vod
- CRM_Desktop_MacOS_vod
Types of VMOCs
Full Object Sync
Full Object Sync syncs all of the data contained within an object to Veeva CRM Mobile platforms. This type of sync entry is reserved for reference objects, such as the Product Catalog and other lookup objects.
Top Level Sync
Top Level Object Sync is reserved for master objects in Veeva CRM, including Account, Medical Event, and User. The Include Related Objects check box enables the sync process to examine the user's page layout for the object and identifies all objects in Related Lists. Any that do not already have a VMOC entry are added to the query and treated as top level objects.
This means there will not be a WHERE clause filtering for those related objects, other than standard visibility of the parent record. The parent's WHERE clause will not filter these objects. This is particularly suited for parent objects with private sharing or similar built-in visibility constraints.
The following objects are typically synced using the Top Level Object Sync setting:
- Call2_vod
- User
- Product_Metrics_vod
- Account_Plan_vod
- Address_vod
- TSF_vod
- AccountShare
- Medical_Event_vod
- Contact
Related to Top Level Sync
VMOCs of this type are queried as sub-queries of the specified parent top level object. Records for this object only sync if they are associated with a parent record that is also synced. VMOCs of this type can also have their own WHERE clauses to further filter records synced.
Child and Parent Row Sync
Used when a child object controls the visibility of the parent. For example, when visibility to a row in the Campaign_vod object is based on visibility to the Campaign_Target_vod object.
Corresponding parent object VMOCs should have a Type of Top Level, with Meta Data Only set to True.
VMOC WHERE Clause
A VMOC’s WHERE clause is used in the SOQL query executed on the online database. It determines which specific records for the corresponding object sync down to the defined device. Any record that satisfies the conditions defined by the WHERE clause is synced. For example, to limit the number of calls synced to only include calls made in the last 90 days, the WHERE clause for the VMOC would be:
WHERE (Account_vod__r.Name !=null OR User_vod__r.Name !=null OR Medical_Event_vod__r.Name !=null OR Contact_vod__r.Name!=null) AND (Status_vod__c = 'Planned_vod' OR (Call_Date_vod__c ›= LAST_N_DAYS:90 AND Call_Date_vod__c ‹= NEXT_N_DAYS:30))
VMobile Object Configuration WHERE clauses have the option of including some special META-SOQL variables which assist in retrieving the correct records. Below is a list of these variables and their definitions:
- VOD_SF_USER_ID - Salesforce.com User ID of the signed in user
- VOD_SF_PROFILEID - Salesforce.com Profile ID for the profile of the signed in user
- VOD_USERS_IN_MY_TERRITORY - All users assigned to the currently signed in user's territory
- VOD_RECORDTYPE_ID - Record Type ID of the desired object
- VOD_USER_LANG_CD - Language code for the signed in user
- VOD_MY_TERRITORY - Returns a comma-delimited list of the mobile user's territory names (not IDs). If any user territories are higher in the territory hierarchy, all sub-territories are also returned. If the total number of results is more than 200, a quoted empty string (' ') is returned.
- VOD_MY_ORGID - Current org's Salesforce.com Org ID
Query Logic for the Call2_vod object
Call queries are treated specially, due to the large number of records and the variety of ways calls can be recorded.
To ensure group calls display the same accounts offline and online, the iPad_vod and iPhone_vod platforms use the following query logic.
There are four built-in WHERE clauses used for Call2_vod on the iPad_vod and iPhone_vod platforms:
- WHERE Parent_Call_vod__c = null AND Account_vod__c IN (SELECT Id FROM Account)
- WHERE Parent_Call_vod__c = null AND Medical_Event_vod__c IN (SELECT Id FROM Medical_Event_vod__c)
- WHERE Parent_Call_vod__r.Account_vod__r.CreatedById != null OR Parent_Call_vod__r.Medical_Event_vod__r.CreatedById != null
- WHERE (((OwnerId ='<userId>' AND Account_ vod__r.CreatedById = null AND Contact_vod__r.CreatedById = null AND Medical_Event_vod__r.CreatedById = null AND User_vod__c = null ) OR User_vod__c = '<userId>' ))AND Call_Date_vod__c >= LAST N DAYS: 60)
If the VMOC has no WHERE clause of its own, the above four queries execute separately to find calls. If there is a WHERE clause entered in the VMOC, the above queries are appended to the entered clause.
For example, if the Call WHERE clause is WHERE Call_Date_vod__c >= LAST_N_DAYS:90, the following queries are actually executed:
- WHERE Call_Date_vod__c >= LAST_N_DAYS:90 AND Parent_Call_vod__c = null AND Account_vod__c in (Select Id from Account) WHERE Call_Date_vod__c >= LAST_N_DAYS:90 AND Parent_Call_vod__c = null AND Medical_Event_vod__c in (Select Id from Medical_Event_vod__c)
- WHERE Call_Date_vod__c >= LAST_N_DAYS:90 AND Parent_Call_vod__r.Account_vod__r.CreatedById != null OR Parent_Call_vod__r.Medical_Event_vod__r.CreatedById != null
- WHERE Call_Date_vod__c >= LAST_N_DAYS:90 AND ((( OwnerId = '<userId>' AND Account_vod__r.CreatedById = null AND Contact_vod__r.CreatedById = null AND Medical_Event_vod__r.CreatedById = null AND User_vod__c = null ) OR User_vod__c = '<userId>' )) AND Call_Date_vod__c >= LAST_N_DAYS:60)
To have more control over the syntax of the executed WHERE clause, the &&CALLWHERE&& tag can be used to specify where the built-in Clause should be located in the query. For example, if WHERE (&&CALLWHERE&&) AND (Call_Date_vod__c >= LAST_N_DAYS:30) is entered as the VMOC, the executed queries become:
- WHERE Parent_Call_vod__c = null AND Account_vod__c in (Select Id from Account) AND (Call_Date_vod__c >= LAST_N_DAYS:30)
- WHERE Parent_Call_vod__c = null AND Medical_Event_vod__c in (Select Id from Medical_Event_vod__c) AND (Call_Date_vod__c >= LAST_N_DAYS:30)
- WHERE Parent_Call_vod__r.Account_vod__r.CreatedById != null OR Parent_Call_vod__r.Medical_Event_vod__r.CreatedById != null AND (Call_Date_vod__c >= LAST_N_DAYS:30)
- WHERE ((( OwnerId = '<userId>' AND Account_vod__r.CreatedById = null AND Contact_vod__r.CreatedById = null AND Medical_Event_vod__r.CreatedById = null AND User_vod__c = null ) OR User_vod__c = '<userId>' ))AND Call_Date_vod__c >= LAST_N_DAYS:60)
If the number of Accounts to sync is over the limit set by the ANALYTIC_ACCOUNT_CAP_vod Veeva Setting (default of 50,000), a limit is set on the number of days of calls to sync based on the Setting CAPPED_CALL_HISTORY_IN_DAYS_vod Veeva Setting (default of 60).
In this case, the WHERE clause on the VMOC is ignored and the number of executed queries are as follows:
- WHERE Parent_Call_vod__c = null AND Account_vod__c IN (SELECT Id FROM Account) AND Call_Date_vod__c >= LAST_N_DAYS:{callCap}
- WHERE Parent_Call_vod__c = null AND Medical_Event_vod__c IN (SELECT Id FROM Medical_Event_vod__c) AND Call_Date_vod__c >= LAST_N_DAYS:{callCap}
- WHERE Parent_Call_vod__r.Account_vod__r.CreatedById != null OR Parent_Call_vod__r.Medical_Event_vod__r.CreatedById != null AND Call_Date_vod__c >= LAST_N_DAYS:{callCap}
- WHERE ((( OwnerId = '<userId>' AND Account_vod__r.CreatedById = null AND Contact_vod__r.CreatedById = null AND Medical_Event_vod__r.CreatedById = null AND User_vod__c = null ) OR User_vod__c = '<userId>' ))AND Call_Date_vod__c >= LAST_N_DAYS:60) AND Call_Date_vod__c >= LAST_N_DAYS:{callCap}
Any WHERE clauses on child objects of the call are still respected.
In addition to the four WHERE clauses, the following queries run for the Call2_vod object:
- SELECT Id, Name, ..., Parent_Call_vod__r.Id, Parent_Call_vod__r.Name... WHERE Parent_Call_vod__c != null AND Parent_Call_vod__r.Account_vod__r.CreatedById = null AND Parent_Call_vod__r.Medical_Event_vod__r.CreatedById = null AND Account_vod__c IN (SELECT Id FROM Account)
- SELECT Id, Name, ..., Parent_Call_vod__r.Id, Parent_Call_vod__r.Name... WHERE Parent_Call_vod__c != null AND Parent_Call_vod__r.Account_vod__r.CreatedById = null AND Parent_Call_vod__r.Medical_Event_vod__r.CreatedById = null AND Medical_Event_vod__c IN (SELECT Id FROM Medical_Event_vod__c)
- SELECT Id, Name, ..., Parent_Call_vod__r.Id, Parent_Call_vod__r.Name... WHERE Parent_Call_vod__c != null AND Parent_Call_vod__r.Account_vod__r.CreatedById = null AND Parent_Call_vod__r.Medical_Event_vod__r.CreatedById = null AND Contact_vod__c IN (SELECT Id FROM Contact)
Query Logic for the Child_Account_vod Object
To support syncing child accounts that point to accounts outside of a user's territory, user can update the Parent_Account_vod__r relationship on the Child_Account_vod object to be a lookup field instead of a master-detail.
If Parent_Account_vod is a normal lookup field:
- Ignore the Child_Account_vod VMOC WHERE clause
- Use the following two WHERE clauses:
- WHERE Parent_Account_vod__c IN (SELECT Id from Account)
- WHERE Child_Account_vod__c IN (SELECT Id from Account)
If the Parent_Account_vod field is a master-detail field, Child_Account_vod records sync according to the Child_Account_vod VMOC.
Query Logic for the TSF_vod, Group, and AccountShare Objects
If the ENABLE_GROUP_FILTERING_vod Veeva Setting is enabled, the TSF_vod, Group, and AccountShare records ignore the defined WHERE clause and are filtered by group or territory membership only.
The user's territories are queried first, descending the hierarchy. After that, the following object-specific queries run:
- Group – WHERE RelatedId IN ( ids_of_my_territories )
- AccountShare – WHERE UserOrGroupId IN ( ids_of_groups )
- TSF_vod – WHERE Territory_vod__c IN ( ids_of_my_territories )
Query Logic for the Affiliation_vod Object
The VMOC WHERE clause for the Affiliation_vod object is always ignored. Instead, the following queries run:
- WHERE From_Account_vod__c IN ( Select Id From Account ) AND To_Account_vod__c IN ( Select Id From Account )
- WHERE From_Contact_vod__c IN ( Select Id From Contact ) AND To_Contact_vod__c IN ( Select Id From Contact )
- WHERE From_Account_vod__c IN ( Select Id From Account ) AND To_Contact_vod__c IN ( Select Id From Contact )
- WHERE From_Contact_vod__c IN ( Select Id From Contact ) AND To_Account_vod__c IN ( Select Id From Account )
Query Logic for the Sample_Limit_vod Object
The following queries run against Sample_ Limit_vod records:
- WHERE User_vod__c = '{userId}'
- WHERE Account_vod__r.Name != null AND User_vod__c = null
If a specific WHERE clause is defined, it is incorporated into the above queries with an AND operator. For example, if the VMOC WHERE clause is WHERE End_Date_vod__c >= TODAY, the queries would be:
- WHERE End_Date_vod__c >= TODAY AND (User_vod__c = '{userId}')
- WHERE End_Date_vod__c >= TODAY AND (Account_vod__r.Name != null AND User_vod__c = null)
Chunking Historical Data
Users can chunk their queries for historical data using the &&LAST_N_DAYS&& method in their WHERE clauses to increase sync performance. The Veeva &&LAST_N_DAYS&& method requires at least three items, separated by colons:
API name of the date or dateTime field to be used
Total number of days to be queried
Number of days in a single chunk
(Optional) Number of days to chunk into the future.
The WHERE clause WHERE &&LAST_N_DAYS:Call_Date_vod__c:60:10&& creates six historical queries and a query for today and all future calls.
Users can also chunk future queries by adding a fourth parameter to the &&LAST_N_DAYS&& method.
The WHERE clause WHERE&&LAST_N_DAYS:Call_Date_vod__c:60:10:30&& creates six historical queries, three queries covering 30 days into the future, and a query for all future calls beyond 30 days.
Using Multiple VMOCs on an Object
Multiple Top Level or Full VMOCs are supported for the same object. When enabled, each VMOC for a particular object and profile is used to build the offline data set. The offline data set is created via OR operators connecting the data sets returned by each VMOC and de-duplicating the results.
Configuring Multiple VMOCs
To enable this feature, enter a value of 1 for the SYNC_CONFIGURATION_MODE_VOD Veeva Setting.
Considerations
- Only Top Level or Full VMOCs are supported by this feature
- Enabling multiple VMOCs for a particular object causes additional queries to run, which impacts sync time. The amount of time varies depending on the type of sync being run, the size of the object, and the complexity of the query or queries.
- Ensure all current VMOCs are functioning correctly before enabling this feature. Once enabled, all active VMOCs are used in the sync and could potentially add unwanted data to the device.
- The Affiliation_vod and Child_Account_vod objects are not supported by this feature
Using Enhanced Sync
Enhanced Sync is a check box that can be enabled for any VMOC. Enhanced Sync VMOCs transfer all newly shared records regardless of the Last Modified By date. All records, corresponding content, and attachments the user no longer has access to are removed in the sync. In contrast, traditional sync updates an object’s records on the device only if the record’s Last Modified By date is after the Last Sync date.
Sync times may be extended by enabling this feature. Only enable this feature for objects that require it.
Considerations
- Enhanced Sync should be enabled for objects with sharing rules configured
- Enable Enhanced Sync when the WHERE clause on an object’s VMOC is updated, or when an object’s sharing model is updated. Disable after all users have synced the change.
- Do not enable Enhanced Sync in Related to Top Level VMOCs. This extends sync times.
- In a master-child relationship, admins should enable Enhanced Sync for each child object
- VMOCs do not need to be created for object share tables except for certain Account Plan Sharing objects
If a CRM for iPad user loses access to a record referenced via another record, sync errors occur. This behavior exists regardless of whether Enhanced Sync is enabled.
Configuring Enhanced Sync
To enable this feature:
- Navigate to the Enable_Enhanced_Sync_vod field on the VMobile_Object_Configuration_vod object.
- Select Edit.
- Select Active from the Field Usage picklist.
- Select Save.
- Grant all users FLS edit permission to the Enable_Enhanced_Sync_vod field on the VMobile_Object_Configuration_vod object.
- Add the Enable_Enhanced_Sync_vod field to the VMobile_Object_Configuration_vod page layout.
- Select the Enable_Enhanced_Sync_vod check box for all appropriate VMOCs.