On field lead source of opportunity object, if currently there are 4 records for the value 'Web', and the user tries to create or update an existing record the trigger should throw an error stating that there can not be more than 4 records for the value web. Till now i have got this

set<ID> userIdset = new set<ID>();
set<string> stageName = new set <string> ();
List<Opportunity> stageList = new List <Opportunity> ();
if (Trigger.isInsert) 
    Schema.DescribeFieldResult fieldResult = Opportunity.stageName.getdescribe();
    List<schema.PicklistEntry> schemaPickList = fieldResult.getPickListvalues();
    System.debug('Schema picklist'+schemaPicklist);

    for (Opportunity o1 : Trigger.new) 


if (Trigger.isUpdate) 
    for (Opportunity o2:trigger.new)
        if (o2.stageName != Trigger.oldMap.get(o2.Id).stageName) 
            System.debug('Update trigger fired');
            system.debug('The old status was'+Trigger.oldMap.get(o2.Id).stageName);
  • 1
    Why are you walking the describe results? That doesn't seem to play into your objective. You'll certainly need a query here, probably a count() query. – David Reed Jan 10 at 14:21
  • I removed your update because it was exactly the same code as what you already posted. No reason for it to be there twice. – gNerb Jan 10 at 17:33

My best guess is that you want to make sure that no account has more than 4 opportunities that were created via leads that came from the web.

Disclaimer: the following is intentionally not copy/paste code and meant as a guide to get you started. Use it as a guide and if you run into any specific issues you can ask another question for more assistance.

trigger oppTriggerTest on Opportunity (before update, before insert) {
    // FIrst step is to get account ids
    Set<id> accountIds = new Set<Id>();

    for (Opportunity opp : trigger.new) {
        if (opp.leadSource = 'Web') { // Make sure we only look at opps that we care about

    // Let's make the database do as much of the work as possible
    List<AggregateResult> ars = [
        SELECT Count(Id) numOfWeb, AccountId
        FROM Opportunity
        WHERE AccountId IN :accountIds
            And LeadSource = 'Web'
        GROUP BY AccountId
        HAVING Count(Id) >= 4

    // Lets make a map that's easier to work with
    Map<Id, Integer> accountToCount = new Map<id, Integer>();

    for (AggregateResult ar : ars) {
        accountToCount.put(ar.get('AccountId'), ar.get('numOfWeb'));

    // Now, lets add an error to opps that violate the rule
    for (Opportunity opp : trigger.new) {
        if (accountToCount.containsKey(opp.accountId)) {
            opp.addError('Too many web opps for the given account');
  • Hi thanks for your help but I need to calculate for all the values of lead source. For example for Web we have 4 account records, then for Phone, we need to have 4 account records ...... – user52297 Jan 12 at 6:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.