Wednesday, 17 January 2018

Create a modal or popup box in salesforce Lightning


I am going to demonstrate salesforce lightning popup model. This model is very simple here I used aura: if condition to show and hide the model.


LightningPopup.cmp

<aura:component >
    <aura:attribute name="openmodel" type="boolean" default="false"/>
    <div class="slds-m-around--xx-large">
        <button class="slds-button slds-button--brand" onclick="{!c.openModel}">Pop up Model</button>  
        <aura:if isTrue="{!v.openmodel}">
            <div role="dialog" tabindex="-1" aria-labelledby="header99" class="slds-modal slds-fade-in-open ">
                <div class="slds-modal__container">
                    <div class="slds-modal__header">
                        <button class="slds-button slds-modal__close slds-button--icon-inverse" title="Close" onclick="{!c.closeModel}">
                            X
                            <span class="slds-assistive-text">Close</span>
                        </button>
                        <h2 id="header99" class="slds-text-heading--medium">Some Inspiration never dies</h2>
                    </div>
                    
                    <div class="slds-modal__content slds-p-around--medium">
                        <p><b>Stay true to yourself, yet always be open to learn. Work hard, and never give up on your dreams, even when nobody else believes they can come true but you. These are not cliches but real tools you need no matter what you do in life to stay focused on your path.
                            
                            </b>
                        </p>
                    </div>
                    
                    <div class="slds-modal__footer">
                        <button class="slds-button slds-button--neutral" onclick="{!c.closeModel}" >Cancel</button>
                        
                    </div>
                </div>
            </div>
            <div class="slds-backdrop slds-backdrop--open"></div>
            
        </aura:if>
    </div>
</aura:component>
---------------------------------------------------------------------------------------------
LightningPopup.controller
({
    openModel: function(component, event, helper) {
        
        component.set("v.openmodel", true);
    },
    
    closeModel: function(component, event, helper) {
        
        component.set("v.openmodel", false);
    }
})
------------------------------------------------------------------------------
Preview it using salesforce Lightning App:

<aura:application extends="force:slds">
    <c:LightningPopup />
</aura:application>

Saturday, 13 January 2018

Simple SOSL scenario:

Create a visual force page:

<apex:page controller="SOSLController">
    <apex:form >
        <apex:inputText value="{!searchStr}"/>
        <apex:commandButton value="Search in Account, Contact, Opportunity" action="{!soslDemo_method}" reRender="acct,error,oppt,cont" status="actStatusId"/>
        <apex:actionStatus id="actStatusId">
            <apex:facet name="start" >
                <img src="/img/loading.gif"/>                    
            </apex:facet>
        </apex:actionStatus>
    </apex:form>
    
    <apex:outputPanel title="" id="error">
        <apex:pageMessages ></apex:pageMessages>
    </apex:outputPanel>
    
    <apex:pageBlock title="Accounts" id="acct">
        <apex:pageblockTable value="{!accList }" var="acc">
            <apex:column value="{!acc.name}"/>
            <apex:column value="{!acc.Type}"/>
        </apex:pageblockTable>
    </apex:pageBlock>
    
    <apex:pageBlock title="Contacts" id="cont">
        <apex:pageblockTable value="{!conList}" var="con">
            <apex:column value="{!con.name}"/>
            <apex:column value="{!con.email}"/>
        </apex:pageblockTable>
    </apex:pageBlock>
    
    <apex:pageBlock title="Opportunities" id="oppt">
        <apex:pageblockTable value="{!optyList}" var="opty">
            <apex:column value="{!opty.name}"/>
            <apex:column value="{!opty.StageName}"/>
        </apex:pageblockTable>
    </apex:pageBlock>
    
</apex:page>
--------------------------------------------------------------------------------------

Public with sharing class SOSLController{
    Public List<Opportunity> optyList {get;set;}
    Public List<contact> conList{get;set;}
    Public List<account> accList{get;set;}
    
    Public String searchStr{get;set;}
    Public SOSLController(){
    }
    
    Public void soslDemo_method(){
        optyList = New List<Opportunity>();
        conList = New List<contact>();
        accList = New List<account>();
        if(searchStr.length() > 1){
            String searchStr1 = '*'+searchStr+'*';
            String searchQuery = 'FIND \'' + searchStr1 + '\' IN ALL FIELDS RETURNING  Account (Id,Name,type),Contact(name,email),Opportunity(name,StageName)';
            List<List <sObject>> searchList = search.query(searchQuery);
            accList = ((List<Account>)searchList[0]);
            conList  = ((List<contact>)searchList[1]);
            optyList = ((List<Opportunity>)searchList[2]);
            if(accList.size() == 0 && conList.size() == 0 && optyList.size() == 0){
                apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Sory, no results returned with matching string..'));
                return;
            }
        }
        else{
            apexPages.addmessage(new apexpages.message(apexpages.severity.Error, 'Please enter at least two characters..'));
            return;
        }
    }
}
--------------------------------------------------------------------------------------------




                           SOSL Queries:

  • Salesforce Object Search Language (SOSL) is a Salesforce search language that is used to perform text searches in records. 
  • Use SOSL to search fields across multiple standard and custom object records in Salesforce.

