Pages

Wednesday, September 28, 2016

Data.com Prospector Usage and User

When you subscribe to Data.com Prospector, each licenses user allow to importing company and contact records into Salesforce or export to CSV file with default maximum number of 300 records /month /user.

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




Or, you also run a report with report type "Data.com 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 records exported or added)

But if you want to drill-down to the details of the contacts or accounts added, that 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 a 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 trying to use the 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


Addition:
You can check users assigned with Data.com license from Setup | Data.com Administration | Prospector Users

Unfortunately, Salesforce screen does not allow you to copy-paste into Excel file nicely, but you can use SOQL to retrieve this:
SELECT Id, Name, Title, Profile.Name FROM User WHERE IsActive = TRUE AND UserPermissionsJigsawProspectingUser = TRUE ORDER BY Name


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 in trigger earlier, this trigger will create a Task and relate it to Account created, therefore we need Account Id.

NOTES: in triggers above, we directly put the logic into trigger, it will work, but that is not the best practice. Ideally trigger should just act as traffic controller to direct to particular apex class based on the event and context.

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


Sunday, September 4, 2016

Salesforce: Rename Field Name

Earlier blog, we discussed about what happened when we try to delete a field used in business rules, in most cases Salesforce will smart enough to detect this and stop you from delete the field.

But, how about to rename field name? From times to times, because of business changes or something else, you get request to change the field label? Change Field Label should be no issue at all, but how about if you are type of admin that looking for perfection, Field Name (API Name) should be also change and follow Field Label? Should you also change the Field Name (API Name) ?

Personally, I would like to have API Name similar to Field Label, but sometimes, for many reason it would be risky to change this, mostly if the field has been deployed in production, or close to deployment date.

Let's see what happened when we change API Name, and how Salesforce re-act with this. This blog is written with Summer 16 release, so it may change / fix in the future.

1. Validation Rule 
Active & Inactive Validation Rule - Auto Update and No issue

2. Custom Formula Field 
Auto Update and No issue

3. Workflow Rule (include Approval Process)
  * as dropdown / criteria are met - Active or Inactive - Auto Update and No issue
  * as formula evaluates to true - Active or Inactive - Auto Update and No issue

4. Field Updates action for Workflow Rule
Auto Update and No issue

5. Email Template
Auto Update and No issue

6. Apex Trigger 
Not Allowed

7. Apex Class 
Not Allowed

8. Process Builder (as condition / dropdown)
  * use as Criteria - Auto Update and No issue
  * use as Filter in Record update - NO API field name auto update, "Error Occurred During Flow"
  * use as Field Values in Record update - NO API field name auto update, "Error Occurred During Flow"

9. Process Builder (as formula)
  * use as Criteria - NO API field name auto update, no error on data update, process not trigger

10. Flow 
API field name auto update, "Error Occurred During Flow"

For Process Builder and Flow, when error occurred, user who create the Process Builder or Flow will get email address, sample:

This error happened in Process Builder, when it cannot find the field name in Decision
An error occurred at element myDecision (FlowDecision).
The flow failed to access the value for myVariable_current.Field_Name__c because it hasn't been set or assigned.

Flow Details
Flow Name: Name
Type: Workflow
Version: 1
Status: Active


This error happened in Flow, when it cannot find the field name for record update
An error occurred at element myRule_1_Name (FlowRecordUpdate).
unable to parse field as dataType could not be retrieved for the passed field: RawFieldImpl[tableName: Account, columnName: Field_Name__c]

Flow Details
Flow Name: Name
Type: Autolaunched Flow
Version: 1
Status: Active


This error happened in Process Builder, when call Flow failed
An error occurred at element myRule_1_Name (FlowActionCall).
An error occurred when executing a flow interview. 

Flow Details
Flow Name: Name
Type: Workflow
Version: 1
Status: Active

From the email received, you can investigate where it failed, and what is the caused.

In summary: validation rule, workflow and email template will auto update the API name for you, apex class and trigger will block you from change the field name, while Process Builder and Flow will throw run-time error and it is ugly.

If your user double click the field to update, they will get the red error message:
The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID 30150000000LJyG. Contact your administrator for help.




If your user click Edit button and Save, they will get following screen below, which actually have the same message:



While user who create the Process or Flow will get error email from "Flow Application" with body as mentioned above. Read this blog Validation Rule in Workflow and Process Builder on how to trace what is 301xxxxx error message when your user report this error.



Reference:


Salesforce: Delete Custom Field

As a Salesforce admin, you may be aware that it is straightforward to create a custom field in Salesforce, and the same also to delete a custom field. But, Salesforce is smart enough to detect if the field that you try to delete is used in some rules, such as validation rules, workflow rules, apex class, etc., and the system will stop you from deleting the field.



In this blog, I would like to share items that will stop you from deleting a custom field when it is used in:

1. Validation Rule
If the rule is Active - NOT ALLOWED
If the rule is Inactive - ALLOWED, if you edit the validation rule without removing the deleted field, you cannot save the validation rule and will get an error message "Field field_name__c not exist".

2. Custom Formula Field
NOT ALLOWED

3. Workflow Rule (include Approval Process)
  * as dropdown/criteria are met - Active or Inactive - NOT ALLOWED
  * as formula evaluates to true - Active or Inactive - NOT ALLOWED

4. Field Update action for Workflow Rule
NOT ALLOWED

5. Email Template
ALLOWED - sample: {!Account.field_name__c} will become {!Account.00N50000002yCez}. Undelete the field will change the API field name with _del__c, and it is updated in Email Template.

6. Apex Trigger
Active or Inactive - NOT ALLOWED

7. Apex Class
NOT ALLOWED

8. Process Builder (as condition/dropdown)
  * use as Criteria - NOT ALLOWED
  * use as Filter in Record update - NOT ALLOWED
  * use as Field Values in Record update - NOT ALLOWED

9. Process Builder (as formula)
  * use as criteria - NOT ALLOWED

10. Flow
Active or Inactive - NOT ALLOWED

11. Report
ALLOWED - both in filter and report will be removed

12. List View
ALLOWED both in filter and view will be removed

13. Page Layout
ALLOWED

14. Dynamic form
NOT ALLOWED



This blog is written in Summer '16 release, so things may change in the future, please comment if you found something changed, or any rules not covered above.

In short, it is pretty safe to delete unused fields and Salesforce will detect it for you before deletion, except inactive validation rules and email templates, and also in report, dashboard, and page layout.


Additional tips: when you delete the email template, Salesforce will stop you when the email template is used in Email Alert.



Page-level ad