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

Sunday, 13 August 2017

                   Remove duplicate items from a List:

Today I'am going to demonstrate how to remove duplicate values in List. Please add below code in your anonymous window and check how it works.

List<integer> orginalresult=new List<integer>();
orginalresult.add(1); // 0th position
orginalresult.add(2);//1st position
orginalresult.add(2);
orginalresult.add(10);
orginalresult.add(11);
orginalresult.add(3);
orginalresult.add(4);
orginalresult.add(4);
orginalresult.add(1);
orginalresult.add(5);
system.debug('@@@ originalList@@@'+orginalresult);
set<integer> setresult=new set<integer>();
List<integer> Listresult=new List<integer>();
setresult.addAll(orginalresult);
system.debug(setresult);
Listresult.addAll(setresult);
system.debug(Listresult);

Problem: when converted to a Set and then back to a List using addAll(), the order doesn't remain.
Solution:
//To maintain order, you need to iterate over the elements:
for(integer s:orginalresult){
    if(setresult.add(s)){
        Listresult.add(s);
    }
    }
system.debug('@@@ListResult @@@@'+Listresult);   

Wednesday, 2 August 2017

Using Apex:Variable in Visualforce to control rendering of HTML Markup


We mostly use apex:variable tag for declaring complex expressions or variables in visual force page. But the same can be used very easily to control the rendering too.



<apex:page controller="ApexVarController1">
<div>
        <!-- apex:variable tag to control the rendering for Markup --> 
<apex:variable
value="anything will go here" var="flag"
rendered="{!flag}">
<h1> Flag value is true </h1><br />
</apex:variable> 
<!-- apex:variable tag used to not render for a Markup --> 
<apex:variable value="anything will go here" var="flag1" rendered="{!flag1}">
<h1>Flag value is false</h1><br />
</apex:variable>
</div>
</apex:page>
--------------------------------------------------------------------------------------------------
public class ApexVarController1 {
    public boolean flag { get;set;}
    public boolean flag1{get;set;}
    
    public ApexVarController1 (){
       flag=true;
       flag1=false;
    }

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

Sunday, 16 July 2017

                                    FREEZE USERS IN SALESFORCE

When administering Salesforce, you can at times run into scenarios where a particular users’s account should no longer have access. An example of that is when you have reason to believe that a user’s account has been compromised or someone has just left the company and you want to prevent them from logging in. Normally you would just disable the user; however, if the user is part of a custom heirachary field - there are more steps involved. A nice solution in the meantime us to just use the "Freeze" function.

After the user is frozen - the Freeze button changes to an Unfreeze button which performs (well, you get the idea).
Note: When you freeze a user, it does not free up a user license. In order to actually free up a license you have to perform an actual deactivation of the user.


For more Information please refer  Link:
                      http://blog.shivanathd.com/2013/10/Freeze-User-In-Salesforce.html