Pages

Wednesday, September 28, 2016

Data.com Prospector Usage

When you subscribe for Data.com Prospector, each license user allow to import company and contact records into Salesforce or export to CSV file for maximum of 300 records /month/user.

You can monitor overall usage from Setup | Data.com Administration | Prospector Users



Or, you also can run a report with report type "Data.com Users and Usage". This report will show:
  • When is the transaction (created date)
  • Who is the user (created by)
  • Purchase Type (added or exported)
  • Purchase Count (number of record exported or added)

But if you want to drill-down to details of the contacts or accounts added, report will not show you that information.

Solution: use SOQL
There are 2 objects related to this DatacloudPurchaseUsage and DatacloudOwnedEntity.

1. DatacloudPurchaseUsage - this object will store all purchase history.
Sample query: SELECT Id, Name, Usage, DatacloudEntityType, PurchaseType, User.Name, CreatedDate FROM DatacloudPurchaseUsage WHERE Id = '09Fo0000000RZ7sEAG'



2. DatacloudOwnedEntity - this object will store each contact or account exported or added to Salesforce.
Sample query: SELECT Id, Name, PurchaseUsageId, DataDotComKey, DatacloudEntityType, PurchaseType, User.Name, CreatedDate FROM DatacloudOwnedEntity WHERE PurchaseUsageId = '09Fo0000000RZ7sEAG'

Even there is no Contact Name or Company Name recorded in this object, but there are a few pointers:
1. Data.com Key - you can match this key to match with data exported or added to Salesforce
2. DatacloudEntityType - 0 = Contact and 1 = Company
3. PurchaseType - 0 = added and 1 = export

As you see, DatacloudOwnedEntity object is lookup to DatacloudPurchaseUsage object, via field PurchaseUsageId. For you  that familiar with SOQL, as you see above queries using child-to-parent query. However, when try to use parent-to-child query, it is just not possible. Further check, I do not see DatacloudOwnedEntity as child relationship from DatacloudPurchaseUsage.

Screenshot of child relationship taken from DatacloudPurchaseUsage



Compare to standard object child relationship, example: Opportunity to OpportunityLineItem


Reference:


Monday, September 26, 2016

Salesforce: Process Builder, Flow and Workflow running in System Mode

System mode: process running is NOT DEPEND on the current user permissions to the object access, field level security, sharing rule. In which the level permissions of the current user are ignored.

User mode: process running is DEPEND on the current user permission to the object access, field level security, sharing rule. In which the level permissions of the current user are enforced.

Automation in Salesforce will run in System mode, in the declarative mode this is include: Workflow, Process Builder, Process Builder + Flow. The same applicable for apex trigger as well.

While Flow will run in User mode, this is make sense as Flow is not count as automation, Flow have user interface that need user to fill something or click button.

Thanks to Mayank Srivastava for sharing matrix below this in Success Community.


The matrix is tested as of Summer '16 release, so this may change in the future. 