This is an example of a SOSL query that searches for accounts and contacts that have any fields with the word 'SFDC'.

List<List<SObject>> searchList = [FIND 'SFDC' IN ALL FIELDS
                                      RETURNING Account(Name), Contact(FirstName,LastName)];
 
Differences and Similarities Between SOQL and SOSL

Like SOQL, SOSL allows you to search your organization’s records for specific information. Unlike SOQL, which can only query one standard or custom object at a time, a single SOSL query can search all objects.

Another difference is that SOSL matches fields based on a word match while SOQL performs an exact match by default (when not using wildcards). For example, searching for 'Digital' in SOSL returns records whose field values are 'Digital' or 'The Digital Company', but SOQL returns only records with field values of 'Digital'.

Steps:
In the Developer Console, open the Execute Anonymous window from the Debug menu.
Insert the below snippet in the window and click Execute.

// Add account and related contact
Account acct = new Account(
    Name='SFDC Computing',
    Phone='(415)555-1212',
    NumberOfEmployees=50,
    BillingCity='San Francisco');
insert acct;

// Once the account is inserted, the sObject will be
// populated with an ID.
// Get this ID.
ID acctID = acct.ID;

// Add a contact to this account.
Contact con = new Contact(
    FirstName='Carol',
    LastName='Ruiz',
    Phone='(415)555-1212',
    Department='Wingo',
    AccountId=acctID);
insert con;

// Add account with no contact
Account acct2 = new Account(
    Name='The SFDC Query Man',
    Phone='(310)555-1213',
    NumberOfEmployees=50,
    BillingCity='Los Angeles',
    Description='Expert in wing technologies.');
insert acct2;


Let’s try running the following SOSL example:

In the Developer Console, click the Query Editor tab.
Copy and paste the following into the first box under Query Editor, and then click Execute.

FIND {Wingo} IN ALL FIELDS RETURNING Account(Name), Contact(FirstName,LastName,Department)


The search query in the Query Editor and the API must be enclosed within curly brackets ({Wingo}). In contrast, in Apex the search query is enclosed within single quotes ('Wingo').


Basic SOSL Syntax
SOSL allows you to specify the following search criteria:
Text expression (single word or a phrase) to search for
Scope of fields to search
List of objects and fields to retrieve
Conditions for selecting rows in the source objects


Execute this snippet in the Execute Anonymous window of the Developer Console. Next, inspect the debug log to verify that all records are returned.

List<List<sObject>> searchList = [FIND 'Wingo OR SFDC' IN ALL FIELDS
                   RETURNING Account(Name),Contact(FirstName,LastName,Department)];
Account[] searchAccounts = (Account[])searchList[0];
Contact[] searchContacts = (Contact[])searchList[1];

System.debug('Found the following accounts.');
for (Account a : searchAccounts) {
    System.debug(a.Name);
}

System.debug('Found the following contacts.');
for (Contact c : searchContacts) {
    System.debug(c.LastName + ', ' + c.FirstName);
}

Thursday, 5 October 2017

                   Batch example scenario

Consider two fields x and y. we have already uploaded or inserted so many  Account records. At that time we haven't written any trigger or we were not aware of the future requirement.

Requirement:  If the x  value is  1  we have to update 10 in DB, if x value is  2 we have to update 20 and so on [code is self-explanatory].  

we might have a huge number of records with these unique values (1,2,3,4) and while processing in DB should be mapped to corresponding values like 20,30,40,50.

As of know, only 4 unique numbers starting from 1. 

for example:
x ---->y
1---->20
2---->30
3---->40
4---->50



Best approach is batch class

