Salesforce Google Map Integration

Salesforce Google Map Integration

We are Salesforce™ Experts and we channelize our energy by documenting all the industry-specific technical problems we solve in Salesforce™ CRM world. Here I am about to explain one of the Google Map API with Saleforce.com custom development projects I was closely involved as a Salesforce™ Developer. At, below I will provide you the brief description of the project what basically it is and how we helped our end client.

Requirements:-

In, this Project Client basically need a system viewer where he can calculate a distance between the source and the other records. The basic agenda of this project to help our end client where they will help their customer and they can identify all the machine from the source of Account.

The original idea of the project is that from a single Account record Source we need the ability to produce a list of other accounts. Account records that fall within a certain proximity radius to that account is a list of accounts that result from the search ‘Proximity’ accounts.

The account in the system could potentially be a source account. The user initiating the search from the Source account would first need to populate a screen showing various criteria information. Such criteria would include a ‘Radius’ setting we will provide the initial default value but we will need the ability to override.

Additional criteria would include two or three custom fields these currently exist on the Account record. It will provide default values for each but we will need the ability to override.

It is not mandatory that the list of Proximity accounts display in map form. If the Proximity accounts are displayed in a list, and not on a map, it is important that we can see the distance in miles from each Proximity account to the Source account.

We came with the solution:-

In,this what we acknowledge that from the list of account we can identify certain set of machines from the source to the estimate miles and can find out the list of machines from the source with different cost and it would ease to identify the certain machine from the list of miles and also it can be identified from the last sale day ago which we can filter from all the above source and then click on search. From this, it provides two option 

1-Generate pdf
2-View Map

Generate Pdf:- From this Option Customer after selecting their choices they will click on this option and they will get the detailed report within the Pdf.

View Map:- It provides the viewer to identify all the destination location of the products and analyze the certain destination via this map.

 

 

Now, with the following screenshots its methodology can be understood as follows:-

1) Search Filter with the various criteria

 

It can be understood with the following Code Snippets as follows. These are the few components which we deployed to the production.

1. Show All Account on Filter Controller:-

From below code, we are able to distinguish how to multi-select the option which is available on the filter-