When Flow hit error if user do not have access to the field, an error email will be sent to the Flow creator:
Subject: Error Occurred During Flow "Flow_Name": INSERT --- INSERT FAILED --- ERRORS : (INVALID_FIELD_FOR_INSERT_UPD...

Body: An error occurred at element Element_Name (FlowRecordCreate).
INSERT --- INSERT FAILED --- ERRORS : (INVALID_FIELD_FOR_INSERT_UPDATE) Unable to create/update fields: Field_Name__c. Please check the security settings of this field and verify that it is read/write for your profile or permission set., 


Reference:

Wednesday, September 21, 2016

Salesforce: Password Expiration Date


So you set user passwords expire in 90 days, under SetupSecurity Controls | Password Policies, or under Password Policies in Profile.

Everything is working fine, all users must change password when login to Salesforce if password age reach 90 days or more.

With simply run a new report using User report type, you can check when a user need to change his/her password. Notice a field called Password Expiration Date.

In normal scenario, Password Expiration Date > Last Login. But, we notice there are a few users with Last Login > Password Expiration Date, is this mean those users able to skip password change when login to Salesforce?



Why this happened? After learn and investigate on this, here is the caused:
User is not login to Salesforce.com web, but they login from API, such as: Salesforce for Outlook, Salesforce1 app, Chatter Desktop, or others. To find out the "true" login to Salesforce.com website, down Login History, filter to that user and Login Type = Application.

Let's see two users from above screenshot:

User-1
Here is recent user login history, last login 9/21/2016 which is aligned with above report.



Filter Login Type = Application, user real last login to Salesforce.com web is 8/13/2016, while Password Expiration Date is 8/22/2016, so this is correct that user never login to Salesforce.com web after 8/22/2016.


User-2
Here is recent user login history, last login 8/12/2016 which is aligned with above report.



Filter Login Type = Application, user real last login to Salesforce.com web is 7/5/2016, while Password Expiration Date is 7/31/2016, so this is correct that user never login to Salesforce.com web after 7/31/2016.


Summary: Last Login in user report is not about just login to Salesforce.com, but it can be from other app / devices and that login method will not ask user to change password.


Other Notes:
  • Create/refresh Sandbox do not change the Password Expiration Date.
  • When user change his/her Salesforce password before Password Expiration Date, this will reset and re-count Password Expiration Date to a another x days, for this blog sample is 90 days.
  • New user created will have Password Expiration Date before Created Date, so user have to change password when login to Salesforce for the first time.




Tuesday, September 20, 2016

Salesforce: I can't deactivate user


In Salesforce, you cannot delete user, but to deactivate user when user left company, or change role that do not need to access Salesforce anymore. By deactivate the user, the license will be released for other user. But in many cases, you cannot deactivate a user because the user is defined as:

Lead
- Default Lead Owner in Lead Settings
- Default Lead Creator in Web-to-Lead Settings
- Use in Lead Assignment Rules
- Web-to-Lead Auto-Response Rules

Case
- Default Case Owner in Case Support Settings
- Automated Case User in Case Support Settings
- Use in Case Assignment Rules

Workflow
- Default Workflow User in Workflow & Approvals Settings
- As new value in Workflow Field Update action
- As the only recipient in Workflow Email Alert

Lookup
- Use as a value in Hierarchical Relationship lookup custom field in User object

Please note that when encountering the error, a link will be provided directly to the location in which the change can be made to remove the designation.

If the user is used as Dashboard running user, system will allowed to deactivate the user, but the dashboard will no longer work "Error: The running user for this dashboard is inactive. Your system administrator should select an active user for this dashboard."

NOTE: There is now the option to "Freeze" the user record. This will allow you to temporarily suspend a user account that requires more work to deactivate. See documentation below for freezing User accounts.

If you know any other areas that will stop user to be deactivated, please comment to this blog for me to add.


Reference:


Friday, September 16, 2016

Salesforce: SystemModstamp

There is one standard field in Salesforce that many of us not aware of, and not really use it, it is available in standard and custom object which is called as SystemModstamp. So what is SystemModstamp field? It is a date time field. Is this similar with LastModifiedDate? Yes in common, but sometimes it may differ.

LastModifiedDate is the date and time when a record was last modified by a user.
SystemModstamp is the date and time when a record was last modified by a user or by an automated process (such as a trigger). In this context, "trigger" refers to Salesforce code that runs to implement standard functionality, rather than an "Apex trigger".

As a result, LastModifiedDate and SystemModstamp will differ when automated processes update the records, which will happen in the following scenarios (asynchronously in some cases):

a) The archive date is extended to greater than 365 days.
b) An existing picklist value is updated (not replaced with an existing picklist value).
c) A contact's e-mail address is flagged as per the Email Bounce Management configuration.
d) The LastActivityDate field is modified
e) Roll-up summary field is created, which will update all the parent records' SystemModstamp asynchronously. Recalculation will also take place if the Summary Type is updated.
f) Some Salesforce Internal backend processes also update SystemModstamp as SystemModstamp is used internally to signal that a record (or related data) may have changed and that internal processes may need to synchronize themselves to the new record data.

