Thursday, October 29, 2020

Getting Started with Salesforce Einstein Vision OCR (tabular model) - Part 2

In the previous Einstein Vision OCR blog post, we took a look at setting up Einstein Vision and viewed a sample usage with Business card. Click here if you missed it. 

In this post, we shall see the other version of the OCR which is reading tabular format image. E.g Balance sheet, excel screen capture, inventory list, etc...

Official Einstein Vision Tabular documentation here: https://metamind.readme.io/docs/detect-text-and-tables

I have created a sample code which will call the tabular model and from the predicted result, I built a html table which is being displayed right away in your Salesforce.

Demo screenshot


Here is a demo video:


Technical details about the prediction result: 

  • the recognized label will contain a cellLocation with rowIndex and colIndex. 
  • use the rowIndex and colIndex to map it on a two dimensional array 
  • then build the html table with tr and td
    • tr - for each row
    • td - for each column

Here are some use cases where it can be useful:
  • You need to digitalize all paper work tabular transaction, just scan it and let Einstein do the rest.
  • scan you sheets and display form for a data entry to validate and correct where necessary. This will save time during data entry


In the next post, we shall talk about the Einstein Vision Retail Execution API. Stay tuned.

Cheers..


Thursday, August 13, 2020

Passing parameters to Custom Label in Apex

Custom labels enable developers to create multilingual applications by automatically presenting information (for example, help text or error messages) in a user’s native language. Custom labels are custom text values that can be accessed from Apex classes, Visualforce pages, or Lightning components. The values can be translated into any language Salesforce supports. (more here: https://help.salesforce.com/articleView?id=cl_about.htm&type=5)

But what if we want to be able to add dynamic Custom Label in APEX? Instead of concatenating several labels and dynamic variables, this can be achieved using a single Custom Label.

Example: Account Spoon Consulting Ltd has 130 contacts and 300 opportunities.

In the above label, the account name, contact amount and opportunity amount are dynamic values which have been fetched from the Account record. 

Here is how the label will look after adding the merge parameters: 
Account {0} has {1} contacts and {2} opportunities.

Syntax to reference a Custom Label in Apex: 
System.Label.AccountSummary

Below is how we replace the merge fields in the custom labels:
String.format(System.Label.AccountSummary, 
   new List<Object>{ 'Spoon Consulting Ltd', 130, 300 });
Output: 

Using the above method, you can easily add translation to the label and fully customizable in any language without the need to modify the code. 

Hope this article was useful to you. 

Cheers :)

Thursday, July 30, 2020

Getting Started with Salesforce Einstein Vision OCR - Part 1

What is Einstein OCR?

We all know that OCR is an Optical Character Recognition which can detect and extract text from images. But, what about Einstein OCR?

Einstein OCR provides models that can detect text in an image such as Business cards, Images that contain unformatted data and images that contain data in tables.

In this blog post, we will focus on the Business Card Model. When choosing business card model, Einstein OCR can detect the entity type text such as Person, Organization, Email, Phone, Address, etc...

Sign Up

To get Started with Einstein Vision, you first need to register for an Account (If you don't already have one). 
Go to: https://api.einstein.ai/signup and Click on Sign Up using Salesforce.



Sign Up Einstein Vision
Sign Up


It is quite straight forward after that. If all goes well, you should see a screen with your Einstein Private Key like below. Download the key and keep it safe for later.

Private key
Private Key

Setup

Deploy Salesforce code

Once you have an Einstein Account, we can start the setup. For the next step, you will require some basic developer skills. 

Download this SFDX project from my public github repository: https://github.com/kevanmoothien/einsteinvisionocr

Connect the project to your Organization using SFDX: Authorize an Org option and then deploy all the elements inside the project structure.

Configure Permission for Salesforce App

When everything has been deployed, you can assign the App Einstein OCR to the desired Profile. 

profile assignment
Profile Assignment


Setup Einstein Vision

Configuring Einstein Vision is pretty straight forward, just switch to the Einstein OCR app on your Salesforce and open the Einstein Vision Setup tab

Enter the email address you used to Sign Up (make sure it is the email and not the Salesforce Username; you should find it in the welcome Einstein Mail).
Then use the Upload Files button to upload the private key (einstein_platform.pem file that you downloaded previously)

When saving the setting, you should have a green tick icon on the right hand side of the component to validate that the Account is valid.

Setup Einstein Vision
Setup Einstein Vision


OCR in Action

To see the OCR in action, simply click on the Einstein OCR tab next to the Einstein Vision Setup tab.

Insert a Business Card Image Url and click on Scan.

Demo

The page comprises of 3 simple component: 
  • Component to input the Image Url
  • Another one for Preview the Business Card
  • lastly, result previewer
From the above example, you can see Mark Benioff business card. It has already categorised the different elements found on the Business  Card.

Wrap-Up

If you want to dive into more details on how the API call is done and detection result is processed, you can just take a look at the class EinsteinVisionUtils and Prediction class in the source code. 

Friday, April 24, 2020

Dynamically access any variable in an instance class

In this blog post, I will show you how to access any variable on an instance of an Apex class dynamically.

This is something useful when you want to make dynamic feature which are based on setting, especialy when doing ISV stuffs.

The code is as simple as below:

public class Employee {
    public String employeeId;
    public String firstname;
    public String lastname;
    public String username;
    public String profileUrl;

    public Object getValue(String variableName) {
        String jsonString = toJSON();
        Map<String, Object> untyped_instance;
        untyped_instance = 
            (Map<String, Object>)JSON.deserializeUntyped(jsonString);
        return untyped_instance.get(variableName);
    }
    
    public string toJSON() {
        return JSON.serialize(this);
    }
}

Example:

Employee emp = new Employee();
emp.employeeId = 'test';
emp.firstname = 'kevan';
emp.lastname = 'moothien';
emp.username = 'kevanmoothien';
emp.profileUrl = 'https://picsum.photos/200/300';

system.debug(emp.getValue('firstname')); // returns kevan
system.debug(emp.getValue('lastname')); // returns moothien

Here is a use case where this kind of integration can be used based on the above code.
Suppose you have to develop a custom related list lightning component which would be used on several layout. But on each layout, it has to display different columns.

To achieve this, we would think of different component and hardcoded variable. But, this can be done by simply having a Custom Metadata type to save the setting of each layout and the related list custom component can simply display the columns value dynamically using the above code based on the setting provided in the Lighting app builder.

Hope this is useful to you trailblazers.

Cheers :)

Sunday, April 5, 2020

How can we efficiently generate a List of Id from a List of SObject structure with just one line of code?


Do you know how to get a list<Id> from a list<SObject>? Yes, doing a loop of the list of SObject and then put each record Id into another list or set. 

What if this was possible in just one line of code?

Infact, it is possible to write this in just one line of code. Don't believe me? Take a look below. 

Let say we have a list of contact records from which we only want to extract the list of record Ids.

Cheers