public with sharing class ShowAllAccountOnFilterController {

public String recordID{get;set;}

public Account Sourceaccount{get;set;}

public double Last_Sale_Days_Ago{get;set;}

public list<Account> accountList{get;set;}

public list<Account> accountlistSearched{get;set;}

public list<Account> accountlistSearched1{get;set;} // list will show on map

public list<wrpclass> SearchAccountListWithMiles{get;set;}

public list<String> accountpicklistvalue;

public list<String> seletectedaccountpicklistvalue;

public boolean listisempty{get;set;}

public boolean showiflistfilled{get;set;}

public  String headerdata{get;set;}

At below there is a description of the above model with the ER Diagram

 

 

 

 

5 Mistakes A Salesforce Developer Can Commit Or Should Avoid

5 Mistakes A Salesforce Developer Can Commit Or Should Avoid

This Salesforce Blog is a developer’s experience in the Journey of Force.com development and customization. The problems faced by a day to day developer and the mistakes committed by them can sometimes be interesting and useful to a wide range of developers and administrators.

So let’s start the epic!!

Do Not Hardcode:

Once upon a time I was developing on a VF page and provided a link to a report(Our Standard Salesforce Reports in Visualforce Page:

So I hardcoded the URL for report as link in my VF page. The URL was working fine in sandbox and I was happy. Once I was done with development I migrated my changes to Production environment, Finally when I tested the application on the website I was unable to see the report on clicking the link.

But I got to know later that I cannot modify the apex class in production environment and I needed to fix it ASAP so it was all a big mess!

After scrutinizing the snag , I found that I had hardcoded the URL for my report and since the environment has changed  URL had stopped working.

So I finally  figured it out  using concept of dynamic URLs and used some code snippet like below:

“URL.getSalesforceBaseUrl().toExternalForm()+’/’+reportId”

Final Verdict: > DO NOT HARDCODE!!!

Avoid SOQL Errors:

While Developing have you encountered errors such as  “System.LimitException: Too many SOQL queries: 101” ?

This error System.LimitException : Too many SOQL queries: 101 is due to the fact, you are hitting on governor limit.

Our esteemed  Governor limits  says that you can run total 100 SOQL queries in a context and you are hitting the limit.

After a thorough study on the same I found that all the triggers fired will be counted in a single context or call. We need to ensure that total number of SOQL fired should be less than 100.

In order to pass this,  Many times i changed my  code in such a way that SOQL fired must be less than 100.

Sometimes I have also preferred if (only  we need to change the context)  using  @future annotation when I was required to run  the code asynchronously.

I made sure always  that the SOQL query I use should not be inside the for loop.

There are certain best practices which you would have to follow to avoid this error (to avoid hitting governor limit).

https://wiki.developerforce.com/page/Best_Practice:_Avoid_SOQL_Queries_Inside_FOR_Loops

http://salesforcedeveloperblog.blogspot.com/2011/05/best-practices-of-triggers.htmhttp://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_bestpract.htm

http://wiki.developerforce.com/page/Apex_Code_Best_Practices

https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm

 Always follow the above practices to make sure you stay smiling at your workplace..

The challenging part is that one cannot increase the governor limit and can only follow best practices.

Streamline Multiple Triggers on same Object

 So here Is one more tricky situation:

Once I was working on a requirement (in short)  on the esteemed object Case to assign the account manager automatically. So I wrote a trigger which was  “Before Insert”.

I found that sometimes the account manager assigned was as expected and sometimes NOT!!

I was Bewildered !!

Like Always I started digging out checking debug logs, manual testing etc etc.

Finally Debug log was a ‘Maseeha’ telling me that I do have two more triggers with “Before Insert “ due to which system was unable to recognize the order of execution. Probably those codes were drafted by some other developers( of course my current and previous colleagues). I sat with them and finally came up with a single trigger with the same event on the object.

So in practice, Avoid multiple triggers with the same event on an object because it may discommode you at times.

Bulkify Your Code

So in the initial days of my Salesforce Development career, I faced something very terrible and good learning of course for me.

Let’s start with giving you some glimpse on my  poorly written code that only handles one record :


trigger BeforeInsert_Account on Account (before insert){

//This only handles the first record in the Trigger.new collection but if more than 1 Account initiated this trigger, those             additional records will not be processed

Account objAccount= Trigger.new[0];

List<Contact> contacts = [SELECT ID,salutation,firstName,lastName,email FROM Contact WHERE
 accountId = :acct.Id];

//and something something

} 

I tested the trigger and it worked fine and I was done by my job and then suddenly one day trigger hit the governor limits.

Like always I was bewildered. Got to know that one of my sweet colleague has written a batch apex to insert the Accounts and this was the whole sole reason.

Since I couldn’t ask my sweet colleague to undo the batch class, I need to do something.

After digging,I found that if a batch of records invokes my Apex code, all of those records need to be processed as a bulk, which hits governor limits.

And the issue was  that only one Account record was handled because the code explicitly accesses only the first record in the Trigger.new collection by using the syntax Trigger.new[0]. Instead, the trigger should properly handle the entire collection of Accounts in the Trigger.new collection.

Here is a sample of how I handled all incoming records from batch:

trigger BeforeInsert_Account on Account (before insert){

//This only handles the first record in the Trigger.new collection but if more than 1 Account initiated this trigger, those additional records will not be processed

Account objAccount= Trigger.new[0];

List<Contact> contacts = [select ID, salutation,firstName,lastName,email FROM Contact 
WHERE accountId = :acct.Id];
//and something something……
}

Notice how this revised version of the code iterates across the entire Trigger.new collection with a for loop. Now if this trigger is invoked with a single Account or up to 200 Accounts, all records will be properly processed.

So always put down strategy to write bulkified code.Make it as practice, though it will be not easy but good for long terms!!

Follow General Design Guidelines for Application Performance

As per my experience in designing Visualforce you may develop a very rich UI with nice pop-ups and images but when the users start using it ,it becomes nettlesome for them to click or navigate to buttons.

I have written these general guidelines to avoid performance impacts:

  • Always design pages around specific tasks, with a sensible workflow and navigation between tasks.The DOTS should be connected everywhere.
  • Never  overload pages with functionality and data. Visualforce pages with unbounded data or a large number of components, rows and  fields have poor ability and performance, and they risk hitting governor limits for view state, heap size, record limits, and total page size.
  • Always try to push back on requests to include non-essential functionality.
  • Must Build prototypes to validate concerns.

 References:

https://developer.salesforce.com/blogs/developer-relations/2015/01/apex-best-practices-15-apex-commandments.html

Salesforce Sandboxes – Key Player in Managing & Deploying Customization

Salesforce Sandboxes – Key Player in Managing & Deploying Customization

What is a Sandbox?

A Sandbox to a developer/administrator is like a playground for a child, it allows the developer/administrators to customize, play and configure the application development environment without affecting the actual production release versions. Sandboxes in Salesforce are used for app development, code management, version control, testing, and training without compromising the actual data and applications in your Salesforce production organization.

Types Of Sandboxes:

  Developer Sandbox Developer Pro Sandbox Partial Copy Sandbox Full Sandbox
What is their Usage? For coding and testing in an isolated environment For coding and testing in an isolated environment For  Testing environments and quality assurance task For testing environments and for performance and  load testing and staging
What do they include of  Production Environment? A copy of production organization’s configuration (metadata). A copy of production organization’s configuration (metadata). They have a larger storage limit than Developer sandboxes. A copy of production organization’s configuration (metadata), and a subset of production data as defined by a sandbox template. Replica of the production organization.
Licenses with which you can create Sandboxes  ·  Full Sandbox ·  PartialCopy Sandbox ·  Developer Pro Sandbox ·  Developer Sandbox · Full Sandbox · PartialCopy Sandbox · Developer Pro Sandbox · Full Sandbox · PartialCopy Sandbox · Full Sandbox

Sandboxes In SDLC Process

In a Salesforce app development life cycle, comes various phases of code development, unit testing, UAT etc. A simple example is: 

   In a case when different teams work on multiple areas simultaneously which finally have to be merged into a single organization, that is a single Production environment, with time the process becomes rather complex. It overcomes this a staging platform is created to repressively test the performance without affecting the production version. An example for the same is shown below: 

Managing Sandboxes For Release Management Process

Though there is no thumb rule or out of the box process defined on which organizations are dependent on handling their release management system. But still there are some points on sandboxes to be considered for running the process:

  • Make a practice to refresh the sandboxes after every release so that we make sure to leverage the new features and make sure that our environment is compatible with the new changes.
  • Also, it’s recommended to have a strategy to align the org releases with Salesforce releases, in order to reduce the efforts for refreshing sandboxes.
  • A Post Refresh Run List should be prepared and followed every time sandboxes are refreshed after a new release. Few things which should be included are:
    • Data Masking Needs
    • User Profile Modifications
    • Test Data Loads
    • Deployment Plan
    • Turn Off Scheduled Jobs
    • Manage Outbound Email.

Hope this would help you in getting an overview of what Salesforce sandboxes are.

Role of a Salesforce Tester

Role of a Salesforce Tester

The Core Team

In a typical Salesforce Project delivery, the following resources from the core team:

  • Business Analysts
  • Project Managers/Scrum Masters
  • Quality Analysts/Testers
  • Developers
  • Administrators

The role of a Salesforce tester is that of a full-fledged engineer in its own right, therefore they are more commonly referred to as Quality Engineers as an alternative to Quality Assurance. Typically they are either Salesforce.com Certified Administrators or Salesforce.com Certified developers. In layman terms, they have all the skills to work on testing assignments for projects that follow Agile as well as traditional software life cycle and can review codes for bugs, and be able to design, write, maintain, and scale complex test frameworks, and sometimes even set up test environments from scratch.

What is the responsibility of a Salesforce Tester?

  • The major function of a Salesforce Tester includes services like Functional Testing, Unit Testing, Manual Testing, Automated Testing, Load Testing, Deployment Testing, and Security Testing.
  • Manual testing, for which specific type of experience and skills related to testing are not required, mainly includes the testing of Salesforce.com App using a human with a methodical approach
  • Testers having experience with AssureClick, Selenium, QTP etc. play a vital role in Salesforce Automated Testing.
  • Salesforce testers are required to test Salesforce.com or Force.com apps functional testing which incorporated Unit Testing and Process Testing.
  • Sometimes the testers are required to work on the application and gain the understanding of its functionality to create functions map. They then use the functions map to create and execute the test cases.
  • Other important testing types include:
    1. Salesforce.com Load testing
    2. Salesforce.com Security testing
    3. Salesforce.com CRM ad-hoc testing

As a career option, the growth prospects for a Salesforce tester are very rapid. ADM 201 certification can add to their career development immensely. With a background in testing, they make for qualified candidates for the role of future business analysts. Happy Testing!

Process Builder Vs Apex Triggers –  Choosing Between Automation Tools

Process Builder Vs Apex Triggers – Choosing Between Automation Tools

Process Builder Overview

Process Builder is a graphical representation of your process as you build it. It consists of

Criteria, Immediate and Scheduled Actions.

There are following things which can be done by process builder:

  • Create Records:In addition to updating a record, you can create a record and set the field values within the record.
  • Create Chatter Post:   Push a chatter update into Group or Feed.
  • Create an approval:Traditionally you needed a trigger to push a record into an approval process automatically. With Process builder, you can do this automatically based on criteria of the process.
  • Quickly consolidate Workflow:Quickly consolidate multiple workflow rules that in one process.
  • Call an Apex Class:You can now call an Apex class.

Trigger Overview

A trigger is the piece of code, that is executed Before or After a record is inserted or updated.

Usually, an APEX (code) based evaluation of criteria to set off a chain of events.These events execute the following types of operations

  • Insert
  • Update
  • Delete
  • Merge
  • Upsert
  • Undelete

In Apex Trigger you must have

  • Need to programming knowledge.
  • Need to design test classes to meet required test coverage.

But the main difference in process builder is you can not delete any record and can’t show any error. For these, you have to write Trigger code. For example:

Apex Limitations

  • Total number of records retrieved via SOQL queries                                       50,000
  • Total number of records retrieved by DML                                                        10,000
  • Total number of SOSL queries issued                                                                 100(Sync) | 200(Async)
  • Total number of SOSL queries issued                                                                 20
  • Total number of records retrieved by a single SOSL query                             2,000
  • Total number of DML statements issued                                                           150
  • Maximum number of characters for a trigger                                                   1 million

Process Builder Limitations

Editing: User can’t edit process once it has been activated.Therefore much like with flow, a new process needs to be created by cloning the initial process and making modifications to that cloned records.

Validation: Processes DO NOT  trigger Validation rule and can, therefore, invalidate data.

Deletion: The inactive process can’t be deleted for at least 12 hours after inactivation and do not appear in the Recycle Bin

Error Message: You can’t specify error messages when creating a process that doesn’t trigger as you can with flow or validation rules.

Formula help: When utilizing formula in criteria, there is no function help preview next to the syntax

Syntax: Pick-list fields are evaluated as text fields in process builder so that they won’t support any pick list formulas like ISCHANGED or ISNEW.

Apex Trigger Best Practices

  • Apex code must provide exception handling.
  • When query large data set use an SOQL FOR loop
  • Don’t use  SOSL and SOQL inside for loop.
  • Avoid Hard Coding IDs

Process Builder Best Practices

  • Check: To see if there are any workflows on the object doing the same things as the process. Also, verify no active Apex Trigger.
  • Avoid: Interviewing Apex, workflows, and processes together for the same process.
  • Document: Use the Description field to populate information such as when it was created by who and what the process does.Also, if processes work in conjunction with each other.
  • Test: And then test some more.Especially when you are first starting to use this please practice in the sandbox first.

There’s a lot of ability to impact users and data here if you do something wrong.

Now the question is Why Process Builder and how is it differ from trigger?

Process builder is fully customization. No code required here because we require lengthy logic and record to complete and fulfill the requirement or if we using process builder it will take less time to complete the requirement.

It has some benefits over the trigger:

SCENARIOS OPTION REASON
Scenario I

Populate a lookup field on record update:

Traditionally required a trigger and It can be done easily with process builder.

The issue is Multi layer lookup logic- i.e. multiple / nested maps of related data required in the trigger.

          Process builder Trigger Traditionally been something that requires a Trigger. Process builder allows administrator can do this without the use of the code.
Scenario II

Set an Account Owner based on Record criteria

Process builder

Trigger

Process builder can be used to assign ownership of records based on criteria in the object.
Scenario III

Post a chatter message based on record criteria

Process builder

Trigger

Process builder can be used to post to chatter based on record criteria.
Scenario IV

Submit a Quote for Approval when Opportunity Stage= Proposal

Process builder Trigger Requires 2 Processes one to Update the Quote based on the opportunity stage and another to submit the quote for the approval when the criteria on the quote had been met.
Scenario V

Launch a Flow via record criteria vs a button or link.

Process builder

Trigger

Process builder can be used to set record criteria and then launch a trigger ready flow.
Scenario VI

Clone an opportunity and change the field values

Process builder

Trigger

Although Process builder can create a new record it can’t reference any of the values from the cloned opportunity without the use of a flow to capture the opportunity values.

Let’s have a look on given Process builder example :

Allow Contact to copy Current User Address in Contact Address and Account Billing Address only when any address field(Street, Country, state )is blank/NULL.

Step 1:

Make your Process-builder on Contact Object. Provide the criteria as Contact.Mailing Street (IS NULL = FALSE) and likewise for every address fields of Contact and Opportunity.

Step 2:

In “Immediate Action” give reference of Mailing Country to that of Contact.Owner.Country and Activate your Process as:

 Step 3:

Now test this process builder in your org by leaving any address field blank in your org.

Step 4:

After leaving Contact address blank here is the address which got autofilled same as contact’s owner address. Similarly you can test this for your Contact’s Account.

This is the reason for using Process builder rather than using Apex. But  in some scenarios you’ll have to write trigger code where process builder can’t be.

For example:

Create a checkbox field “SAME COUNTRY AS USER & COMPANY”. Throw error when a Contact is getting inserted in Salesforce having Country same as User country and Company country.

Above example can’t be done via Process builder since this do not allow you to throw error while inserting Contact.
Create  Checkbox field named “SAME COUNTRY AS USER & COMPANY” on Contact.

APEX CLASS:
public class SameUserAndCompanyCountryContact {

public static void sameCountry(List<Contact> conList){

   User user = new User();

   user = [SELECT Id , Country , CompanyName from User where Id =:UserInfo.getUserId()];

   System.debug('>>>>>>>>>>RB<<<<<<<<<<<<'+user);

Organization orgDetails = [ SELECT Name , Country , Address from Organization where Name =: user.CompanyName];

System.debug('>>>>>>>>>>>RB<<<<<<<<<<<<'+orgDetails);

for(Contact con : conList) {

  if(con.MailingCountry == user.Country && con.MailingCountry == orgDetails.Country){

   con.addError('Country of Company and User is same as country of Contact trying to insert');

     con.Same_Country_As_User_And_Company__c = True;

         }

      }

   }

}
APEX TRIGGER:
trigger ErrorOnSameCountry on Contact (before insert){
  List<Contact> conList = Trigger.new;
     if(conList!=null) {
       SameUserAndCompanyCountryContact.sameCountry(conList);

    }
}

Although the usage of process builder over apex trigger or vice versa is dependent on various other factors too, such as:

  • Complexity Of Codes.
  • Programmatic Logics.
  • Rapid Iteration In Process Builder Can Be Challenging.
  • Unit Test Considerations.
Salesforce Script and Trigger series I

Salesforce Script and Trigger series I

Hey Guys, I have solved some questions which i think was really helpful for me, so I thought sharing them would be a help for you all, here is my 1st series of Salesforce trigger.

So let’s start by solving some requirements below.

Requirement 1:

Let’s look into the scenario where 2 people John and Alice would like to book their honeymoon trip with the company named ‘Travel Agency’ which is based upon salesforce CRM.

They  have planned for following location visits:

  1. New York
  2. New Jersey
  3. Georgia
  4. California
  5. Texas
  6. Virginia

From Admin point of view this particular scenario need to be logged into CRM for :

Create a Custom Object Plan With Two Required fields.

  1. Travel Hours(Integers)
  2. Travel Location (New York,New Jersey,Georgia,California,Texas,Virginia) Multipicklist.

(I) Write a script to get the total hours of all the Plans record having Multipicklist New York or Virginia selected only or with other values.

(II) Write a Trigger to Stop creating any more Plan records with location ‘New York‘ if we have ‘Travel Hours’ more than 100 hours for any specific location ‘New York‘. Example:

If ‘John and Alice’ want spend  time in New york and have total no of hours for all the Plans for ‘New York’ is 90 hours, for ‘New Jersey’ is 70 hours and for  ‘Georgia’ is 100 hours. Follow some given steps as:

  • A new Plan is getting created on ’New York’ with John and Alice in addition to previously added  5 hours. Then Trigger will not stop,  as total hours will become 95 hours.
  • A new Plan is getting created on ‘New Jersey’ hours 45 hours. Trigger should stop as total hours will become 105 hours.

Solution 1:

(I) Script
public class GetHours{
 // To get The Required Data
public static void gethrs(){
List Plist=new List< Plan__c>();
 Plist=[select Travel_Hours__c from Plan__c where Travel__c='A' OR Travel__c='F' OR Travel__c includes('B,C,D,E;A') OR Travel__c includes('B,C,D,E;F')];
 //Getting ALL THE from Plan__c Object
 Decimal hrs=0;
for(Plan__c pc:Plist){
 hrs=hrs + pc.Travel_Hours__c;
 }
System.debug('TOTAL HOURS-->'+hrs);
 }
}
(II)Trigger
List pcList=Trigger.New;
List pcListnew= [select Travel_Hours__c from Plan__c where Travel__c ='A'];
 // or Travel__c includes('A')];
System.debug('get list---------'+pcListnew);
Decimal totalHr=0;
for(Plan__c pchr:pcListnew){
 totalHr= totalHr + pchr.Travel_Hours__c;
  }
for(Plan__c pc:pcList){
  if(totalHr + pc.Travel_Hours__c >100 && pc.Travel__c=='A')
     pc.addError('YOU CAN NOT ADD MORE WITH LOCATION ----> A');
 }
}

Requirement 2:

A Event organizing company which organize Dahi Handi Event and they organize the festival of Dahi Handi in societies, groups and different companies.

From Admin point of view this particular scenario need to be logged into CRM for :

“Create an Object “”Event“” (Name Default field and “”Event Date”” Date time field).

Another Junction Object ““Event Participant“” with 3 fields

1. lookup Contact

2.lookup Event

3. Attendee multipicklist(“”Attendee Contact“”,””Presenter Contact“”,””Organizer Contact“”)

(I) Write a script to create 10 “”Event Participant”” 4 with “”Attendee Contact””, 4 with “”Presenter Contact””, 2 with “”Organizer Contact””.”

(II) “Please solve the script question first.

Write a trigger to make sure No Event is having the same Contact registered as Attendee twice.

Explanation : A user named Nick is not allowed to create Two Event participant with same contact Lookup value under same Event.”

Solution 2:

(I) Script
public with sharing class CreateEventParticipent{
public static void eventCreate(){
List ConList=new List();
for(Integer i=1;i<=10;i++){
 Contact con=new Contact();
 con.LastName='TEST cont'+i+' F';
 ConList.add(con);
 }
if(ConList.size()>0)
 insert ConList;
/system.debug(con);
Event__c even=new Event__c();
even.Name='Salesforce meeting';
//even.Event_Date__c=6/02/2017 3:25 AM;
 insert even;
 System.debug(even);
 List PcList=new List();
  Integer i=0;
for(Contact con:ConList){
 Event_Participant__c evenpc = new Event_Participant__c();
if(i >0  &&  i <=4){
 evenpc.Name='INDIA CRICKET  '+i;
 evenpc.Participent__c='Attendee Contact';
 evenpc.Event__c=even.Id;
 evenpc.Contact__c=con.Id;
 }
else if(i>4 && i<=8){
  evenpc.Name='INDIA HOCKEY  '+i;
  evenpc.Participent__c='Presenter Contact';
  evenpc.Event__c=even.Id;
  evenpc.Contact__c=con.Id;
 }
else{
 evenpc.Name='INDIA MEN RACE '+i;
 evenpc.Participent__c='Organizer Contact';
 evenpc.Event__c=even.Id;
 evenpc.Contact__c=con.Id;
 }
PcList.add(evenpc);
System.debug('ADDDED------------------>'+evenpc);
 i++;
 }
if(PcList.size()>0){
  insert PcList;
System.debug('ADDDED------------------>'+PcList);
  }
 }
}
(II)Trigger
trigger PreventContactForMultipleEvents on Event_Participant__c (before insert, before update){ 
List EvPList=Trigger.New; 
for(Event_Participant__c epc:EvPList){ 
 for(Event_Participant__c cc:[select Id,Contact__c,Participent__c from Event_Participant__c where Contact__c!=NULL AND Participent__c !=NULL]){ 
  if(epc.Contact__c == cc.Contact__c && cc.Participent__c==epc.Participent__c){ 
   epc.addError('YOU CAN NOT ADD A SINGLE CONATCT WITH MORE THAN ONE EVENT !!!'); 
   }
  }
 } 
}

 Requirement 3:

A salesforce company named ABC and plan to launch a product in different region (ASIA, EMA, NA, SA) across the globe.They also want to sell the products to their clients which are in ASIA,EMA, NA and SA .

From Admin point of view this particular scenario need to be logged into CRM for:

  • Create a Multi picklist name In Account Object “Working in”

Picklist Values:

  1. ASIA
  2. EMA
  3. NA
  4. SA

(I) Write a script to get the total Quantity of Products sold in only Accounts working in  = ASIA.

(II) Write a Trigger to stop creating or updating Opportunities with Account having  “Working in = ASIA” and Already 2 Closed Won Opportunity under same Account.

Solution 3:

(I) Script
public class GetProQtywithAcc{    
public static void GetToatlPtoQty(){        
 List AccList=[select id,Name from Account where Working_In__c='ASIA'];        
//system.debug('ACCCC---->'+AccList);        
if(AccList.size()>0){            
  List oppList =[select id,TotalOpportunityQuantity,AccountId from Opportunity where AccountId IN:AccList AND StageName='Closed Won'];            
//system.debug('opp--->'+oppList);            
for(Opportunity opp:oppList){                
  System.debug('ACCOUNT---->'+opp.AccountId+'Number Of Product Sol--->'+opp.TotalOpportunityQuantity);            
   }        
  }    
 } 
}
(II) Trigger
public class PreventCreateOppOppCLoseWon_Trigger{
public static void PreventOppCreate(List OppList){
  //new List();
List AccList=[Select Name,Id from Account Where Working_In__c includes('ASIA')]; 
 //Getting all the account which is working in ASIA 
System.debug('ACCC-->'+AccList);
List OppCloseWonList=[Select Id, AccountId From Opportunity Where StageName='Closed Won' and AccountId IN:AccList];
  //getting id and accountid of all the opportunity where accountid is in AccList and stageName is Closed won
System.debug('opp-->'+OppCloseWonList);
for(Opportunity Opp:OppList){
 Integer add=0;</span>
for(Opportunity opp1:OppCloseWonList){
 if(opp1.AccountId==Opp.AccountId){
   add++;
  }
}
if(add>1){
  Opp.addError('CAN NOT ADD OR UPDATE NEW OPPORTUNITY !!');
  System.debug('AFTER MATCH------------------------>'+Opp.AccountId);
   }
  }
 }
}

Enjoy Coding!!

Pin It on Pinterest