Friday, 20 January 2023

Winter-23-Platform-Developer-I-Maintenance

 @isTest

private class DataGenerationTest {
  @testSetup
  static void dataCreation() {
      Account account = TestFactory.getAccount('Muddy Waters Inc.', true);
      Contact contact = TestFactory.getContact(account.Id, 'Muddy', 'Waters', true);
      Opportunity opp = New Opportunity();
      opp.Name = 'Long lost record';
      opp.AccountId = account.Id;
      opp.CloseDate = Date.today().addDays(14);
      opp.StageName = 'Prospecting';
      insert opp;
  }
  @isTest
  static void testBruteForceAccountCreation() {
      List<Account> accts = new List<Account>();
      Test.startTest();
          accts = [SELECT Id FROM Account];
      Test.stopTest();
      Assert.IsTrue(accts.size() > 0, 'Was expecting to find at least one account created on the Test Setup');
  }
  @isTest
  static void testUseTestFactoryToCreateAccountsWithContacts() {
      List<Account> accts;
      List<Contact> contacts;
      TestFactory.generateAccountWithContacts(5);
      Test.startTest();
          accts = [SELECT Id FROM Account];
          contacts = [SELECT Id FROM Contact];
      Test.stopTest();
      Assert.IsTrue(accts.size() > 0, 'Was expecting to find at least one account created');
      Assert.IsTrue(contacts.size() == 6, 'Was expecting to find 6 contacts');
      Assert.areNotEqual(accts.size(), contacts.size(), 'Was expecting there to be a different number of account and contacts');
  }
  @isTest
  static void testAtTestSetupMethodsRule() {
      List<Opportunity> opps = [SELECT Id, AccountId FROM Opportunity];
      Assert.areEqual(1, opps.size(), 'Expected test to find a single Opp');
  }
}

Tuesday, 26 February 2019

Trigger framework

According to trigger framework
1) we should create single trigger for each object.
2) One handler class which will call Action
3) Create one action class with business logic same function you can use for other activity also. You can call from VF page or batch job if required.

1) One Trigger Per Object
A single Apex Trigger is all you need for one particular object. If you develop multiple Triggers for a single object, you have no way of controlling the order of execution if those Triggers can run in the same contexts

2) Logic-less Triggers
If you write methods in your Triggers, those can’t be exposed for test purposes. You also can’t expose logic to be re-used anywhere else in your org.

3) Context-Specific Handler Methods
Create context-specific handler methods in Trigger handlers

4) Bulkify your Code
Bulkifying Apex code refers to the concept of making sure the code properly handles more than one record at a time.

5) Avoid SOQL Queries or DML statements inside FOR Loops
An individual Apex request gets a maximum of 100 SOQL queries before exceeding that governor limit. So if this trigger is invoked by a batch of more than 100 Account records, the governor limit will throw a runtime exception

6) Using Collections, Streamlining Queries, and Efficient For Loops
It is important to use Apex Collections to efficiently query data and store the data in memory. A combination of using collections and streamlining SOQL queries can substantially help writing efficient Apex code and avoid governor limits

7) Querying Large Data Sets
The total number of records that can be returned by SOQL queries in a request is 50,000. If returning a large set of queries causes you to exceed your heap limit, then a SOQL query for loop must be used instead. It can process multiple batches of records through the use of internal calls to query and queryMore

8) Use @future Appropriately
It is critical to write your Apex code to efficiently handle bulk or many records at a time. This is also true for asynchronous Apex methods (those annotated with the @future keyword). The differences between synchronous and asynchronous Apex can be found

9) Avoid Hardcoding IDs
When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, the logic can dynamically identify the proper data to operate against and not fail

Let us know if this will help you

Monday, 29 January 2018

Salesforce Queueable , Batch job and Future Methods

1.The Batchable Interface
 • When should you use it? -
Complex long running processes (thousands of records)
- Asynchronous processing - Scheduled jobs
• How can you define a Batch? - Implement Database.Batchable -
Define start(), execute() and finish() methods

The Batchable Interface
• Advantages -
It can process up to 50m records
It can be scheduled to run at a particular time
• Disadvantages - Only five concurrent batch jobs running at a time* - It’s difficult to troubleshoot - Execution may be delayed based on server availability -
@future methods are not allowed - Can’t use getContent/getContentAsPDF methods - and a few more governor limits…

2. @future method •
When should I use it?
 - When it’s not a batch (group = 2 or more) - Asynchronous processing (simple and often)
- Long-running operations (callouts to external web services) - Separating mixed DML operations
• How can I define @future method?
 - @future annotation - Must be static and return void - Specify (callout=true) to allow callouts
@future method
• Advantages - Asynchronous processing without a concurrent limit (queue)
- Easier and quicker to implement as opposed to Batch
- Can use getContent/getContentAsPDF methods
• Disadvantages - Parameters passed in can be only of Primitive type
 - - Can’t chain @future methods - Difficult access to job ID

3. The Queueable Interface
 • When should I use it?
 - When Batch and @future need to meet in the middle - Chaining jobs
 - You need @future method with support for non-primitive types
 - Asynchronous monitoring
 • How can I define Queueable Apex?
