You are using an older browser that might negatively affect how this site is displayed. Please update to a modern browser to have a better experience. Sorry for the inconvenience!

Discount on Opportunity Product and Email Notification Using Schedule Apex


Introduction: 

In this article, we are explaining that how to give discount on opportunity product based on customers’ lifetime and send notification to them regarding that discount through email.

We are using a batch class to avoid governor limit exceptions and schedule class to trigger this process on customer birthday; so that they can receive discount notification particularly on that day.

Process Explanation: 

This process fetches contact details of all who are celebrating their birthday today, and identifies the opportunity details related to those contacts.

After reading the opportunity details, it identifies the products and opportunity line item details related to those opportunities.

Based on customer lifetime, this process provides different discount rates on the opportunity product and sends notification email to those contacts.

Apex Code Implementation: 

Batch Class: 

global class Article_Batch_AC implements  Database.Batchable<sobject> 

{ 

    global Database.QueryLocator start(Database.BatchableContext DBC) 

    { 

        String quy='SELECT Id,Birthdate,createddate,lastname,email FROM Contact WHERE Birthdate=Today'; 

        return Database.getQueryLocator(quy); 

    } 

     

    global void execute(Database.BatchableContext DBC,List<Contact> acc) 

    { 

        Map<id,string> emailaddress=new Map<id,string>(); 

        Set<Id> accidlessthan1=new Set<Id>(); 

        Set<Id> accidmorethan1=new Set<Id>(); 

        Set<Id> Total=new Set<Id>(); 

        for(Contact ac:acc) 

        { 

            Date cd=Date.valueOf(ac.CreatedDate); 

            Date now=Date.valueOf(system.now()); 

            Integer days=now.year()-cd.year(); 

            if(days<1) 

            { 

                accidlessthan1.add(ac.id); 

            } 

            else 

            { 

                accidmorethan1.add(ac.id);   

            } 

            Total.add(ac.Id); 

        } 

        List<OpportunityContactRole> oppcntrolequy=[select Opportunityid,ContactId  from OpportunityContactRole where ContactId=:Total]; 

        Set<Id> ocntrolelessone=new Set<Id>(); 

        Set<Id> ocntrolemoreone=new Set<Id>(); 

        Set<Id> Totalopprole=new Set<Id>(); 

        for(OpportunityContactRole oppcntrole:oppcntrolequy) 

        { 

            if(accidlessthan1.contains(oppcntrole.ContactId)) 

            { 

                ocntrolelessone.add(oppcntrole.OpportunityId); 

            } 

            else 

            { 

                ocntrolemoreone.add(oppcntrole.OpportunityId); 

            } 

            Totalopprole.add(oppcntrole.OpportunityId); 

        } 

        List<Opportunity> opppriceid=[select id,Pricebook2Id,stagename  from Opportunity where id=:Totalopprole]; 

        Set<Id> pricebookidone=new Set<Id>(); 

        Set<Id> pricebookidmore=new Set<Id>(); 

        Set<Id> Totalpricebookid=new Set<Id>(); 

        List<Opportunity> totalopp=new  List<Opportunity>(); 

        for(Opportunity opp:opppriceid) 

        { 

            if(ocntrolelessone.contains(opp.Id)) 

            { 

                pricebookidone.add(opp.Pricebook2Id); 

            } 

            else 

            { 

                pricebookidmore.add(opp.Pricebook2Id); 

            } 

            Totalpricebookid.add(opp.Pricebook2Id); 

            totalopp.add(opp); 

        } 

        List<PricebookEntry> pricebookentryquy=[select id,Unitprice,Pricebook2Id,Product2Id  from PricebookEntry where Pricebook2Id=:Totalpricebookid]; 

        List<PricebookEntry> insertpricebookentry=new  List<PricebookEntry>(); 

        map<id,decimal> lessthanoneprice=new map<id,decimal>(); 

        map<id,decimal> morethanoneprice=new map<id,decimal>(); 

        List<PricebookEntry> stdinsertpricebookentry=new  List<PricebookEntry>(); 

        Pricebook2 stdpb = [select id from Pricebook2 where isStandard=true]; 

        for(pricebookentry prboo:pricebookentryquy) 

        { 

            PricebookEntry pbe=new PricebookEntry(); 

            if(pricebookidone.contains(prboo.Pricebook2Id)) 

            {           

                pbe.UnitPrice=prboo.UnitPrice-100; 

                lessthanoneprice.put(prboo.Pricebook2Id,pbe.UnitPrice); 

            } 

            else 

            { 

                pbe.UnitPrice=prboo.UnitPrice-200; 

                morethanoneprice.put(prboo.Pricebook2Id,pbe.UnitPrice); 

            } 

        } 

        List<PricebookEntry> pricbbbboquy=[select id,Pricebook2Id,Product2Id,ProductCode from PricebookEntry ]; 

        set<id> productid=new set<id>(); 

        map<id,id> pricbookentryid1=new map<id,id>(); 

        map<id,id> pricbookentryid2=new map<id,id>(); 

        for(PricebookEntry pbee:pricbbbboquy) 

        { 

            if(lessthanoneprice.containsKey(pbee.Pricebook2Id)) 

            { 

                pricbookentryid1.put(pbee.Pricebook2Id,pbee.id); 

            } 

            else 

            { 

                pricbookentryid2.put(pbee.Pricebook2Id,pbee.id); 

            } 

            productid.add(pbee.Product2Id); 

        }         

        List<OpportunityLineItem> opplineitem=new List<OpportunityLineItem>(); 

        map<id,Decimal> quan=new map<id,Decimal>(); 

        map<id,id> quan11=new map<id,id>(); 

        List<OpportunityLineItem> opplineitemquy=[select Name,quantity,PricebookEntryId,id,opportunityid,Product2Id from OpportunityLineItem where Product2Id=:productid]; 

        for(OpportunityLineItem olineitem:opplineitemquy) 

        { 

            quan.put(olineitem.opportunityid,olineitem.quantity); 

        } 

        for(Opportunity opp:totalopp) 

        { 

            if(opp.StageName!='Closed Won' || opp.StageName!='Closed Lost' ) 

            { 

                if(pricbookentryid1.containsKey(opp.Pricebook2Id)) 

                { 

                    OpportunityLineItem oppitem = new OpportunityLineItem(); 

                    oppitem.OpportunityId=opp.Id; 

                    oppitem.Quantity=quan.get(opp.Id); 

                    oppitem.UnitPrice=lessthanoneprice.get(opp.Pricebook2Id);  

                    oppitem.PricebookEntryId=pricbookentryid1.get(opp.Pricebook2Id); 

                    opplineitem.add(oppitem);   

                } 

                else 

                { 

                    OpportunityLineItem oppitem = new OpportunityLineItem(); 

                    oppitem.OpportunityId=opp.Id; 

                    oppitem.Quantity=quan.get(opp.Id); 

                    oppitem.UnitPrice=morethanoneprice.get(opp.Pricebook2Id); 

                    oppitem.PricebookEntryId=pricbookentryid2.get(opp.Pricebook2Id); 

                    opplineitem.add(oppitem);  

                }   

            } 

        } 

        insert opplineitem; 

        Set<id> oppid=new Set<id>(); 

        Set<id> opplineid=new Set<id>(); 

        Set<String> opplinename=new Set<string>(); 

        for(OpportunityLineItem del:opplineitem) 

        { 

            oppid.add(del.OpportunityId); 

            opplineid.add(del.id); 

        } 

        List<OpportunityLineItem> oppnamequy=[select id,Name from OpportunityLineItem where id=:opplineid]; 

        for(OpportunityLineItem delname:oppnamequy) 

        { 

            opplinename.add(delname.Name); 

        } 

        List<OpportunityLineItem> opplineitemquy1=[select id from OpportunityLineItem where Name=:opplinename and id!=:opplineid and Opportunityid=:oppid]; 

        delete opplineitemquy1; 

        List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>(); 

        for(Contact mailcnt :acc) { 

            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); 

            mail.plainTextBody = 'Hi,'+mailcnt.LastName+','+'Happy Brithday,you got discount on your product.Kindly check it'; 

            mail.subject='Product discount on Birthday'; 

            mail.toAddresses=new String[] {mailcnt.Email}; 

            mails.add(mail); 

        } 

        Messaging.sendEmail(mails); 

    } 

    global void finish(Database.BatchableContext BC) 

    { 

         

    } 

}

Schedule Class: 

global class Opportunity_Prod_Discount_Schedule implements Schedulable 

{ 

    global void execute(SchedulableContext SC) 

    { 

        Article_Batch_AC ab=new Article_Batch_AC(); 

        Database.executeBatch(ab,2000); 

    } 

} 

Sample Screen Shots: 

Before Starting the Process 

Schedule the Process 

After the Process is complete

Reference: https://success.salesforce.com/answers?id=90630000000gjohAAA