Sample
I have a custom picklist field in Account called Brand__c. I will change one of the picklist value from Toyota to Honda. This field is also set for tracking. 
Before I do that, let me query all the records where brand is Kia 
SELECT Id,Name,Brand__c,LastModifiedDate,SystemModstamp FROM Account WHERE Brand__c = 'Toyota' ORDER BY LastModifiedDate


As you see here, all records have LastModifiedDate = SystemModstamp

Now, let me update the picklist value from Toyota to Honda. Salesforce by default will auto update all records where Brand__c match Toyota to Honda. 
Then let's do another query.
SELECT Id,Name,Brand__c,LastModifiedDate,SystemModstamp FROM Account WHERE Brand__c = 'Honda'

Notice here that SystemModstamp is updated, but LastModifiedDate stay the same. As this field also enable for tracking, let's check to Account History.


The value change is not tracked and Last Modified By also stay the same.


Another sample here when user try to send email to invalid email address.


Email Bounce Management will mark the email address as invalid, this will update SystemModstamp, but the LastModifiedDate will stay the same.








Tuesday, September 6, 2016

Salesforce: Getting Started with Trigger syntax


trigger TriggerName on ObjectName (trigger_events) {
   // code_block
}

TriggerName: name for the trigger e.g. AccountHandler
ObjectName: object start the trigger e.g. Account
trigger_eventscan be a comma-separated list of one or more of the following events:
before insert
- before update
- before delete
- after insert
- after update
- after delete
- after undelete

For example, the following code defines a trigger for the before insert and before update events on the Account object:
trigger AccountHandler on Account (before insert, before update) {
    // Your code here
}

Context Variables
To access the records that caused the trigger to fire, use context variables.
Trigger.New contains all the records that were inserted in insert or update triggers.
Trigger.Old provides the old version of values before they were updated in update triggers, or a list of deleted values in delete triggers.

You can use for loop to iterate over Trigger.New to get each individual sObject because data enter to Salesforce maybe in bulk, example: Data Loader or from integration with other system. Sample trigger below will populate / overwrite Description field when new accounts created.

trigger AccountHandler on Account (before insert) {
    for (Account a : Trigger.New) {
        a.Description = 'Hello World';
    }   
}
a = variable of object Account

Sample of after insert trigger:
trigger AccountHandler on Account (after insert) {
    for (Account acc : Trigger.New) {
        Task t = new Task();
        t.Subject = 'Hello World';
        t.Priority = 'High';
        t.WhatId = acc.Id;
        insert t;   
    }   
}
compare this trigger with before insert trigger earlier, this trigger will create a Task and relate it to Account created, therefore we need Account Id.

Here another sample of trigger using if and else syntax, and trigger context variables.
trigger AccountHandler on Account (before insert, after insert, after delete) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            // Process before insert
        } else if (Trigger.isAfter) {
            // Process after insert
        }        
    }
    else if (Trigger.isDelete) {
        // Process after delete
    }
}

List of context variables available for triggers:
  • isExecuting: returns true if the current context for the Apex code is a trigger, not a Visualforce page, a Web service, or an executeanonymous() API call.
  • isInsert: returns true if this trigger was fired due to an insert operation, from the Salesforce user interface, Apex, or the API.
  • isUpdate: returns true if this trigger was fired due to an update operation, from the Salesforce user interface, Apex, or the API.
  • isDelete: returns true if this trigger was fired due to a delete operation, from the Salesforce user interface, Apex, or the API.
  • isBefore: returns true if this trigger was fired before any record was saved.
  • isAfter: returns true if this trigger was fired after all records were saved.
  • isUndelete: returns true if this trigger was fired after a record is recovered from the Recycle Bin (that is, after an undelete operation from the Salesforce user interface, Apex, or the API.)
  • new: returns a list of the new versions of the sObject records. Note that this sObject list is only available in insert and update triggers, and the records can only be modified in before triggers.
  • old: returns a list of the old versions of the sObject records. Note that this sObject list is only available in update and delete triggers.

Reference