- Implement the Queueable interface - Define execute() method
• How can I enqueue a job? - ID jobID = System.enqueueJob(new MyQueueableClass());
The Queueable Interface • Advantages
 - Asynchronous processing with non-primitive arguments
- Easy access to the job ID - Chaining jobs* •
 Disadvantages - Can’t have more than one job in the chain that does callouts

Which one to use? Batchable @future Queueable
 - Good at processing large number of records (50m) and tasks are not time-crucial

 - Can be scheduled to run at a certain time 
- Maximum of 5 concurrent jobs running at a time 
- You need good error handling for troubleshooting 
- Quick async processing (typically one record at a time) e.g. avoid mixed DML or a web service callout - Faster than a Batch - Easy to implement
 - Only accepts primitive type arguments - Can’t chain jobs 
- Hard to monitor
 - Quick async processing that supports primitive types 
- Faster than a batch

 - Ability to chain jobs - Can’t have more than one job doing callouts within the chain - Can be monitored


Please accept my solution as Best Answer if my reply was helpful. It will make it available for other as the proper solution. If you felt I went above and beyond, you can give me kudos.

Thanks and Regards
Prateek

Friday, 17 November 2017

How to Whitelist All IPs in Salesforce

I saw this on many developer forums and stack exchange and many others are facing the same issue of how we can enable of all IPs in our organization. For developers this a big problem, as every-time you share the credentials with anyone you've to whitelist their IP so they can login without sending any security code to emails.

So here is sweet and short solution to it. You simply need to create a home page component (custom link) and use this code there :


var startingPoint = 0; 
var endpoint = 0; 

openPage(); 
function openPage() 
{ 
endpoint = startingPoint + 1; 
var win = window.open('https://ap2.salesforce.com/05G/e?IpStartAddress=' + startingPoint + '.0.0.0&IpEndAddress=' + endpoint + '.255.255.255&isdtp=vw',600,600); 
win.onload = function() 
{ 
win.document.getElementsByName('save')[0].click(); 
win.onunload = function() 
{ 
win.close(); 
startingPoint = startingPoint + 2; 
if(startingPoint <= 255) 
{ 
openPage(); 
} 
} 
} 
}


On home page layout you've to use this custom link. Make sure your browser is allowing the pop-ups as once you click on this link just sit back and relax as it will continuously calls the page and add IPs to your org.

Also in code I've "https://ap2.salesforce.com", please make sure you change it your base URL of the ORG (rest URL remain as is "/05G/e?IpStartAddress=' + startingPoint + '.0.0.0&IpEndAddress=' + endpoint + '.255.255.255&isdtp=vw',600,600")

Friday, 12 August 2016

Introducing Tooling API

Use Tooling API to build custom development tools or apps for Force.com applications. Tooling API’s SOQL capabilities for many metadata types allow you to retrieve smaller pieces of metadata. Smaller retrieves improve performance, which makes Tooling API a better fit for developing interactive applications.Tooling API provides SOAP and REST interfaces.
For example, you can:
  • Add features and functionality to your existing Force.com tools.
  • Build dynamic modules for Force.com development into your enterprise integration tools.
  • Build specialized development tools for a specific application or service.
Tooling API exposes metadata used in developer tooling that you can access through REST or SOAP.
For detailed descriptions of Tooling API objects and the REST resources and SOAP calls that each object supports, seeTooling API Objects.

Tuesday, 22 March 2016

Monday, 17 August 2015

Best Practice: Avoid SOQL Queries or DML statements inside FOR Loops

The previous Best Practice talked about the importance of handling all incoming records in a bulk manner. That example showed use of a for loop to iterate over all of the records in the Trigger.new collection. A common mistake is that queries or DML statements are placed inside a for loop. There is a governor limit that enforces a maximum number of SOQL queries. There is another that enforces a maximum number of DML statements (insert, update, delete, undelete). When these operations are placed inside a for loop, database operations are invoked once per iteration of the loop making it very easy to reach these governor limits.
Instead, move any database operations outside of for loops. If you need to query, query once, retrieve all the necessary data in a single query, then iterate over the results. If you need to modify the data, batch up data into a list and invoke your DML once on that list of data.
Here is an example showing both a query and a DML statement inside a for loop:

trigger accountTestTrggr on Account (before insert, before update) {
   
   //For loop to iterate through all the incoming Account records
   for(Account a: Trigger.new) {
         
      //THIS FOLLOWING QUERY IS INEFFICIENT AND DOESN'T SCALE
      //Since the SOQL Query for related Contacts is within the FOR loop, if this trigger is initiated 
      //with more than 100 records, the trigger will exceed the trigger governor limit
      //of maximum 100 SOQL Queries.
         
      List<Contact> contacts = [select id, salutation, firstname, lastname, email 
                        from Contact where accountId = :a.Id];
     
      for(Contact c: contacts) {
         System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '], 
                                         LastName[' + c.lastname +']');
         c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
        
         //THIS FOLLOWING DML STATEMENT IS INEFFICIENT AND DOESN'T SCALE
         //Since the UPDATE dml operation is within the FOR loop, if this trigger is initiated 
         //with more than 150 records, the trigger will exceed the trigger governor limit 
         //of 150 DML Operations maximum.
                                
         update c;
      }       
   }
}