global class MapConceptUpdate implements Database.Batchable<sObject>{
    global Database.QueryLocator start(Database.BatchableContext BC)  {
        string query='select id,x_value__c,y_value__c from Account';
        return database.getqueryLocator(query);
    }
    global void execute(Database.BatchableContext BC,List<Account> scope){
        map<double,double> mapval=new map<double,double>();
        mapval.put(1,20);
        mapval.put(2,30);
        mapval.put(3,40);
        mapval.put(4,50);
       
        List<Account> aclist=new List<Account>();
        for(account ac:scope){
            if(ac.x_value__c!=null && !mapval.isEmpty()&& mapval.containsKey(ac.x_value__c)&&mapval.get(ac.x_value__c)!=null){ 
               ac.y_value__c=mapval.get(ac.x_value__c);
               aclist.add(ac);
            }   
        }
        if(!aclist.isEmpty()){
             update aclist; 
        }
       
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
}

               System.debug  is not showing in debug logs


step 1:
                  In your debug level check in Apex code debug is set
                setup--->debuglevel--->Apexcode-->debug set
Step 2:
               Debug log size if its 2MB <= then SF skip the Debug statement in that case set all unwanted flag to none so that it will reduce your debug size and then you can see the debug.

                                     Batch Apex

------------------------------------------------------------------------------------------------------------------------
Batch Apex is used to run large jobs (think thousands or millions of records!) that would exceed normal processing limits. Using Batch Apex, you can process records asynchronously in batches (hence the name, “Batch Apex”) to stay within platform limits. If you have a lot of records to process, for example, data cleansing or archiving, Batch Apex is probably your best solution.


Start method:
       The start method is called at the beginning of a batch Apex job. Use the start method to collect the records or objects to be passed to the interface method execute.

Execute Method:
      The execute method is called for each batch of records passed to the method. Use this method to do all required processing for each chunk of data.

Finish Method
  The finish method is called after all batches are processed. Use this method to send confirmation emails or execute post-processing operations.
       Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and is executed without the optional scope parameter from Database.executeBatch is considered five transactions of 200 records each.
The Apex governor limits are reset for each transaction. If the first transaction succeeds but the second fails, the database updates made in the first transaction are not rolled back.

--------------------------------------------------------------------------------------------------------------------------
Useful Links:

1. http://www.infallibletechie.com/2012/05/apex-scheduler.html

2. https://trailhead.salesforce.com/en/modules/asynchronous_apex/units/async_apex_batch

3. http://blog.shivanathd.com/2013/01/how-to-write-batch-class-in.html
-------------------------------------------------------------------------------------------------------------------------

global class BatchAccountUpdate implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext BC) {
        String query = 'SELECT Id,Name FROM Account';
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<Account> scope) {
         for(Account a : scope)
         {
             a.Name =  a.Name+'Salesforce King';
           
         }
     
         update scope;
    } 
 
    global void finish(Database.BatchableContext BC) {
    }
}
--------------------------------------------------------------------------------------------------------------------------
global class BatchScheduleAccount {
    global void execute(SchedulableContext sc)
    {
        // Implement any logic to be scheduled
     
        // We now call the batch class to be scheduled
        BatchAccountUpdate b = new BatchAccountUpdate ();
     
        //Parameters of ExecuteBatch(context,BatchSize)
        database.executebatch(b,200);
    }
}
------------------------------------------------------------------------------------------------------------------------

Test class for Batch Apex:
@isTest
public class BatchAccountUpdate_Test {
    public static testmethod void batchMethod(){
        List<Account> aclist=new List<Account>();
        for(integer i=0;i<=200;i++){
            Account ac=new Account();
            ac.name='TEST'+i;
            aclist.add(ac);
        }
        insert aclist;
     
        Test.startTest();
        BatchAccountUpdate b=new BatchAccountUpdate();
        // database.executeBatch(b);
        Database.QueryLocator ql = b.start(null);
        b.execute(null,aclist);
        b.Finish(null);
        Test.stopTest();
    }
 
}
--------------------------------------------------------------------------------------------------------------------------
Test class for scheduler class:
@isTest
public class BatchScheduleAccount_Test {
    public static testmethod void batchMethod(){
        test.startTest();
        BatchScheduleAccount  ac=new BatchScheduleAccount();
        ac.execute(null);
        test.stopTest();
    }

}
------------------------------------------------------------------------------------------------------------------------

Sunday, 3 September 2017

                                 Future Method:


A future method runs in background, Asynchronously
each method is queued and executes when system resource becomes available
To define future method simply annotate it with future annotation
========================================================
global class FutureClass{
@future
public static void myFutureMethod(){

}
}
=======================================================
future Method:
Method with future annotation

1.Must be static methods
2.and only return a void type

specified parameter must be primitive data types
or arrays of primitive data type


It doesn't except sObject as parameter. sObject might change between the time you call the method and time it executes

To work with sObject that already exist in the database pass the sObject ID
=============================================================
Simple Code Snippets:

global class FutureMethodRecordProcessing{
   @future
public static void processRecords(List<id>recordids){

List<account> accts= [SELECT name FROM account WHERE id in:recordids];

}
}
==============================================================

                        Queueable Apex:


Take control of your asynchronous process by using queueable interface

To monitor Queueable Apex:
setup-->Apex Jobs

Queueable jobs are similar to future methods in that they are both queued for execution

Additional benefits:
1.Getting the id of the job
2.using non primitive datatypes
3.chaining Jobs

================================================================
public class c1 implements Queueable{

public void execute(QueueableContext context){
account a=newaccount();
a.name='test';
a.phone='8147285030';
insert a;
}

}

=================================================================
//how do you call this class

ID jobid=system.enqueueJob(new c1());
=================================================================

                           Apex scheduler:

Suppose we want to execute job at regular interval.

=================================================================
public class s1 implements  Scheduleable{

public void execute(ScheduleableContext  sc){
//code here
}

}
=================================================================

Please Note:

1.Code executes at the specified time
2.Actually execution may be delayed based on service availability
3.you can only have 100 scheduled apex at one time

goto apex classes-->scheduled apex--> you can specified time as well and start date & end date